From b946bc214a07ba731dcaa290bfcb575f731c7df1 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 28 May 2021 19:17:36 +0900 Subject: [PATCH 01/67] Update Version to 1.0.1 --- Info.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Info.json b/Info.json index b6f2819..680c136 100644 --- a/Info.json +++ b/Info.json @@ -2,7 +2,7 @@ "Id": "NoStopMod", "Author": "Luxus", "Version": "1.0.0", - "ManagerVersion": "1.0.0", + "ManagerVersion": "1.0.1", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load" -} \ No newline at end of file +} From ad401d5b108102147a27bf71c136605c73db5ad3 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 28 May 2021 19:17:57 +0900 Subject: [PATCH 02/67] Update Info.json --- Info.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Info.json b/Info.json index 680c136..89a6b02 100644 --- a/Info.json +++ b/Info.json @@ -1,8 +1,8 @@ { "Id": "NoStopMod", + "DisplayName": "NoStopMod", "Author": "Luxus", - "Version": "1.0.0", - "ManagerVersion": "1.0.1", + "Version": "1.0.1", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load" } From b98ecb1c3b4dfb2de395756a8abad8ac7dcea40f Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 9 Jun 2021 19:02:36 +0900 Subject: [PATCH 03/67] Refactor: move classes, simplify onToggle method --- GarbageCollection/GCManager.cs | 60 ++++++++++++++++ {Patches => GarbageCollection}/Patches.cs | 44 ++++++------ Info.json | 4 +- NoStopMod.cs | 88 ++++++----------------- 4 files changed, 106 insertions(+), 90 deletions(-) create mode 100644 GarbageCollection/GCManager.cs rename {Patches => GarbageCollection}/Patches.cs (69%) diff --git a/GarbageCollection/GCManager.cs b/GarbageCollection/GCManager.cs new file mode 100644 index 0000000..2826bdc --- /dev/null +++ b/GarbageCollection/GCManager.cs @@ -0,0 +1,60 @@ +using System; +using UnityEngine.Scripting; + +namespace NoStopMod.GarbageCollection +{ + public class GCManager + { + + private bool gcEnabled = true; + + public GCManager() + { + NoStopMod.onToggleListeners.Add(OnToggle); + } + + private void OnToggle(bool enabled) + { + EnableGC(); + } + + public bool GetDisableAutoSave() + { + return !gcEnabled; + } + + public void DisableGC() + { + try + { + gcEnabled = false; + //NoStopMod.mod.Logger.Log("disablegc"); + GarbageCollector.GCMode = GarbageCollector.Mode.Disabled; + System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.SustainedLowLatency; + } + catch (NotImplementedException e) + { + NoStopMod.mod.Logger.Log("Exception occur"); + NoStopMod.mod.Logger.Error(e.ToString()); + } + } + + public void EnableGC() + { + try + { + gcEnabled = true; + //NoStopMod.mod.Logger.Log("enablegc"); + GarbageCollector.GCMode = GarbageCollector.Mode.Enabled; + System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Interactive; + GC.Collect(); + } + catch (NotImplementedException e) + { + NoStopMod.mod.Logger.Log("Exception occur"); + NoStopMod.mod.Logger.Error(e.ToString()); + } + } + + } +} diff --git a/Patches/Patches.cs b/GarbageCollection/Patches.cs similarity index 69% rename from Patches/Patches.cs rename to GarbageCollection/Patches.cs index 3b7a0ba..de70021 100644 --- a/Patches/Patches.cs +++ b/GarbageCollection/Patches.cs @@ -4,35 +4,35 @@ namespace NoStopMod.Patches { - internal static class Patches + public static class Patches { [HarmonyPatch(typeof(CustomLevel), "Play")] - public static class CustomLevel_Play_Patch + private static class CustomLevel_Play_Patch { private static void Prefix(CustomLevel __instance) { //NoStopMod.mod.Logger.Log("Play"); - NoStopMod.DisableGC(); + NoStopMod.gcManager.DisableGC(); } } [HarmonyPatch(typeof(scnEditor), "ResetScene")] - public static class scnEditor_ResetScene_Patch + private static class scnEditor_ResetScene_Patch { private static void Postfix(scnEditor __instance) { //NoStopMod.mod.Logger.Log("ResetScene"); - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } [HarmonyPatch(typeof(scnEditor), "SaveBackup")] - public static class scnEditor_SaveBackup_Patch + private static class scnEditor_SaveBackup_Patch { private static bool Prefix(scnEditor __instance) { //NoStopMod.mod.Logger.Log("SaveBackup"); - if (NoStopMod.GetDisableAutoSave()) + if (NoStopMod.gcManager.GetDisableAutoSave()) { //NoStopMod.mod.Logger.Log("Cancel AutoSave"); return false; @@ -43,74 +43,72 @@ private static bool Prefix(scnEditor __instance) } [HarmonyPatch(typeof(scrController), "Awake")] - public static class scrController_Awake_Patch + private static class scrController_Awake_Patch { public static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("Awake"); - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } [HarmonyPatch(typeof(scrController), "FailAction")] - public static class scrController_FailAction_Patch + private static class scrController_FailAction_Patch { private static void Prefix(scrController __instance) { - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } [HarmonyPatch(typeof(scrController), "QuitToMainMenu")] - internal static class scrController_QuitToMainMenu_Patch + private static class scrController_QuitToMainMenu_Patch { private static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("StartLoadingScene"); - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } [HarmonyPatch(typeof(scrController), "ResetCustomLevel")] - internal static class scrController_ResetCustomLevel_Patch + private static class scrController_ResetCustomLevel_Patch { private static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("ResetCustomLevel"); - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } [HarmonyPatch(typeof(scrController), "Restart")] - public static class scrController_Restart_Patch + private static class scrController_Restart_Patch { private static void Prefix(scrController __instance) { //NoStopMod.mod.Logger.Log("Restart"); - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } [HarmonyPatch(typeof(scrController), "StartLoadingScene")] - internal static class scrController_StartLoadingScene_Patch + private static class scrController_StartLoadingScene_Patch { private static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("StartLoadingScene"); - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } - - [HarmonyPatch(typeof(scrUIController), "WipeToBlack")] - public static class scrUIController_WipeToBlack_Patch + private static class scrUIController_WipeToBlack_Patch { private static void Postfix(scrUIController __instance) { //NoStopMod.mod.Logger.Log("WipeToBlack"); - NoStopMod.EnableGC(); + NoStopMod.gcManager.EnableGC(); } } diff --git a/Info.json b/Info.json index b6f2819..d21e24b 100644 --- a/Info.json +++ b/Info.json @@ -1,8 +1,8 @@ { "Id": "NoStopMod", "Author": "Luxus", - "Version": "1.0.0", - "ManagerVersion": "1.0.0", + "Version": "1.0.1", + "ManagerVersion": "0.23.4.0", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load" } \ No newline at end of file diff --git a/NoStopMod.cs b/NoStopMod.cs index bdbebe0..b214b71 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -1,13 +1,10 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; using System.Reflection; using HarmonyLib; -using UnityEngine; using UnityModManagerNet; -using UnityEngine.Scripting; +using NoStopMod.GarbageCollection; +using System.Collections.Generic; +using NoStopMod.AsyncInput; namespace NoStopMod { @@ -16,84 +13,45 @@ class NoStopMod public static UnityModManager.ModEntry mod; public static Harmony harmony; + public static GCManager gcManager; + public static AsyncInputManager asyncInputManager; + public static List> onToggleListeners; - public static bool currentEnabled = false; - public static bool ready = false; - public static bool gcEnabled = true; + //public static bool isEnabled = false; + //public static bool ready = false; public static bool Load(UnityModManager.ModEntry modEntry) { modEntry.OnToggle = new Func(NoStopMod.OnToggle); + NoStopMod.harmony = new Harmony(modEntry.Info.Id); NoStopMod.mod = modEntry; + NoStopMod.onToggleListeners = new List>(); + + gcManager = new GCManager(); + asyncInputManager = new AsyncInputManager(); + return true; } public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) { NoStopMod.mod = modEntry; - - if (NoStopMod.currentEnabled != enabled) + + if (enabled) { - if (enabled) - { - NoStopMod.ready = true; - NoStopMod.harmony = new Harmony(modEntry.Info.Id); - NoStopMod.harmony.PatchAll(Assembly.GetExecutingAssembly()); - - } - else - { - NoStopMod.ready = false; - NoStopMod.harmony.UnpatchAll(NoStopMod.harmony.Id); - - } - NoStopMod.currentEnabled = enabled; + NoStopMod.harmony.PatchAll(Assembly.GetExecutingAssembly()); } - NoStopMod.gcEnabled = true; - return true; - } - - public static bool GetDisableAutoSave() - { - return NoStopMod.ready && !NoStopMod.gcEnabled; - } - - public static void DisableGC() - { - if (NoStopMod.ready) + else { - try - { - gcEnabled = false; - //NoStopMod.mod.Logger.Log("disablegc"); - GarbageCollector.GCMode = GarbageCollector.Mode.Disabled; - System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.SustainedLowLatency; - } - catch (NotImplementedException e) - { - NoStopMod.mod.Logger.Log("Exception occur"); - NoStopMod.mod.Logger.Error(e.ToString()); - } + NoStopMod.harmony.UnpatchAll(NoStopMod.harmony.Id); } - } - public static void EnableGC() - { - if (NoStopMod.ready) + foreach (Action listener in onToggleListeners) { - try - { - gcEnabled = true; - //NoStopMod.mod.Logger.Log("enablegc"); - GarbageCollector.GCMode = GarbageCollector.Mode.Enabled; - System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Interactive; - GC.Collect(); - } catch (NotImplementedException e) - { - NoStopMod.mod.Logger.Log("Exception occur"); - NoStopMod.mod.Logger.Error(e.ToString()); - } + listener.Invoke(enabled); } + + return true; } } From 5a11ba91097ada6b6e5261228128c8c1b056bcf1 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 9 Jun 2021 19:03:53 +0900 Subject: [PATCH 04/67] Feat: Add HyperRabbit Adavnced version of mod "FixedOtto" by PizzaLovers007 --- HyperRabbit/HyperRabbitManager.cs | 50 +++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 HyperRabbit/HyperRabbitManager.cs diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitManager.cs new file mode 100644 index 0000000..e992d7a --- /dev/null +++ b/HyperRabbit/HyperRabbitManager.cs @@ -0,0 +1,50 @@ +using HarmonyLib; + +namespace NoStopMod.HyperRabbit +{ + class HyperRabbitManager + { + + [HarmonyPatch(typeof(scrPlanet), "SwitchChosen")] + private static class PlanetSwitchChosenPatch + { + public static void Prefix(scrPlanet __instance) + { + if (RDC.auto && scrController.isGameWorld) + { + __instance.angle = __instance.targetExitAngle; + } + } + } + + [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] + private static class scrController_PlayerControl_Update_Patch2 + { + public static void Postfix(scrController __instance) + { + if (!RDC.auto || !scrController.isGameWorld) + { + return; + } + + __instance.chosenplanet.Update_RefreshAngles(); + while (__instance.chosenplanet.AutoShouldHitNow()) + { + __instance.Hit(); + __instance.chosenplanet.Update_RefreshAngles(); + } + } + } + + [HarmonyPatch(typeof(scrController), "FailAction")] + private static class ControllerFailActionPatch + { + public static bool Prefix() + { + return !RDC.auto; + } + } + + } + +} From 8f3ade96ae9f12b59f4cda66d91575e054d9f139 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 9 Jun 2021 19:06:38 +0900 Subject: [PATCH 05/67] Feat: Create AsyncInputManager & did bunch of things. --- AsyncInput/AsyncInputManager.cs | 458 ++++++++++++++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 AsyncInput/AsyncInputManager.cs diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs new file mode 100644 index 0000000..b37da84 --- /dev/null +++ b/AsyncInput/AsyncInputManager.cs @@ -0,0 +1,458 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using UnityEngine; + +namespace NoStopMod.AsyncInput +{ + class AsyncInputManager + { + + private Thread thread; + public Queue>> keyQueue = new Queue>>(); + public double dspTimeSong; + + public long offsetTick; + public long currTick; + public long lastHitTick; + public long currHitTick; + + public double sum = 0; + public int count = 0; + + private long pauseStart = 0; + public bool jumpToOtherClass = false; + + private bool[] mask; + + public AsyncInputManager() + { + NoStopMod.onToggleListeners.Add(OnToggle); + mask = Enumerable.Repeat(false, 1024).ToArray(); + + } + + private void OnToggle(bool enabled) + { + if (enabled) + { + //Start(); + } + else + { + Stop(); + } + } + + public void Start() + { + Stop(); + thread = new Thread(Run); + thread.Start(); + } + + public void Stop() + { + if (thread != null) + { + thread.Abort(); + thread = null; + } + } + + private bool GetKeyDown(int idx) + { + if (mask[idx]) + { + if (!Input.GetKey((KeyCode)idx)) + { + mask[idx] = false; + } + } + else + { + if (Input.GetKey((KeyCode)idx)) + { + mask[idx] = true; + return true; + } + } + return false; + } + + private void Run() + { + long prevTick = DateTime.Now.Ticks; + while (true) + { + long currTick = DateTime.Now.Ticks; + + if (currTick > prevTick) + { + + prevTick = currTick; + List keyCodes = new List(); + + for (int i = 0; i < 320; i++) + { + if (GetKeyDown(i)) + { + keyCodes.Add((KeyCode)i); + } + } + + for (int i = 323; i <= 329; i++) + { + if (GetKeyDown(i)) + { + keyCodes.Add((KeyCode)i); + } + } + + if (keyCodes.Any()) + { + keyQueue.Enqueue(new Tuple>(DateTime.Now.Ticks, keyCodes)); + //string str = DateTime.Now.Ticks + " press "; + //foreach (KeyCode keyCode in keyCodes) + //{ + // str += keyCode.ToString() + ", "; + //} + //str += keyQueue.Count() + "개 " + keyQueue.Any(); + //NoStopMod.mod.Logger.Log(str); + } + } + } + } + + public static string s(double d, int to=6) + { + try + { + return ("" + d).Substring(0, to); + } + catch + { + return "" + d; + } + } + // Update() + + [HarmonyPatch(typeof(scrConductor), "Update")] + private static class scrConductor_Update_Patch_Time + { + public static void Prefix(scrConductor __instance) + { + NoStopMod.asyncInputManager.currTick = DateTime.Now.Ticks; + } + } + + [HarmonyPatch(typeof(scrController), "TogglePauseGame")] + private static class scrController_TogglePauseGame_Patch + { + public static void Postfix(scrController __instance) + { + if (__instance.paused) + { + NoStopMod.asyncInputManager.pauseStart = NoStopMod.asyncInputManager.currTick; + NoStopMod.mod.Logger.Log(NoStopMod.asyncInputManager.pauseStart + " TogglePauseGame start"); + } + else if (NoStopMod.asyncInputManager.pauseStart != 0) + { + NoStopMod.asyncInputManager.offsetTick += NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; + NoStopMod.mod.Logger.Log(NoStopMod.asyncInputManager.currTick + " TogglePauseGame end (" + (NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart) + "ticks"); + NoStopMod.asyncInputManager.pauseStart = 0; + } + + + } + } + + [HarmonyPatch(typeof(scrController), "Awake_Rewind")] + private static class scrController_Awake_Rewind_Patch + { + public static void Postfix(scrController __instance) + { + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; + NoStopMod.asyncInputManager.pauseStart = 0; + NoStopMod.asyncInputManager.Start(); + NoStopMod.mod.Logger.Log(NoStopMod.asyncInputManager.currTick + " Awake_Rewind"); + } + } + + [HarmonyPatch(typeof(scrController), "CountValidKeysPressed")] + private static class scrController_CountValidKeysPressed_Patch + { + public static void Postfix(scrController __instance, ref int __result) + { + if (__result != 0) + { + long diff = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + //NoStopMod.asyncInputManager.currHitTick = diff; + NoStopMod.mod.Logger.Log(diff + " press " + __result + " keys"); + NoStopMod.mod.Logger.Log(__instance.chosenplanet.other.angle + " angle"); + } + } + } + + + + //PlayerControl_Update + [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] + private static class scrController_PlayerControl_Update_Patch + { + public static void Postfix(scrController __instance) + { + while (NoStopMod.asyncInputManager.keyQueue.Any()) + { + long tick; + List keyCodes; + NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); + + if (!scrController.isGameWorld) continue; + //scrConductor conductor = __instance.conductor; + + + //string str = ""; + //if (!GCS.d_oldConductor && !GCS.d_webglConductor) + //{ + // str = "new conductor " + tick + ", " + conductor.dspTime + ", " + NoStopMod.asyncInputManager.dspTimeSong + ":" + conductor.songposition_minusi; + // conductor.songposition_minusi = (double)((float)(conductor.dspTime - NoStopMod.asyncInputManager.dspTimeSong - (double)scrConductor.calibration_i) * conductor.song.pitch) - conductor.addoffset; + //} + //else + //{ + // str = "old conductor " + tick + ", " + conductor.dspTime + ", " + NoStopMod.asyncInputManager.dspTimeSong + ":" + conductor.songposition_minusi; + // conductor.songposition_minusi = (double)(conductor.song.time - scrConductor.calibration_i) - conductor.addoffset / (double)conductor.song.pitch; + //} + //str += " -> " + conductor.songposition_minusi; + //NoStopMod.mod.Logger.Log(str); + + //NoStopMod.asyncInputManager.currTick = tick; + + scrPlanet planet = __instance.chosenplanet; + //planet.angle = planet.snappedLastAngle + (planet.conductor.songposition_minusi - planet.conductor.lastHit) / planet.conductor.crotchet * 3.1415927410125732 * __instance.speed * (double)(__instance.isCW ? 1 : -1); + + + for (int i=0;i< keyCodes.Count(); i++) + { + //__instance.chosenplanet.Update_RefreshAngles(); + //__instance.Hit(); + } + + // this.snappedLastAngle + (this.conductor.songposition_minusi - this.conductor.lastHit) / + // this.conductor.crotchet * 3.1415927410125732 * this.controller.speed * (double) (this.controller.isCW ? 1 : -1); + + //__instance.chosenplanet.angle; + + + } + + + } + } + + // Update_RefreshAngles() + [HarmonyPatch(typeof(scrPlanet), "Update_RefreshAngles")] + private static class scrPlanet_Update_RefreshAngles_Patch + { + public static bool Prefix(scrPlanet __instance, double ___snappedLastAngle) + { + if (NoStopMod.asyncInputManager.currHitTick == 0) + { + return true; + } + + + return true; + //long diff = + + //__instance.angle = ___snappedLastAngle + (__instance.conductor.songposition_minusi - __instance.conductor.lastHit) / __instance.conductor.crotchet + // * 3.1415927410125732 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); + + + //NoStopMod.asyncInputManager.currTick = 0; + //return false; + } + + + public static void Postfix(scrPlanet __instance, double ___snappedLastAngle) + { + + + if (__instance.isChosen) + { + long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + double diff = nowTick - NoStopMod.asyncInputManager.lastHitTick; + diff /= 10000000; + + + //NoStopMod.mod.Logger.Log("Update_RefreshAngles " + __instance.conductor.lastHit + ", " + NoStopMod.asyncInputManager.lastHitTick + " : " + (NoStopMod.asyncInputManager.lastHitTick / __instance.conductor.lastHit)); + + //NoStopMod.mod.Logger.Log(__instance.conductor.dspTime); + //NoStopMod.mod.Logger.Log((__instance.conductor.songposition_minusi - __instance.conductor.lastHit) + ":" + diff + "=>" + (diff / (__instance.conductor.songposition_minusi - __instance.conductor.lastHit))); + + // TODO : change constant. + //__instance.angle = ___snappedLastAngle + (diff / __instance.conductor.crotchet * 3.14159265358979 * 1.0 * + // __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1)); + + //NoStopMod.mod.Logger.Log(__instance.angle + ":" + ___snappedLastAngle + ", " + __instance.conductor.songposition_minusi + ", " + + // __instance.conductor.lastHit + " & " + diff); + + } + + + //NoStopMod.asyncInputManager.offsetTick = DateTime.Now.Ticks; + //NoStopMod.mod.Logger.Log("Update_RefreshAngles " + ___dspTimeSong); + } + } + + + [HarmonyPatch(typeof(scrPlanet), "MoveToNextFloor")] + private static class scrPlanet_Rewind_Patch + { + public static void Postfix(scrPlanet __instance) + { + NoStopMod.asyncInputManager.lastHitTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + + double lastHitSec = NoStopMod.asyncInputManager.lastHitTick / 10000000; + NoStopMod.mod.Logger.Log("MoveToNextFloor " + __instance.conductor.lastHit + ", " + lastHitSec + " , err: " + (lastHitSec - __instance.conductor.lastHit)); + + } + } + + public double getSongPosition(scrConductor __instance, long nowTick) + { + if (!GCS.d_oldConductor && !GCS.d_webglConductor) + { + return ((nowTick / 10000000 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + } + else + { + return (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; + } + } + + // Update() + [HarmonyPatch(typeof(scrConductor), "Update")] + private static class scrConductor_Update_Patch + { + public static void Postfix(scrConductor __instance, double ___dspTimeSong) + { + double nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + double diff = nowTick - NoStopMod.asyncInputManager.lastHitTick; + diff /= 10000000.0; + + if (NoStopMod.asyncInputManager.pauseStart != 0) + { + nowTick -= NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; + } + + double nowSec = nowTick / 10000000; + double calculated; + + if (!GCS.d_oldConductor && !GCS.d_webglConductor) + { + NoStopMod.asyncInputManager.sum += (nowSec - (__instance.dspTime - ___dspTimeSong)); + NoStopMod.asyncInputManager.count++; + //calculated = (double)((float)(__instance.dspTime - ___dspTimeSong - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + + NoStopMod.mod.Logger.Log("New Update " + s(__instance.dspTime) + ", " + s(___dspTimeSong) + ", " + s(nowSec) + " : " + s(nowSec - (__instance.dspTime - ___dspTimeSong)) + " mean : " + (NoStopMod.asyncInputManager.sum / NoStopMod.asyncInputManager.count)); + } + else + { + calculated = (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; + NoStopMod.mod.Logger.Log("Old Update " + (__instance.song.time) + ", " + nowTick + " : " + (nowTick - (__instance.song.time))); + } + + } + } + + + [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] + private static class scrController_Rewind_Patch + { + public static void Postfix(scrController __instance) + { + NoStopMod.asyncInputManager.sum = 0; + NoStopMod.asyncInputManager.count = 0; + + NoStopMod.asyncInputManager.jumpToOtherClass = true; + __instance.conductor.Start(); + + NoStopMod.mod.Logger.Log("OnMusicScheduled"); + } + } + + [HarmonyPatch(typeof(scrConductor), "Start")] + private static class scrConductor_Start_Patch + { + public static bool Prefix(scrConductor __instance, double ___dspTimeSong) + { + if (NoStopMod.asyncInputManager.jumpToOtherClass) + { + NoStopMod.asyncInputManager.jumpToOtherClass = false; + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); + + return false; + } + return true; + } + } + + [HarmonyPatch(typeof(scrConductor), "Rewind")] + private static class scrConductor_Rewind_Patch + { + public static void Postfix(scrConductor __instance, double ___dspTimeSong) + { + NoStopMod.asyncInputManager.sum = 0; + NoStopMod.asyncInputManager.count = 0; + + NoStopMod.asyncInputManager.dspTimeSong = ___dspTimeSong; + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; + NoStopMod.mod.Logger.Log("Rewind " + ___dspTimeSong); + } + } + + [HarmonyPatch(typeof(scrConductor), "StartMusicCo")] + private static class scrConductor_StartMusicCo_Patch + { + public static void Prefix(scrConductor __instance, double ___dspTimeSong, double ___buffer) + { + NoStopMod.asyncInputManager.sum = 0; + NoStopMod.asyncInputManager.count = 0; + + NoStopMod.asyncInputManager.dspTimeSong = ___dspTimeSong; + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; + NoStopMod.mod.Logger.Log("StartMusicCo " + ___dspTimeSong); + } + } + + [HarmonyPatch(typeof(scrConductor), "ScrubMusicToTile")] + private static class scrConductor_ScrubMusicToTile_Patch + { + public static void Postfix(scrConductor __instance) + { + NoStopMod.asyncInputManager.sum = 0; + NoStopMod.asyncInputManager.count = 0; + + NoStopMod.asyncInputManager.lastHitTick = 0; + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.lastHitTick; + } + } + + [HarmonyPatch(typeof(scrConductor), "DesyncFix")] + private static class scrConductor_DesyncFix_Patch + { + public static void Postfix(scrConductor __instance) + { + NoStopMod.asyncInputManager.sum = 0; + NoStopMod.asyncInputManager.count = 0; + + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; + } + } + + + } +} From 3cef0302d7ebf9be615aa2ad4b4da7d793e4e7ce Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 10 Jun 2021 09:13:31 +0900 Subject: [PATCH 06/67] Refactor: Change File name --- AsyncInput/AsyncInputManager.cs | 133 ++---------------- AsyncInput/AsyncInputPatches.cs | 85 +++++++++++ .../{Patches.cs => GCPatches.cs} | 0 ...RabbitManager.cs => HyperRabbitPatches.cs} | 0 NoStopMod.csproj | 18 ++- 5 files changed, 111 insertions(+), 125 deletions(-) create mode 100644 AsyncInput/AsyncInputPatches.cs rename GarbageCollection/{Patches.cs => GCPatches.cs} (100%) rename HyperRabbit/{HyperRabbitManager.cs => HyperRabbitPatches.cs} (100%) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index b37da84..f5ddd8e 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -12,15 +12,15 @@ class AsyncInputManager private Thread thread; public Queue>> keyQueue = new Queue>>(); - public double dspTimeSong; + //public double dspTimeSong; public long offsetTick; public long currTick; public long lastHitTick; public long currHitTick; - public double sum = 0; - public int count = 0; + //public double sum = 0; + //public int count = 0; private long pauseStart = 0; public bool jumpToOtherClass = false; @@ -156,16 +156,12 @@ public static void Postfix(scrController __instance) if (__instance.paused) { NoStopMod.asyncInputManager.pauseStart = NoStopMod.asyncInputManager.currTick; - NoStopMod.mod.Logger.Log(NoStopMod.asyncInputManager.pauseStart + " TogglePauseGame start"); } else if (NoStopMod.asyncInputManager.pauseStart != 0) { NoStopMod.asyncInputManager.offsetTick += NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; - NoStopMod.mod.Logger.Log(NoStopMod.asyncInputManager.currTick + " TogglePauseGame end (" + (NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart) + "ticks"); NoStopMod.asyncInputManager.pauseStart = 0; } - - } } @@ -239,6 +235,7 @@ public static void Postfix(scrController __instance) //__instance.chosenplanet.Update_RefreshAngles(); //__instance.Hit(); } + // this.snappedLastAngle + (this.conductor.songposition_minusi - this.conductor.lastHit) / // this.conductor.crotchet * 3.1415927410125732 * this.controller.speed * (double) (this.controller.isCW ? 1 : -1); @@ -321,6 +318,11 @@ public static void Postfix(scrPlanet __instance) } } + public void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) + { + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); + } + public double getSongPosition(scrConductor __instance, long nowTick) { if (!GCS.d_oldConductor && !GCS.d_webglConductor) @@ -334,124 +336,7 @@ public double getSongPosition(scrConductor __instance, long nowTick) } // Update() - [HarmonyPatch(typeof(scrConductor), "Update")] - private static class scrConductor_Update_Patch - { - public static void Postfix(scrConductor __instance, double ___dspTimeSong) - { - double nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - double diff = nowTick - NoStopMod.asyncInputManager.lastHitTick; - diff /= 10000000.0; - - if (NoStopMod.asyncInputManager.pauseStart != 0) - { - nowTick -= NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; - } - - double nowSec = nowTick / 10000000; - double calculated; - - if (!GCS.d_oldConductor && !GCS.d_webglConductor) - { - NoStopMod.asyncInputManager.sum += (nowSec - (__instance.dspTime - ___dspTimeSong)); - NoStopMod.asyncInputManager.count++; - //calculated = (double)((float)(__instance.dspTime - ___dspTimeSong - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; - - NoStopMod.mod.Logger.Log("New Update " + s(__instance.dspTime) + ", " + s(___dspTimeSong) + ", " + s(nowSec) + " : " + s(nowSec - (__instance.dspTime - ___dspTimeSong)) + " mean : " + (NoStopMod.asyncInputManager.sum / NoStopMod.asyncInputManager.count)); - } - else - { - calculated = (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; - NoStopMod.mod.Logger.Log("Old Update " + (__instance.song.time) + ", " + nowTick + " : " + (nowTick - (__instance.song.time))); - } - - } - } - - [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] - private static class scrController_Rewind_Patch - { - public static void Postfix(scrController __instance) - { - NoStopMod.asyncInputManager.sum = 0; - NoStopMod.asyncInputManager.count = 0; - - NoStopMod.asyncInputManager.jumpToOtherClass = true; - __instance.conductor.Start(); - - NoStopMod.mod.Logger.Log("OnMusicScheduled"); - } - } - - [HarmonyPatch(typeof(scrConductor), "Start")] - private static class scrConductor_Start_Patch - { - public static bool Prefix(scrConductor __instance, double ___dspTimeSong) - { - if (NoStopMod.asyncInputManager.jumpToOtherClass) - { - NoStopMod.asyncInputManager.jumpToOtherClass = false; - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); - - return false; - } - return true; - } - } - - [HarmonyPatch(typeof(scrConductor), "Rewind")] - private static class scrConductor_Rewind_Patch - { - public static void Postfix(scrConductor __instance, double ___dspTimeSong) - { - NoStopMod.asyncInputManager.sum = 0; - NoStopMod.asyncInputManager.count = 0; - - NoStopMod.asyncInputManager.dspTimeSong = ___dspTimeSong; - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; - NoStopMod.mod.Logger.Log("Rewind " + ___dspTimeSong); - } - } - - [HarmonyPatch(typeof(scrConductor), "StartMusicCo")] - private static class scrConductor_StartMusicCo_Patch - { - public static void Prefix(scrConductor __instance, double ___dspTimeSong, double ___buffer) - { - NoStopMod.asyncInputManager.sum = 0; - NoStopMod.asyncInputManager.count = 0; - - NoStopMod.asyncInputManager.dspTimeSong = ___dspTimeSong; - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; - NoStopMod.mod.Logger.Log("StartMusicCo " + ___dspTimeSong); - } - } - - [HarmonyPatch(typeof(scrConductor), "ScrubMusicToTile")] - private static class scrConductor_ScrubMusicToTile_Patch - { - public static void Postfix(scrConductor __instance) - { - NoStopMod.asyncInputManager.sum = 0; - NoStopMod.asyncInputManager.count = 0; - - NoStopMod.asyncInputManager.lastHitTick = 0; - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.lastHitTick; - } - } - - [HarmonyPatch(typeof(scrConductor), "DesyncFix")] - private static class scrConductor_DesyncFix_Patch - { - public static void Postfix(scrConductor __instance) - { - NoStopMod.asyncInputManager.sum = 0; - NoStopMod.asyncInputManager.count = 0; - - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; - } - } } diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs new file mode 100644 index 0000000..14206b5 --- /dev/null +++ b/AsyncInput/AsyncInputPatches.cs @@ -0,0 +1,85 @@ +using HarmonyLib; + +namespace NoStopMod.AsyncInput +{ + public static class AsyncInputPatches + { + + [HarmonyPatch(typeof(scrConductor), "Update")] + private static class scrConductor_Update_Patch + { + public static void Postfix(scrConductor __instance, double ___dspTimeSong) + { + if (__instance.isGameWorld) + { + long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + double calculated = NoStopMod.asyncInputManager.getSongPosition(__instance, nowTick); + __instance.songposition_minusi = calculated; + } + } + } + + [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] + private static class scrController_Rewind_Patch + { + public static void Postfix(scrController __instance) + { + NoStopMod.asyncInputManager.jumpToOtherClass = true; + __instance.conductor.Start(); + } + } + + [HarmonyPatch(typeof(scrConductor), "Start")] + private static class scrConductor_Start_Patch + { + public static bool Prefix(scrConductor __instance, double ___dspTimeSong) + { + if (NoStopMod.asyncInputManager.jumpToOtherClass) + { + NoStopMod.asyncInputManager.jumpToOtherClass = false; + NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + return false; + } + return true; + } + } + + [HarmonyPatch(typeof(scrConductor), "Rewind")] + private static class scrConductor_Rewind_Patch + { + public static void Postfix(scrConductor __instance, double ___dspTimeSong) + { + NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + } + } + + [HarmonyPatch(typeof(scrConductor), "StartMusicCo")] + private static class scrConductor_StartMusicCo_Patch + { + public static void Prefix(scrConductor __instance, double ___dspTimeSong) + { + NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + } + } + + [HarmonyPatch(typeof(scrConductor), "ScrubMusicToTile")] + private static class scrConductor_ScrubMusicToTile_Patch + { + public static void Postfix(scrConductor __instance, double ___dspTimeSong) + { + NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + } + } + + [HarmonyPatch(typeof(scrConductor), "DesyncFix")] + private static class scrConductor_DesyncFix_Patch + { + public static void Postfix(scrConductor __instance, double ___dspTimeSong) + { + NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + } + } + + + } +} diff --git a/GarbageCollection/Patches.cs b/GarbageCollection/GCPatches.cs similarity index 100% rename from GarbageCollection/Patches.cs rename to GarbageCollection/GCPatches.cs diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitPatches.cs similarity index 100% rename from HyperRabbit/HyperRabbitManager.cs rename to HyperRabbit/HyperRabbitPatches.cs diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 6fc2a83..b8a4062 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -44,6 +44,10 @@ ..\lib\Assembly-CSharp-firstpass.dll + + False + ..\lib\RD\RDTools.dll + @@ -55,12 +59,20 @@ ..\lib\UnityEngine.dll + + False + ..\lib\UnityEngine.AudioModule.dll + ..\lib\UnityEngine.CoreModule.dll ..\lib\UnityEngine.IMGUIModule.dll + + False + ..\lib\UnityEngine.InputLegacyModule.dll + ..\lib\UnityEngine.UI.dll @@ -69,8 +81,12 @@ + + + + + - From 1d9430b04109bd1eb74966d0c3ec558a428b46cd Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 10 Jun 2021 10:54:38 +0900 Subject: [PATCH 07/67] Fix: Fix getSongPosition in AsyncInputManager. & Moved methods. --- AsyncInput/AsyncInputManager.cs | 59 +++++-------------------------- AsyncInput/AsyncInputPatches.cs | 57 +++++++++++++++++++++++++++++ HyperRabbit/HyperRabbitPatches.cs | 2 +- NoStopMod.csproj | 6 ++-- 4 files changed, 69 insertions(+), 55 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index f5ddd8e..974bee1 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -22,7 +22,7 @@ class AsyncInputManager //public double sum = 0; //public int count = 0; - private long pauseStart = 0; + public long pauseStart = 0; public bool jumpToOtherClass = false; private bool[] mask; @@ -126,56 +126,12 @@ private void Run() } } - public static string s(double d, int to=6) - { - try - { - return ("" + d).Substring(0, to); - } - catch - { - return "" + d; - } - } + // Update() - [HarmonyPatch(typeof(scrConductor), "Update")] - private static class scrConductor_Update_Patch_Time - { - public static void Prefix(scrConductor __instance) - { - NoStopMod.asyncInputManager.currTick = DateTime.Now.Ticks; - } - } + - [HarmonyPatch(typeof(scrController), "TogglePauseGame")] - private static class scrController_TogglePauseGame_Patch - { - public static void Postfix(scrController __instance) - { - if (__instance.paused) - { - NoStopMod.asyncInputManager.pauseStart = NoStopMod.asyncInputManager.currTick; - } - else if (NoStopMod.asyncInputManager.pauseStart != 0) - { - NoStopMod.asyncInputManager.offsetTick += NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; - NoStopMod.asyncInputManager.pauseStart = 0; - } - } - } - [HarmonyPatch(typeof(scrController), "Awake_Rewind")] - private static class scrController_Awake_Rewind_Patch - { - public static void Postfix(scrController __instance) - { - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick; - NoStopMod.asyncInputManager.pauseStart = 0; - NoStopMod.asyncInputManager.Start(); - NoStopMod.mod.Logger.Log(NoStopMod.asyncInputManager.currTick + " Awake_Rewind"); - } - } [HarmonyPatch(typeof(scrController), "CountValidKeysPressed")] private static class scrController_CountValidKeysPressed_Patch @@ -264,8 +220,7 @@ public static bool Prefix(scrPlanet __instance, double ___snappedLastAngle) return true; //long diff = - //__instance.angle = ___snappedLastAngle + (__instance.conductor.songposition_minusi - __instance.conductor.lastHit) / __instance.conductor.crotchet - // * 3.1415927410125732 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); + //NoStopMod.asyncInputManager.currTick = 0; @@ -283,9 +238,11 @@ public static void Postfix(scrPlanet __instance, double ___snappedLastAngle) double diff = nowTick - NoStopMod.asyncInputManager.lastHitTick; diff /= 10000000; + //__instance.angle = ___snappedLastAngle + (__instance.conductor.songposition_minusi - __instance.conductor.lastHit) / __instance.conductor.crotchet + // * 3.1415927410125732 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); //NoStopMod.mod.Logger.Log("Update_RefreshAngles " + __instance.conductor.lastHit + ", " + NoStopMod.asyncInputManager.lastHitTick + " : " + (NoStopMod.asyncInputManager.lastHitTick / __instance.conductor.lastHit)); - + //NoStopMod.mod.Logger.Log(__instance.conductor.dspTime); //NoStopMod.mod.Logger.Log((__instance.conductor.songposition_minusi - __instance.conductor.lastHit) + ":" + diff + "=>" + (diff / (__instance.conductor.songposition_minusi - __instance.conductor.lastHit))); @@ -327,7 +284,7 @@ public double getSongPosition(scrConductor __instance, long nowTick) { if (!GCS.d_oldConductor && !GCS.d_webglConductor) { - return ((nowTick / 10000000 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + return ((nowTick / 10000000.0 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; } else { diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 14206b5..51c758b 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -1,10 +1,65 @@ using HarmonyLib; +using System; namespace NoStopMod.AsyncInput { public static class AsyncInputPatches { + + + + public static string s(double d, int to = 6) + { + try + { + return ("" + d).Substring(0, to); + } + catch + { + return "" + d; + } + } + + [HarmonyPatch(typeof(scrConductor), "Update")] + private static class scrConductor_Update_Patch_Time + { + public static void Prefix(scrConductor __instance) + { + NoStopMod.asyncInputManager.currTick = DateTime.Now.Ticks; + } + } + + [HarmonyPatch(typeof(scrController), "TogglePauseGame")] + private static class scrController_TogglePauseGame_Patch + { + public static void Postfix(scrController __instance) + { + if (__instance.paused) + { + NoStopMod.asyncInputManager.pauseStart = NoStopMod.asyncInputManager.currTick; + } + else if (NoStopMod.asyncInputManager.pauseStart != 0) + { + NoStopMod.asyncInputManager.offsetTick += NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; + NoStopMod.asyncInputManager.pauseStart = 0; + } + } + } + + [HarmonyPatch(typeof(scrController), "Awake_Rewind")] + private static class scrController_Awake_Rewind_Patch + { + public static void Postfix(scrController __instance) + { + NoStopMod.asyncInputManager.jumpToOtherClass = true; + __instance.conductor.Start(); + //NoStopMod.asyncInputManager.Start(); + } + } + + + [HarmonyPatch(typeof(scrConductor), "Update")] private static class scrConductor_Update_Patch { @@ -13,7 +68,9 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) if (__instance.isGameWorld) { long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + double calculated = NoStopMod.asyncInputManager.getSongPosition(__instance, nowTick); + //NoStopMod.mod.Logger.Log("New Update " + s(__instance.songposition_minusi) + ", " + s(calculated) + " : " + s(calculated - __instance.songposition_minusi)); __instance.songposition_minusi = calculated; } } diff --git a/HyperRabbit/HyperRabbitPatches.cs b/HyperRabbit/HyperRabbitPatches.cs index e992d7a..1bde9ab 100644 --- a/HyperRabbit/HyperRabbitPatches.cs +++ b/HyperRabbit/HyperRabbitPatches.cs @@ -2,7 +2,7 @@ namespace NoStopMod.HyperRabbit { - class HyperRabbitManager + class HyperRabbitPatches { [HarmonyPatch(typeof(scrPlanet), "SwitchChosen")] diff --git a/NoStopMod.csproj b/NoStopMod.csproj index b8a4062..9bc2b6f 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -82,10 +82,10 @@ - + - - + + From ca98eab20d1011396120e776c595611eed5a2bfe Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 11 Jun 2021 09:06:08 +0900 Subject: [PATCH 08/67] Feat: Make planet angle calibration mechanism. --- AsyncInput/AsyncInputManager.cs | 76 +++++++++++++++++++-------------- AsyncInput/AsyncInputPatches.cs | 76 ++++++++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 39 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 974bee1..9ac7ab3 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -16,7 +16,10 @@ class AsyncInputManager public long offsetTick; public long currTick; + public long prevTick; + public long lastHitTick; + public double lastHitSec; public long currHitTick; //public double sum = 0; @@ -31,7 +34,10 @@ public AsyncInputManager() { NoStopMod.onToggleListeners.Add(OnToggle); mask = Enumerable.Repeat(false, 1024).ToArray(); - + + prevTick = DateTime.Now.Ticks; + currTick = prevTick; + } private void OnToggle(bool enabled) @@ -49,8 +55,8 @@ private void OnToggle(bool enabled) public void Start() { Stop(); - thread = new Thread(Run); - thread.Start(); + //thread = new Thread(Run); + //thread.Start(); } public void Stop() @@ -230,49 +236,47 @@ public static bool Prefix(scrPlanet __instance, double ___snappedLastAngle) public static void Postfix(scrPlanet __instance, double ___snappedLastAngle) { - - + if (__instance.isChosen) { long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - double diff = nowTick - NoStopMod.asyncInputManager.lastHitTick; - diff /= 10000000; - - //__instance.angle = ___snappedLastAngle + (__instance.conductor.songposition_minusi - __instance.conductor.lastHit) / __instance.conductor.crotchet - // * 3.1415927410125732 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); - - //NoStopMod.mod.Logger.Log("Update_RefreshAngles " + __instance.conductor.lastHit + ", " + NoStopMod.asyncInputManager.lastHitTick + " : " + (NoStopMod.asyncInputManager.lastHitTick / __instance.conductor.lastHit)); + __instance.angle = NoStopMod.asyncInputManager.getAngle(__instance, ___snappedLastAngle, nowTick); - //NoStopMod.mod.Logger.Log(__instance.conductor.dspTime); - //NoStopMod.mod.Logger.Log((__instance.conductor.songposition_minusi - __instance.conductor.lastHit) + ":" + diff + "=>" + (diff / (__instance.conductor.songposition_minusi - __instance.conductor.lastHit))); + //NoStopMod.mod.Logger.Error("aa" + ___snappedLastAngle + ", " + NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick) + ", " + nowTick + ", " + __instance.conductor.crotchet); - // TODO : change constant. - //__instance.angle = ___snappedLastAngle + (diff / __instance.conductor.crotchet * 3.14159265358979 * 1.0 * - // __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1)); - - //NoStopMod.mod.Logger.Log(__instance.angle + ":" + ___snappedLastAngle + ", " + __instance.conductor.songposition_minusi + ", " + - // __instance.conductor.lastHit + " & " + diff); + //NoStopMod.mod.Logger.Log(__instance.conductor.lastHit + ", " + (NoStopMod.asyncInputManager.lastHitSec) + ":" + (__instance.conductor.lastHit - NoStopMod.asyncInputManager.lastHitSec)); + //string str = ___snappedLastAngle + ", " + (NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick)) + ", " + (__instance.conductor.lastHit) + ", " + __instance.conductor.crotchet + + // ", " + __instance.controller.speed + ", " + (double)(__instance.controller.isCW ? 1 : -1); + //double r = ___snappedLastAngle + (NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick) - NoStopMod.asyncInputManager.lastHitSec) / __instance.conductor.crotchet + // * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); + //str += ", result:" + r + ", real:" + __instance.angle + ", " + AudioListener.pause; + //NoStopMod.mod.Logger.Log(str); + //__instance.angle = r; } - - - //NoStopMod.asyncInputManager.offsetTick = DateTime.Now.Ticks; - //NoStopMod.mod.Logger.Log("Update_RefreshAngles " + ___dspTimeSong); } } - [HarmonyPatch(typeof(scrPlanet), "MoveToNextFloor")] - private static class scrPlanet_Rewind_Patch + + + // Update LastHitTick + // scrConductor.Rewind + // scrConductor.ScrubMusicToTile + // scrPlanet.MoveToNextFloor + + public void adjustLastHitTick(scrConductor __instance, long tick) { - public static void Postfix(scrPlanet __instance) - { - NoStopMod.asyncInputManager.lastHitTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - double lastHitSec = NoStopMod.asyncInputManager.lastHitTick / 10000000; - NoStopMod.mod.Logger.Log("MoveToNextFloor " + __instance.conductor.lastHit + ", " + lastHitSec + " , err: " + (lastHitSec - __instance.conductor.lastHit)); + // scrConductor.Rewind + // conductor.lastHit = 0.0f - } + // scrConductor.ScrubMusicToTile + // this.lastHit = base.lm.listFloors[tileID].entryTime; + + // scrPlanet.MoveToNextFloor + // this.conductor.lastHit += ((double)exitAngle - this.snappedLastAngle) * (double)(this.controller.isCW ? 1 : -1) / 3.1415927410125732 * this.conductor.crotchet / this.controller.speed; + } public void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) @@ -288,10 +292,16 @@ public double getSongPosition(scrConductor __instance, long nowTick) } else { - return (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; + return (__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / __instance.song.pitch; } } + public double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) + { + return ___snappedLastAngle + (NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet + * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); + } + // Update() diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 51c758b..beb2ab1 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -1,5 +1,6 @@ using HarmonyLib; using System; +using UnityEngine; namespace NoStopMod.AsyncInput { @@ -26,6 +27,7 @@ private static class scrConductor_Update_Patch_Time { public static void Prefix(scrConductor __instance) { + NoStopMod.asyncInputManager.prevTick = NoStopMod.asyncInputManager.currTick; NoStopMod.asyncInputManager.currTick = DateTime.Now.Ticks; } } @@ -65,17 +67,72 @@ private static class scrConductor_Update_Patch { public static void Postfix(scrConductor __instance, double ___dspTimeSong) { - if (__instance.isGameWorld) + if (AudioListener.pause) { - long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - - double calculated = NoStopMod.asyncInputManager.getSongPosition(__instance, nowTick); - //NoStopMod.mod.Logger.Log("New Update " + s(__instance.songposition_minusi) + ", " + s(calculated) + " : " + s(calculated - __instance.songposition_minusi)); - __instance.songposition_minusi = calculated; + NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + } + + { + + //long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + //double calculated = NoStopMod.asyncInputManager.getSongPosition(__instance, nowTick); + //NoStopMod.mod.Logger.Log("New Update " + s(__instance.dspTime) + ", " + s(___dspTimeSong) + "," + s(__instance.songposition_minusi) + ", " + s(calculated) + " : " + s(calculated - __instance.songposition_minusi)); + //__instance.songposition_minusi = calculated; } } } + [HarmonyPatch(typeof(scrPlanet), "MoveToNextFloor")] + private static class scrPlanet_Rewind_Patch + { + public static void Postfix(scrPlanet __instance) + { + long nowTick = (NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick); + NoStopMod.asyncInputManager.lastHitSec = NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick); + + // diffTime (from last angle to current) + // ___snappedLastAngle + (diffTime) + // ; + + // ((nowTick / 10000000.0 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + + //this.conductor.lastHit = this.conductor.lastHit + (exitAngle - (exitAngle % 2)) + // (x % m + m) % m; + // ; + + + // diffTime (from last angle to current) + // ___snappedLastAngle + (diffTime) / __instance.conductor.crotchet + // *3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); + + // ((nowTick / 10000000.0 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + + //this.conductor.lastHit += ((double)exitAngle - this.scrMisc.mod((double)(exitAngle + 3.1415927f), 6.2831854820251465)) * (double)(this.controller.isCW ? 1 : -1) + // / 3.1415927410125732 * this.conductor.crotchet / this.controller.speed; + + /* + + if (scrController.isGameWorld) + + num2 = this.targetExitAngle; + + + else + + + + + + */ + + //NoStopMod.asyncInputManager.lastHitTick = (NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick); + + //double lastHitSec = NoStopMod.asyncInputManager.lastHitTick / 10000000; + //NoStopMod.mod.Logger.Log("MoveToNextFloor " + __instance.conductor.lastHit + ", " + lastHitSec + " , err: " + (lastHitSec - __instance.conductor.lastHit)); + + } + } + [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] private static class scrController_Rewind_Patch { @@ -107,6 +164,9 @@ private static class scrConductor_Rewind_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + NoStopMod.asyncInputManager.lastHitTick = 0; + NoStopMod.mod.Logger.Log("Rewind"); + } } @@ -116,6 +176,7 @@ private static class scrConductor_StartMusicCo_Patch public static void Prefix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + NoStopMod.mod.Logger.Log("StartMusicCo"); } } @@ -125,6 +186,8 @@ private static class scrConductor_ScrubMusicToTile_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + NoStopMod.asyncInputManager.lastHitTick = (long) (__instance.lastHit * 10000000.0); + NoStopMod.mod.Logger.Log("ScrubMusicToTile"); } } @@ -134,6 +197,7 @@ private static class scrConductor_DesyncFix_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + NoStopMod.mod.Logger.Log("DesyncFix"); } } From 10568b36ef4e7bb2b33b684dc1d989ed0521f233 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 11 Jun 2021 09:21:45 +0900 Subject: [PATCH 09/67] Refactor: Move patches from manager class to patches class --- AsyncInput/AsyncInputManager.cs | 162 +-------------------------- AsyncInput/AsyncInputPatches.cs | 190 +++++++++++++++++++------------- NoStopMod.cs | 3 +- 3 files changed, 120 insertions(+), 235 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 9ac7ab3..83022ee 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -1,4 +1,5 @@ -using HarmonyLib; +using DG.Tweening; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; @@ -18,9 +19,9 @@ class AsyncInputManager public long currTick; public long prevTick; - public long lastHitTick; - public double lastHitSec; - public long currHitTick; + //public long lastHitTick; + //public double lastHitSec; + public long currPressTick; //public double sum = 0; //public int count = 0; @@ -44,7 +45,7 @@ private void OnToggle(bool enabled) { if (enabled) { - //Start(); + Start(); } else { @@ -132,153 +133,6 @@ private void Run() } } - - // Update() - - - - - - [HarmonyPatch(typeof(scrController), "CountValidKeysPressed")] - private static class scrController_CountValidKeysPressed_Patch - { - public static void Postfix(scrController __instance, ref int __result) - { - if (__result != 0) - { - long diff = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - //NoStopMod.asyncInputManager.currHitTick = diff; - NoStopMod.mod.Logger.Log(diff + " press " + __result + " keys"); - NoStopMod.mod.Logger.Log(__instance.chosenplanet.other.angle + " angle"); - } - } - } - - - - //PlayerControl_Update - [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] - private static class scrController_PlayerControl_Update_Patch - { - public static void Postfix(scrController __instance) - { - while (NoStopMod.asyncInputManager.keyQueue.Any()) - { - long tick; - List keyCodes; - NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); - - if (!scrController.isGameWorld) continue; - //scrConductor conductor = __instance.conductor; - - - //string str = ""; - //if (!GCS.d_oldConductor && !GCS.d_webglConductor) - //{ - // str = "new conductor " + tick + ", " + conductor.dspTime + ", " + NoStopMod.asyncInputManager.dspTimeSong + ":" + conductor.songposition_minusi; - // conductor.songposition_minusi = (double)((float)(conductor.dspTime - NoStopMod.asyncInputManager.dspTimeSong - (double)scrConductor.calibration_i) * conductor.song.pitch) - conductor.addoffset; - //} - //else - //{ - // str = "old conductor " + tick + ", " + conductor.dspTime + ", " + NoStopMod.asyncInputManager.dspTimeSong + ":" + conductor.songposition_minusi; - // conductor.songposition_minusi = (double)(conductor.song.time - scrConductor.calibration_i) - conductor.addoffset / (double)conductor.song.pitch; - //} - //str += " -> " + conductor.songposition_minusi; - //NoStopMod.mod.Logger.Log(str); - - //NoStopMod.asyncInputManager.currTick = tick; - - scrPlanet planet = __instance.chosenplanet; - //planet.angle = planet.snappedLastAngle + (planet.conductor.songposition_minusi - planet.conductor.lastHit) / planet.conductor.crotchet * 3.1415927410125732 * __instance.speed * (double)(__instance.isCW ? 1 : -1); - - - for (int i=0;i< keyCodes.Count(); i++) - { - //__instance.chosenplanet.Update_RefreshAngles(); - //__instance.Hit(); - } - - - // this.snappedLastAngle + (this.conductor.songposition_minusi - this.conductor.lastHit) / - // this.conductor.crotchet * 3.1415927410125732 * this.controller.speed * (double) (this.controller.isCW ? 1 : -1); - - //__instance.chosenplanet.angle; - - - } - - - } - } - - // Update_RefreshAngles() - [HarmonyPatch(typeof(scrPlanet), "Update_RefreshAngles")] - private static class scrPlanet_Update_RefreshAngles_Patch - { - public static bool Prefix(scrPlanet __instance, double ___snappedLastAngle) - { - if (NoStopMod.asyncInputManager.currHitTick == 0) - { - return true; - } - - - return true; - //long diff = - - - - - //NoStopMod.asyncInputManager.currTick = 0; - //return false; - } - - - public static void Postfix(scrPlanet __instance, double ___snappedLastAngle) - { - - if (__instance.isChosen) - { - long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - __instance.angle = NoStopMod.asyncInputManager.getAngle(__instance, ___snappedLastAngle, nowTick); - - //NoStopMod.mod.Logger.Error("aa" + ___snappedLastAngle + ", " + NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick) + ", " + nowTick + ", " + __instance.conductor.crotchet); - - //NoStopMod.mod.Logger.Log(__instance.conductor.lastHit + ", " + (NoStopMod.asyncInputManager.lastHitSec) + ":" + (__instance.conductor.lastHit - NoStopMod.asyncInputManager.lastHitSec)); - //string str = ___snappedLastAngle + ", " + (NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick)) + ", " + (__instance.conductor.lastHit) + ", " + __instance.conductor.crotchet + - // ", " + __instance.controller.speed + ", " + (double)(__instance.controller.isCW ? 1 : -1); - //double r = ___snappedLastAngle + (NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick) - NoStopMod.asyncInputManager.lastHitSec) / __instance.conductor.crotchet - // * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); - //str += ", result:" + r + ", real:" + __instance.angle + ", " + AudioListener.pause; - //NoStopMod.mod.Logger.Log(str); - //__instance.angle = r; - - } - } - } - - - - - // Update LastHitTick - // scrConductor.Rewind - // scrConductor.ScrubMusicToTile - // scrPlanet.MoveToNextFloor - - public void adjustLastHitTick(scrConductor __instance, long tick) - { - - // scrConductor.Rewind - // conductor.lastHit = 0.0f - - // scrConductor.ScrubMusicToTile - // this.lastHit = base.lm.listFloors[tileID].entryTime; - - // scrPlanet.MoveToNextFloor - // this.conductor.lastHit += ((double)exitAngle - this.snappedLastAngle) * (double)(this.controller.isCW ? 1 : -1) / 3.1415927410125732 * this.conductor.crotchet / this.controller.speed; - - } - public void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); @@ -301,10 +155,6 @@ public double getAngle(scrPlanet __instance, double ___snappedLastAngle, long no return ___snappedLastAngle + (NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); } - - // Update() - - } } diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index beb2ab1..11d7464 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -7,9 +7,6 @@ namespace NoStopMod.AsyncInput public static class AsyncInputPatches { - - - public static string s(double d, int to = 6) { try @@ -32,23 +29,121 @@ public static void Prefix(scrConductor __instance) } } - [HarmonyPatch(typeof(scrController), "TogglePauseGame")] - private static class scrController_TogglePauseGame_Patch + //[HarmonyPatch(typeof(scrController), "PlayerControl_Update")] + //private static class scrController_PlayerControl_Update_Patch + //{ + // public static void Postfix(scrController __instance) + // { + // while (NoStopMod.asyncInputManager.keyQueue.Any()) + // { + // long tick; + // List keyCodes; + // NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); + + // //if (!scrController.isGameWorld) continue; + + // for (int i=0;i< keyCodes.Count(); i++) + // { + // __instance.chosenplanet.Update_RefreshAngles(); + // __instance.Hit(); + // } + + // } + // } + //} + + [HarmonyPatch(typeof(scrController), "CountValidKeysPressed")] + private static class scrController_CountValidKeysPressed_Patch { - public static void Postfix(scrController __instance) + public static void Postfix(scrController __instance, ref int __result) { - if (__instance.paused) + if (__result != 0) + { + //__result = 0; + } + } + } + + [HarmonyPatch(typeof(scrPlanet), "Update_RefreshAngles")] + private static class scrPlanet_Update_RefreshAngles_Patch + { + public static bool Prefix(scrPlanet __instance, double ___snappedLastAngle) + { + if (NoStopMod.asyncInputManager.jumpToOtherClass) + { + NoStopMod.asyncInputManager.jumpToOtherClass = false; + __instance.angle = NoStopMod.asyncInputManager.getAngle(__instance, ___snappedLastAngle, NoStopMod.asyncInputManager.currPressTick); + + return false; + } + + if (!GCS.d_stationary) + { + long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; + __instance.angle = NoStopMod.asyncInputManager.getAngle(__instance, ___snappedLastAngle, nowTick); + + if (__instance.shouldPrint) + { + __instance.shouldPrint = false; + } + } + else { - NoStopMod.asyncInputManager.pauseStart = NoStopMod.asyncInputManager.currTick; + if (Input.GetKey(KeyCode.DownArrow)) + { + __instance.angle += 0.10000000149011612; + } + if (Input.GetKey(KeyCode.UpArrow)) + { + __instance.angle -= 0.10000000149011612; + } } - else if (NoStopMod.asyncInputManager.pauseStart != 0) + float num = (float)__instance.angle; + if (__instance.currfloor != null) { - NoStopMod.asyncInputManager.offsetTick += NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; - NoStopMod.asyncInputManager.pauseStart = 0; + if (__instance.controller.rotationEase != Ease.Linear) + { + float num2 = scrMisc.EasedAngle((float)___snappedLastAngle, (float)__instance.targetExitAngle, num, __instance.controller.rotationEase, __instance.controller.rotationEaseParts); + if (!float.IsNaN(num2) && !float.IsInfinity(num2)) + { + num = num2; + } + } + if (__instance.controller.stickToFloor) + { + num -= (__instance.currfloor.transform.rotation.eulerAngles - __instance.currfloor.startRot).z * 0.017453292f; + } } + Vector3 position = __instance.transform.position; + __instance.other.transform.position = new Vector3(position.x + Mathf.Sin(num) * __instance.cosmeticRadius, position.y + Mathf.Cos(num) * __instance.cosmeticRadius, position.z); + if (__instance.is3D) + { + __instance.other.transform.position = new Vector3(position.x + Mathf.Sin((float)__instance.angle) * __instance.cosmeticRadius, position.y, position.z + Mathf.Cos((float)__instance.angle) * __instance.cosmeticRadius); + } + + return false; } } + + + //[HarmonyPatch(typeof(scrController), "TogglePauseGame")] + //private static class scrController_TogglePauseGame_Patch + //{ + // public static void Postfix(scrController __instance) + // { + // if (__instance.paused) + // { + // NoStopMod.asyncInputManager.pauseStart = NoStopMod.asyncInputManager.currTick; + // } + // else if (NoStopMod.asyncInputManager.pauseStart != 0) + // { + // NoStopMod.asyncInputManager.offsetTick += NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; + // NoStopMod.asyncInputManager.pauseStart = 0; + // } + // } + //} + [HarmonyPatch(typeof(scrController), "Awake_Rewind")] private static class scrController_Awake_Rewind_Patch { @@ -59,9 +154,7 @@ public static void Postfix(scrController __instance) //NoStopMod.asyncInputManager.Start(); } } - - - + [HarmonyPatch(typeof(scrConductor), "Update")] private static class scrConductor_Update_Patch { @@ -71,67 +164,10 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); } - - { - - //long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - //double calculated = NoStopMod.asyncInputManager.getSongPosition(__instance, nowTick); - //NoStopMod.mod.Logger.Log("New Update " + s(__instance.dspTime) + ", " + s(___dspTimeSong) + "," + s(__instance.songposition_minusi) + ", " + s(calculated) + " : " + s(calculated - __instance.songposition_minusi)); - //__instance.songposition_minusi = calculated; - } } } - [HarmonyPatch(typeof(scrPlanet), "MoveToNextFloor")] - private static class scrPlanet_Rewind_Patch - { - public static void Postfix(scrPlanet __instance) - { - long nowTick = (NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick); - NoStopMod.asyncInputManager.lastHitSec = NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick); - - // diffTime (from last angle to current) - // ___snappedLastAngle + (diffTime) - // ; - - // ((nowTick / 10000000.0 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; - - //this.conductor.lastHit = this.conductor.lastHit + (exitAngle - (exitAngle % 2)) - // (x % m + m) % m; - // ; - - - // diffTime (from last angle to current) - // ___snappedLastAngle + (diffTime) / __instance.conductor.crotchet - // *3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); - - // ((nowTick / 10000000.0 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; - - //this.conductor.lastHit += ((double)exitAngle - this.scrMisc.mod((double)(exitAngle + 3.1415927f), 6.2831854820251465)) * (double)(this.controller.isCW ? 1 : -1) - // / 3.1415927410125732 * this.conductor.crotchet / this.controller.speed; - - /* - - if (scrController.isGameWorld) - - num2 = this.targetExitAngle; - - - else - - - - - - */ - - //NoStopMod.asyncInputManager.lastHitTick = (NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick); - - //double lastHitSec = NoStopMod.asyncInputManager.lastHitTick / 10000000; - //NoStopMod.mod.Logger.Log("MoveToNextFloor " + __instance.conductor.lastHit + ", " + lastHitSec + " , err: " + (lastHitSec - __instance.conductor.lastHit)); - - } - } + [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] private static class scrController_Rewind_Patch @@ -164,8 +200,7 @@ private static class scrConductor_Rewind_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.asyncInputManager.lastHitTick = 0; - NoStopMod.mod.Logger.Log("Rewind"); + //NoStopMod.mod.Logger.Log("Rewind"); } } @@ -176,7 +211,7 @@ private static class scrConductor_StartMusicCo_Patch public static void Prefix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.mod.Logger.Log("StartMusicCo"); + //NoStopMod.mod.Logger.Log("StartMusicCo"); } } @@ -186,8 +221,7 @@ private static class scrConductor_ScrubMusicToTile_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.asyncInputManager.lastHitTick = (long) (__instance.lastHit * 10000000.0); - NoStopMod.mod.Logger.Log("ScrubMusicToTile"); + //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); } } @@ -197,7 +231,7 @@ private static class scrConductor_DesyncFix_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.mod.Logger.Log("DesyncFix"); + //NoStopMod.mod.Logger.Log("DesyncFix"); } } diff --git a/NoStopMod.cs b/NoStopMod.cs index b214b71..dab24ae 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -17,7 +17,7 @@ class NoStopMod public static AsyncInputManager asyncInputManager; public static List> onToggleListeners; - //public static bool isEnabled = false; + public static bool isEnabled = false; //public static bool ready = false; public static bool Load(UnityModManager.ModEntry modEntry) @@ -46,6 +46,7 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) NoStopMod.harmony.UnpatchAll(NoStopMod.harmony.Id); } + isEnabled = enabled; foreach (Action listener in onToggleListeners) { listener.Invoke(enabled); From aae07d2fe1a18aea7e9a0e0b2511710df792f9fb Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 11 Jun 2021 09:22:48 +0900 Subject: [PATCH 10/67] Fix: Fix build errors --- AsyncInput/AsyncInputManager.cs | 4 +--- AsyncInput/AsyncInputPatches.cs | 3 ++- NoStopMod.csproj | 6 ++++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 83022ee..5d37f0c 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -1,6 +1,4 @@ -using DG.Tweening; -using HarmonyLib; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 11d7464..4eb3157 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -1,4 +1,5 @@ -using HarmonyLib; +using DG.Tweening; +using HarmonyLib; using System; using UnityEngine; diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 9bc2b6f..c22ef21 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -44,6 +44,12 @@ ..\lib\Assembly-CSharp-firstpass.dll + + ..\lib\DOTween.dll + + + ..\lib\DOTweenPro.dll + False ..\lib\RD\RDTools.dll From 1e7d0870e523fdfc981081d16b13e312b0fd6c75 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 11 Jun 2021 10:45:12 +0900 Subject: [PATCH 11/67] Feat: Async Input methods --- AsyncInput/AsyncInputManager.cs | 18 ++---- AsyncInput/AsyncInputPatches.cs | 103 +++++++++++++++----------------- 2 files changed, 54 insertions(+), 67 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 5d37f0c..fe519fa 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -11,20 +11,13 @@ class AsyncInputManager private Thread thread; public Queue>> keyQueue = new Queue>>(); - //public double dspTimeSong; - public long offsetTick; public long currTick; public long prevTick; - //public long lastHitTick; - //public double lastHitSec; + public long offsetTick; public long currPressTick; - - //public double sum = 0; - //public int count = 0; - - public long pauseStart = 0; + public bool jumpToOtherClass = false; private bool[] mask; @@ -36,7 +29,6 @@ public AsyncInputManager() prevTick = DateTime.Now.Ticks; currTick = prevTick; - } private void OnToggle(bool enabled) @@ -54,8 +46,8 @@ private void OnToggle(bool enabled) public void Start() { Stop(); - //thread = new Thread(Run); - //thread.Start(); + thread = new Thread(Run); + thread.Start(); } public void Stop() @@ -150,7 +142,7 @@ public double getSongPosition(scrConductor __instance, long nowTick) public double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) { - return ___snappedLastAngle + (NoStopMod.asyncInputManager.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet + return ___snappedLastAngle + (this.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); } diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 4eb3157..776f6f2 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -1,6 +1,8 @@ using DG.Tweening; using HarmonyLib; using System; +using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace NoStopMod.AsyncInput @@ -19,6 +21,26 @@ public static string s(double d, int to = 6) return "" + d; } } + + [HarmonyPatch(typeof(scrController), "Awake")] + private static class scrController_Awake_Patch + { + public static void Postfix(scrController __instance) + { + NoStopMod.asyncInputManager.jumpToOtherClass = true; + __instance.conductor.Start(); + NoStopMod.asyncInputManager.Start(); + } + } + + [HarmonyPatch(typeof(scrController), "OnApplicationQuit")] + private static class scrController_OnApplicationQuit_Patch + { + public static void Prefix(scrController __instance) + { + NoStopMod.asyncInputManager.Stop(); + } + } [HarmonyPatch(typeof(scrConductor), "Update")] private static class scrConductor_Update_Patch_Time @@ -30,28 +52,28 @@ public static void Prefix(scrConductor __instance) } } - //[HarmonyPatch(typeof(scrController), "PlayerControl_Update")] - //private static class scrController_PlayerControl_Update_Patch - //{ - // public static void Postfix(scrController __instance) - // { - // while (NoStopMod.asyncInputManager.keyQueue.Any()) - // { - // long tick; - // List keyCodes; - // NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); - - // //if (!scrController.isGameWorld) continue; - - // for (int i=0;i< keyCodes.Count(); i++) - // { - // __instance.chosenplanet.Update_RefreshAngles(); - // __instance.Hit(); - // } - - // } - // } - //} + [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] + private static class scrController_PlayerControl_Update_Patch + { + public static void Postfix(scrController __instance) + { + while (NoStopMod.asyncInputManager.keyQueue.Any()) + { + long tick; + List keyCodes; + NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); + + if (AudioListener.pause) continue; + + for (int i = 0; i < keyCodes.Count(); i++) + { + __instance.chosenplanet.Update_RefreshAngles(); + __instance.Hit(); + } + + } + } + } [HarmonyPatch(typeof(scrController), "CountValidKeysPressed")] private static class scrController_CountValidKeysPressed_Patch @@ -60,7 +82,7 @@ public static void Postfix(scrController __instance, ref int __result) { if (__result != 0) { - //__result = 0; + __result = 0; } } } @@ -68,8 +90,10 @@ public static void Postfix(scrController __instance, ref int __result) [HarmonyPatch(typeof(scrPlanet), "Update_RefreshAngles")] private static class scrPlanet_Update_RefreshAngles_Patch { - public static bool Prefix(scrPlanet __instance, double ___snappedLastAngle) + public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) { + if (!__instance.isChosen || __instance.conductor.crotchet == 0.0) return false; + if (NoStopMod.asyncInputManager.jumpToOtherClass) { NoStopMod.asyncInputManager.jumpToOtherClass = false; @@ -125,36 +149,7 @@ public static bool Prefix(scrPlanet __instance, double ___snappedLastAngle) return false; } } - - - - //[HarmonyPatch(typeof(scrController), "TogglePauseGame")] - //private static class scrController_TogglePauseGame_Patch - //{ - // public static void Postfix(scrController __instance) - // { - // if (__instance.paused) - // { - // NoStopMod.asyncInputManager.pauseStart = NoStopMod.asyncInputManager.currTick; - // } - // else if (NoStopMod.asyncInputManager.pauseStart != 0) - // { - // NoStopMod.asyncInputManager.offsetTick += NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.pauseStart; - // NoStopMod.asyncInputManager.pauseStart = 0; - // } - // } - //} - - [HarmonyPatch(typeof(scrController), "Awake_Rewind")] - private static class scrController_Awake_Rewind_Patch - { - public static void Postfix(scrController __instance) - { - NoStopMod.asyncInputManager.jumpToOtherClass = true; - __instance.conductor.Start(); - //NoStopMod.asyncInputManager.Start(); - } - } + [HarmonyPatch(typeof(scrConductor), "Update")] private static class scrConductor_Update_Patch From 86cfef17e7334db175bd83c516a965c3d53cc680 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 11 Jun 2021 14:59:06 +0900 Subject: [PATCH 12/67] Feat: Impl Async Input Mechanism --- AsyncInput/AsyncInputManager.cs | 11 +---- AsyncInput/AsyncInputPatches.cs | 78 +++++++++++++++++---------------- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index fe519fa..a983980 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -88,7 +88,6 @@ private void Run() if (currTick > prevTick) { - prevTick = currTick; List keyCodes = new List(); @@ -110,14 +109,8 @@ private void Run() if (keyCodes.Any()) { - keyQueue.Enqueue(new Tuple>(DateTime.Now.Ticks, keyCodes)); - //string str = DateTime.Now.Ticks + " press "; - //foreach (KeyCode keyCode in keyCodes) - //{ - // str += keyCode.ToString() + ", "; - //} - //str += keyQueue.Count() + "개 " + keyQueue.Any(); - //NoStopMod.mod.Logger.Log(str); + keyCodes = keyCodes.GetRange(0, 4); + keyQueue.Enqueue(new Tuple>(currTick, keyCodes)); } } } diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 776f6f2..a3c329c 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -10,17 +10,17 @@ namespace NoStopMod.AsyncInput public static class AsyncInputPatches { - public static string s(double d, int to = 6) - { - try - { - return ("" + d).Substring(0, to); - } - catch - { - return "" + d; - } - } + //public static string s(double d, int to = 6) + //{ + // try + // { + // return ("" + d).Substring(0, to); + // } + // catch + // { + // return "" + d; + // } + //} [HarmonyPatch(typeof(scrController), "Awake")] private static class scrController_Awake_Patch @@ -50,27 +50,46 @@ public static void Prefix(scrConductor __instance) NoStopMod.asyncInputManager.prevTick = NoStopMod.asyncInputManager.currTick; NoStopMod.asyncInputManager.currTick = DateTime.Now.Ticks; } + + public static void Postfix(scrConductor __instance, double ___dspTimeSong) + { + if (AudioListener.pause) + { + NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + } + + if (__instance.controller.GetState().CompareTo(scrController.States.PlayerControl) != 0) + { + //NoStopMod.mod.Logger.Log("Update " + __instance.controller.GetState() + ", " + ((Enum)scrController.States.PlayerControl) + " : " + (__instance.controller.GetState() != (Enum)scrController.States.PlayerControl)); + NoStopMod.asyncInputManager.keyQueue.Clear(); + } + + } } [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] private static class scrController_PlayerControl_Update_Patch { - public static void Postfix(scrController __instance) + public static void Prefix(scrController __instance) { + bool pause = AudioListener.pause || RDC.auto; while (NoStopMod.asyncInputManager.keyQueue.Any()) { long tick; List keyCodes; NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); - if (AudioListener.pause) continue; + if (pause) continue; + + NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; + scrController controller = __instance.controller; for (int i = 0; i < keyCodes.Count(); i++) { - __instance.chosenplanet.Update_RefreshAngles(); - __instance.Hit(); + NoStopMod.asyncInputManager.jumpToOtherClass = true; + controller.chosenplanet.Update_RefreshAngles(); + controller.Hit(); } - } } } @@ -92,7 +111,6 @@ private static class scrPlanet_Update_RefreshAngles_Patch { public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) { - if (!__instance.isChosen || __instance.conductor.crotchet == 0.0) return false; if (NoStopMod.asyncInputManager.jumpToOtherClass) { @@ -102,6 +120,8 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) return false; } + if (!__instance.isChosen || __instance.conductor.crotchet == 0.0) return false; + if (!GCS.d_stationary) { long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; @@ -149,21 +169,6 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) return false; } } - - - [HarmonyPatch(typeof(scrConductor), "Update")] - private static class scrConductor_Update_Patch - { - public static void Postfix(scrConductor __instance, double ___dspTimeSong) - { - if (AudioListener.pause) - { - NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - } - } - } - - [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] private static class scrController_Rewind_Patch @@ -196,8 +201,7 @@ private static class scrConductor_Rewind_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("Rewind"); - + NoStopMod.mod.Logger.Log("Rewind"); } } @@ -207,7 +211,7 @@ private static class scrConductor_StartMusicCo_Patch public static void Prefix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("StartMusicCo"); + NoStopMod.mod.Logger.Log("StartMusicCo"); } } @@ -217,7 +221,7 @@ private static class scrConductor_ScrubMusicToTile_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); + NoStopMod.mod.Logger.Log("ScrubMusicToTile"); } } @@ -227,7 +231,7 @@ private static class scrConductor_DesyncFix_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("DesyncFix"); + NoStopMod.mod.Logger.Log("DesyncFix"); } } From e6d5b6ea8e9c2c9643658db27757643e3e1b202c Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 11 Jun 2021 16:38:38 +0900 Subject: [PATCH 13/67] Feat: Block some keys. --- AsyncInput/AsyncInputManager.cs | 35 ++++++++++++++++++++++++--------- AsyncInput/AsyncInputPatches.cs | 8 ++++---- Info.json | 3 ++- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index a983980..c87d2f6 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -19,16 +19,27 @@ class AsyncInputManager public long currPressTick; public bool jumpToOtherClass = false; - + private bool[] mask; + private bool[] disable; public AsyncInputManager() { NoStopMod.onToggleListeners.Add(OnToggle); - mask = Enumerable.Repeat(false, 1024).ToArray(); prevTick = DateTime.Now.Ticks; currTick = prevTick; + + mask = Enumerable.Repeat(false, 1024).ToArray(); + disable = Enumerable.Repeat(false, 1024).ToArray(); + disable[(int)KeyCode.BackQuote] = true; + disable[(int)KeyCode.Alpha1] = true; + disable[(int)KeyCode.Alpha2] = true; + disable[(int)KeyCode.Alpha3] = true; + disable[(int)KeyCode.Alpha4] = true; + disable[(int)KeyCode.Alpha5] = true; + disable[(int)KeyCode.Alpha6] = true; + disable[(int)KeyCode.Alpha7] = true; } private void OnToggle(bool enabled) @@ -61,6 +72,7 @@ public void Stop() private bool GetKeyDown(int idx) { + if (disable[idx]) return false; if (mask[idx]) { if (!Input.GetKey((KeyCode)idx)) @@ -109,16 +121,22 @@ private void Run() if (keyCodes.Any()) { - keyCodes = keyCodes.GetRange(0, 4); - keyQueue.Enqueue(new Tuple>(currTick, keyCodes)); + //String str = "press " + keyCodes.Count(); + //foreach (KeyCode code in keyCodes) + //{ + // str += code + "(" + ((int)code) + "), "; + //} + //NoStopMod.mod.Logger.Log(str); + keyQueue.Enqueue(new Tuple>(currTick, keyCodes.GetRange(0, Math.Min(4, keyCodes.Count())))); } } } } - public void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) + public double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) { - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); + return ___snappedLastAngle + (this.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet + * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); } public double getSongPosition(scrConductor __instance, long nowTick) @@ -133,10 +151,9 @@ public double getSongPosition(scrConductor __instance, long nowTick) } } - public double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) + public void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) { - return ___snappedLastAngle + (this.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet - * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); + NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); } } diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index a3c329c..2ecdd51 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -201,7 +201,7 @@ private static class scrConductor_Rewind_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.mod.Logger.Log("Rewind"); + //NoStopMod.mod.Logger.Log("Rewind"); } } @@ -211,7 +211,7 @@ private static class scrConductor_StartMusicCo_Patch public static void Prefix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.mod.Logger.Log("StartMusicCo"); + //NoStopMod.mod.Logger.Log("StartMusicCo"); } } @@ -221,7 +221,7 @@ private static class scrConductor_ScrubMusicToTile_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.mod.Logger.Log("ScrubMusicToTile"); + //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); } } @@ -231,7 +231,7 @@ private static class scrConductor_DesyncFix_Patch public static void Postfix(scrConductor __instance, double ___dspTimeSong) { NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); - NoStopMod.mod.Logger.Log("DesyncFix"); + //NoStopMod.mod.Logger.Log("DesyncFix"); } } diff --git a/Info.json b/Info.json index d21e24b..8ccd52b 100644 --- a/Info.json +++ b/Info.json @@ -1,7 +1,8 @@ { "Id": "NoStopMod", + "DisplayName": "NoStopMod", "Author": "Luxus", - "Version": "1.0.1", + "Version": "1.1.0", "ManagerVersion": "0.23.4.0", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load" From 511e837fbc5c056c08e794a0e6a20b876baa0d75 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 11 Jun 2021 17:44:23 +0900 Subject: [PATCH 14/67] Fix: Fix midspin bug --- HyperRabbit/HyperRabbitPatches.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/HyperRabbit/HyperRabbitPatches.cs b/HyperRabbit/HyperRabbitPatches.cs index 1bde9ab..965ec93 100644 --- a/HyperRabbit/HyperRabbitPatches.cs +++ b/HyperRabbit/HyperRabbitPatches.cs @@ -30,6 +30,7 @@ public static void Postfix(scrController __instance) __instance.chosenplanet.Update_RefreshAngles(); while (__instance.chosenplanet.AutoShouldHitNow()) { + __instance.keyBufferCount = 0; __instance.Hit(); __instance.chosenplanet.Update_RefreshAngles(); } From bf900249be9e7504edb1e3f4cad0e4e4adf4e8d4 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 12 Jun 2021 10:01:07 +0900 Subject: [PATCH 15/67] Fix: Fix key input errors in custom level selector --- AsyncInput/AsyncInputManager.cs | 20 +++---- AsyncInput/AsyncInputPatches.cs | 9 +++- AsyncInput/HitDisable/HitDisableManager.cs | 63 ++++++++++++++++++++++ AsyncInput/HitDisable/HitDisablePatches.cs | 28 ++++++++++ NoStopMod.csproj | 3 ++ 5 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 AsyncInput/HitDisable/HitDisableManager.cs create mode 100644 AsyncInput/HitDisable/HitDisablePatches.cs diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index c87d2f6..414b05e 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -1,4 +1,5 @@ -using System; +using NoStopMod.AsyncInput.HitDisable; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -9,6 +10,8 @@ namespace NoStopMod.AsyncInput class AsyncInputManager { + public HitDisableManager hitDisableManager; + private Thread thread; public Queue>> keyQueue = new Queue>>(); @@ -21,7 +24,6 @@ class AsyncInputManager public bool jumpToOtherClass = false; private bool[] mask; - private bool[] disable; public AsyncInputManager() { @@ -31,15 +33,8 @@ public AsyncInputManager() currTick = prevTick; mask = Enumerable.Repeat(false, 1024).ToArray(); - disable = Enumerable.Repeat(false, 1024).ToArray(); - disable[(int)KeyCode.BackQuote] = true; - disable[(int)KeyCode.Alpha1] = true; - disable[(int)KeyCode.Alpha2] = true; - disable[(int)KeyCode.Alpha3] = true; - disable[(int)KeyCode.Alpha4] = true; - disable[(int)KeyCode.Alpha5] = true; - disable[(int)KeyCode.Alpha6] = true; - disable[(int)KeyCode.Alpha7] = true; + + hitDisableManager = new HitDisableManager(); } private void OnToggle(bool enabled) @@ -72,7 +67,6 @@ public void Stop() private bool GetKeyDown(int idx) { - if (disable[idx]) return false; if (mask[idx]) { if (!Input.GetKey((KeyCode)idx)) @@ -127,7 +121,7 @@ private void Run() // str += code + "(" + ((int)code) + "), "; //} //NoStopMod.mod.Logger.Log(str); - keyQueue.Enqueue(new Tuple>(currTick, keyCodes.GetRange(0, Math.Min(4, keyCodes.Count())))); + keyQueue.Enqueue(new Tuple>(currTick, keyCodes)); } } } diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 2ecdd51..9e703e0 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -1,5 +1,6 @@ using DG.Tweening; using HarmonyLib; +using NoStopMod.AsyncInput.HitDisable; using System; using System.Collections.Generic; using System.Linq; @@ -72,20 +73,24 @@ private static class scrController_PlayerControl_Update_Patch { public static void Prefix(scrController __instance) { - bool pause = AudioListener.pause || RDC.auto; while (NoStopMod.asyncInputManager.keyQueue.Any()) { long tick; List keyCodes; NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); - if (pause) continue; + if (AudioListener.pause || RDC.auto) continue; NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; + //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + " : " + GCS.sceneToLoad); scrController controller = __instance.controller; + HitDisableManager hitDisableManager = NoStopMod.asyncInputManager.hitDisableManager; + int count = 0; for (int i = 0; i < keyCodes.Count(); i++) { + if (hitDisableManager.shouldBeDisabled(keyCodes[i])) continue; + if (++count > 4) break; NoStopMod.asyncInputManager.jumpToOtherClass = true; controller.chosenplanet.Update_RefreshAngles(); controller.Hit(); diff --git a/AsyncInput/HitDisable/HitDisableManager.cs b/AsyncInput/HitDisable/HitDisableManager.cs new file mode 100644 index 0000000..f4b6141 --- /dev/null +++ b/AsyncInput/HitDisable/HitDisableManager.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NoStopMod.AsyncInput.HitDisable +{ + class HitDisableManager + { + private Dictionary dictionary; + + public bool scnCLS_searchMode; + + public HitDisableManager() + { + dictionary = new Dictionary(); + + bool[] disableScnNewIntro = Enumerable.Repeat(false, 1024).ToArray(); + dictionary["scnNewIntro"] = disableScnNewIntro; + disableScnNewIntro[(int)KeyCode.BackQuote] = true; + disableScnNewIntro[(int)KeyCode.Alpha0] = true; + disableScnNewIntro[(int)KeyCode.Alpha1] = true; + disableScnNewIntro[(int)KeyCode.Alpha2] = true; + disableScnNewIntro[(int)KeyCode.Alpha3] = true; + disableScnNewIntro[(int)KeyCode.Alpha4] = true; + disableScnNewIntro[(int)KeyCode.Alpha5] = true; + disableScnNewIntro[(int)KeyCode.Alpha6] = true; + disableScnNewIntro[(int)KeyCode.Alpha7] = true; + + bool[] disableScnCLS = Enumerable.Repeat(false, 1024).ToArray(); + dictionary["scnCLS"] = disableScnCLS; + disableScnCLS[(int)KeyCode.S] = true; + disableScnCLS[(int)KeyCode.Delete] = true; + disableScnCLS[(int)KeyCode.F] = true; + disableScnCLS[(int)KeyCode.O] = true; + disableScnCLS[(int)KeyCode.Alpha7] = true; + disableScnCLS[(int)KeyCode.UpArrow] = true; + disableScnCLS[(int)KeyCode.DownArrow] = true; + + scnCLS_searchMode = false; + } + + public bool shouldBeDisabled(KeyCode keyCode) + { + if (keyCode == KeyCode.Escape) return true; + + bool[] disableMasks = dictionary[GCS.sceneToLoad]; + if (disableMasks != null) + { + if (GCS.sceneToLoad == "scnCLS" && scnCLS_searchMode) + { + return true; + } + return disableMasks[(int) keyCode]; + } + return false; + } + + + } +} diff --git a/AsyncInput/HitDisable/HitDisablePatches.cs b/AsyncInput/HitDisable/HitDisablePatches.cs new file mode 100644 index 0000000..0898c45 --- /dev/null +++ b/AsyncInput/HitDisable/HitDisablePatches.cs @@ -0,0 +1,28 @@ +using HarmonyLib; + +namespace NoStopMod.AsyncInput.HitDisable +{ + class HitDisablePatches + { + + [HarmonyPatch(typeof(scnCLS), "Refresh")] + private static class scnCLS_Refresh_Patch + { + public static void Postfix(scnCLS __instance, ref bool ___searchMode) + { + NoStopMod.asyncInputManager.hitDisableManager.scnCLS_searchMode = ___searchMode; + } + } + + [HarmonyPatch(typeof(scnCLS), "ToggleSearchMode")] + private static class scnCLS_ToggleSearchMode_Patch + { + public static void Postfix(scnCLS __instance, ref bool ___searchMode) + { + NoStopMod.asyncInputManager.hitDisableManager.scnCLS_searchMode = ___searchMode; + } + } + + + } +} diff --git a/NoStopMod.csproj b/NoStopMod.csproj index c22ef21..1bdae94 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -89,8 +89,11 @@ + + + From 894b94e63a87f49d5b25fc56071c1374b3f8c7cc Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 12 Jun 2021 10:18:34 +0900 Subject: [PATCH 16/67] Chore: Stabilize onToggle Mechanism --- AsyncInput/AsyncInputManager.cs | 6 ---- HyperRabbit/HyperRabbitManager.cs | 49 +++++++++++++++++++++++++++++++ HyperRabbit/HyperRabbitPatches.cs | 2 +- NoStopMod.cs | 40 ++++++++++++++++++++++--- 4 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 HyperRabbit/HyperRabbitManager.cs diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 414b05e..20d1a3e 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -115,12 +115,6 @@ private void Run() if (keyCodes.Any()) { - //String str = "press " + keyCodes.Count(); - //foreach (KeyCode code in keyCodes) - //{ - // str += code + "(" + ((int)code) + "), "; - //} - //NoStopMod.mod.Logger.Log(str); keyQueue.Enqueue(new Tuple>(currTick, keyCodes)); } } diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitManager.cs new file mode 100644 index 0000000..3206b90 --- /dev/null +++ b/HyperRabbit/HyperRabbitManager.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityModManagerNet; + +namespace NoStopMod.HyperRabbit +{ + class HyperRabbitManager + { + + + public bool isEnabled; + + + enum Status + { + OFF, + FIXED_OTTO, + HYPER_RABBIT, + } + + public HyperRabbitManager() + { + NoStopMod.onToggleListeners.Add(OnToggle); + NoStopMod.onGUIListeners.Add(OnGUI); + } + + private void OnToggle(bool enabled) + { + this.isEnabled = enabled; + } + + private void OnGUI(UnityModManager.ModEntry modEntry) + { + GUILayout.BeginHorizontal("HyperRabbit"); + GUILayout.TextArea("HyperRabbit Status", 20); + //if (GUILayout.Button(tex)) + //{ + + //} + //this.isEnabled = GUILayout.Toggle(isEnabled, "HyperRabbit"); + GUILayout.EndHorizontal(); + } + + } +} diff --git a/HyperRabbit/HyperRabbitPatches.cs b/HyperRabbit/HyperRabbitPatches.cs index 965ec93..d091919 100644 --- a/HyperRabbit/HyperRabbitPatches.cs +++ b/HyperRabbit/HyperRabbitPatches.cs @@ -18,7 +18,7 @@ public static void Prefix(scrPlanet __instance) } [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] - private static class scrController_PlayerControl_Update_Patch2 + private static class scrController_PlayerControl_Update_Patch { public static void Postfix(scrController __instance) { diff --git a/NoStopMod.cs b/NoStopMod.cs index dab24ae..4f9726d 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -5,6 +5,7 @@ using NoStopMod.GarbageCollection; using System.Collections.Generic; using NoStopMod.AsyncInput; +using NoStopMod.HyperRabbit; namespace NoStopMod { @@ -13,22 +14,30 @@ class NoStopMod public static UnityModManager.ModEntry mod; public static Harmony harmony; + public static bool isEnabled = false; + + public static List> onToggleListeners; + public static List> onGUIListeners; + public static GCManager gcManager; public static AsyncInputManager asyncInputManager; - public static List> onToggleListeners; + public static HyperRabbitManager hyperRabbitManager; + - public static bool isEnabled = false; //public static bool ready = false; public static bool Load(UnityModManager.ModEntry modEntry) { - modEntry.OnToggle = new Func(NoStopMod.OnToggle); + modEntry.OnToggle = NoStopMod.OnToggle; + //modEntry.OnGUI = NoStopMod.OnGUI; NoStopMod.harmony = new Harmony(modEntry.Info.Id); NoStopMod.mod = modEntry; NoStopMod.onToggleListeners = new List>(); + NoStopMod.onGUIListeners = new List>(); gcManager = new GCManager(); asyncInputManager = new AsyncInputManager(); + hyperRabbitManager = new HyperRabbitManager(); return true; } @@ -49,11 +58,34 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) isEnabled = enabled; foreach (Action listener in onToggleListeners) { - listener.Invoke(enabled); + try + { + listener.Invoke(enabled); + } + catch (Exception e) + { + mod.Logger.Error("Error on OnToggle : " + e.Message); + } } return true; } + public static void OnGUI(UnityModManager.ModEntry modEntry) + { + NoStopMod.mod = modEntry; + foreach (Action listener in onGUIListeners) + { + try + { + listener.Invoke(modEntry); + } + catch (Exception e) + { + mod.Logger.Error("Error on ONGUI : " + e.Message); + } + } + } + } } From 4b7f26a0fb05e330db9152580d27607ed579e9d6 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 12 Jun 2021 10:58:16 +0900 Subject: [PATCH 17/67] Fix: Fix when GCS.sceneToLoad is null --- AsyncInput/AsyncInputPatches.cs | 2 +- AsyncInput/HitDisable/HitDisableManager.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 9e703e0..8f9137d 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -82,7 +82,7 @@ public static void Prefix(scrController __instance) if (AudioListener.pause || RDC.auto) continue; NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; - //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + " : " + GCS.sceneToLoad); + //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + ")"); scrController controller = __instance.controller; HitDisableManager hitDisableManager = NoStopMod.asyncInputManager.hitDisableManager; diff --git a/AsyncInput/HitDisable/HitDisableManager.cs b/AsyncInput/HitDisable/HitDisableManager.cs index f4b6141..0deec47 100644 --- a/AsyncInput/HitDisable/HitDisableManager.cs +++ b/AsyncInput/HitDisable/HitDisableManager.cs @@ -45,6 +45,7 @@ public HitDisableManager() public bool shouldBeDisabled(KeyCode keyCode) { if (keyCode == KeyCode.Escape) return true; + if (GCS.sceneToLoad == null) GCS.sceneToLoad = "scnNewIntro"; bool[] disableMasks = dictionary[GCS.sceneToLoad]; if (disableMasks != null) From b436a87f5279fd21bd4ea0f11e01458dcf24bdf5 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 12 Jun 2021 11:01:28 +0900 Subject: [PATCH 18/67] Refactor: Change names HitDisable to HitIgnore --- AsyncInput/AsyncInputManager.cs | 6 +- AsyncInput/AsyncInputPatches.cs | 15 +++-- AsyncInput/HitDisable/HitDisableManager.cs | 64 ---------------------- AsyncInput/HitDisable/HitDisablePatches.cs | 28 ---------- AsyncInput/HitIgnore/HitIgnoreManager.cs | 64 ++++++++++++++++++++++ AsyncInput/HitIgnore/HitIgnorePatches.cs | 47 ++++++++++++++++ NoStopMod.csproj | 4 +- 7 files changed, 126 insertions(+), 102 deletions(-) delete mode 100644 AsyncInput/HitDisable/HitDisableManager.cs delete mode 100644 AsyncInput/HitDisable/HitDisablePatches.cs create mode 100644 AsyncInput/HitIgnore/HitIgnoreManager.cs create mode 100644 AsyncInput/HitIgnore/HitIgnorePatches.cs diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 20d1a3e..f8b1201 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -1,4 +1,4 @@ -using NoStopMod.AsyncInput.HitDisable; +using NoStopMod.AsyncInput.HitIgnore; using System; using System.Collections.Generic; using System.Linq; @@ -10,7 +10,7 @@ namespace NoStopMod.AsyncInput class AsyncInputManager { - public HitDisableManager hitDisableManager; + public HitIgnoreManager hitIgnoreManager; private Thread thread; public Queue>> keyQueue = new Queue>>(); @@ -34,7 +34,7 @@ public AsyncInputManager() mask = Enumerable.Repeat(false, 1024).ToArray(); - hitDisableManager = new HitDisableManager(); + hitIgnoreManager = new HitIgnoreManager(); } private void OnToggle(bool enabled) diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 8f9137d..ee40e0d 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -1,6 +1,6 @@ using DG.Tweening; using HarmonyLib; -using NoStopMod.AsyncInput.HitDisable; +using NoStopMod.AsyncInput.HitIgnore; using System; using System.Collections.Generic; using System.Linq; @@ -61,7 +61,7 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) if (__instance.controller.GetState().CompareTo(scrController.States.PlayerControl) != 0) { - //NoStopMod.mod.Logger.Log("Update " + __instance.controller.GetState() + ", " + ((Enum)scrController.States.PlayerControl) + " : " + (__instance.controller.GetState() != (Enum)scrController.States.PlayerControl)); + //NoStopMod.mod.Logger.Log("Ignore All " + __instance.controller.GetState() + ", " + GCS.sceneToLoad); NoStopMod.asyncInputManager.keyQueue.Clear(); } @@ -82,15 +82,20 @@ public static void Prefix(scrController __instance) if (AudioListener.pause || RDC.auto) continue; NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; - //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + ")"); + NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + "), " + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType); scrController controller = __instance.controller; - HitDisableManager hitDisableManager = NoStopMod.asyncInputManager.hitDisableManager; + HitIgnoreManager hitDisableManager = NoStopMod.asyncInputManager.hitIgnoreManager; int count = 0; for (int i = 0; i < keyCodes.Count(); i++) { - if (hitDisableManager.shouldBeDisabled(keyCodes[i])) continue; + if (hitDisableManager.shouldBeIgnored(keyCodes[i])) + { + NoStopMod.mod.Logger.Log("Ignored" + keyCodes[i] + ", " + GCS.sceneToLoad + ", " + __instance.GetState()); + continue; + } if (++count > 4) break; + NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", " + __instance.GetState()); NoStopMod.asyncInputManager.jumpToOtherClass = true; controller.chosenplanet.Update_RefreshAngles(); controller.Hit(); diff --git a/AsyncInput/HitDisable/HitDisableManager.cs b/AsyncInput/HitDisable/HitDisableManager.cs deleted file mode 100644 index 0deec47..0000000 --- a/AsyncInput/HitDisable/HitDisableManager.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace NoStopMod.AsyncInput.HitDisable -{ - class HitDisableManager - { - private Dictionary dictionary; - - public bool scnCLS_searchMode; - - public HitDisableManager() - { - dictionary = new Dictionary(); - - bool[] disableScnNewIntro = Enumerable.Repeat(false, 1024).ToArray(); - dictionary["scnNewIntro"] = disableScnNewIntro; - disableScnNewIntro[(int)KeyCode.BackQuote] = true; - disableScnNewIntro[(int)KeyCode.Alpha0] = true; - disableScnNewIntro[(int)KeyCode.Alpha1] = true; - disableScnNewIntro[(int)KeyCode.Alpha2] = true; - disableScnNewIntro[(int)KeyCode.Alpha3] = true; - disableScnNewIntro[(int)KeyCode.Alpha4] = true; - disableScnNewIntro[(int)KeyCode.Alpha5] = true; - disableScnNewIntro[(int)KeyCode.Alpha6] = true; - disableScnNewIntro[(int)KeyCode.Alpha7] = true; - - bool[] disableScnCLS = Enumerable.Repeat(false, 1024).ToArray(); - dictionary["scnCLS"] = disableScnCLS; - disableScnCLS[(int)KeyCode.S] = true; - disableScnCLS[(int)KeyCode.Delete] = true; - disableScnCLS[(int)KeyCode.F] = true; - disableScnCLS[(int)KeyCode.O] = true; - disableScnCLS[(int)KeyCode.Alpha7] = true; - disableScnCLS[(int)KeyCode.UpArrow] = true; - disableScnCLS[(int)KeyCode.DownArrow] = true; - - scnCLS_searchMode = false; - } - - public bool shouldBeDisabled(KeyCode keyCode) - { - if (keyCode == KeyCode.Escape) return true; - if (GCS.sceneToLoad == null) GCS.sceneToLoad = "scnNewIntro"; - - bool[] disableMasks = dictionary[GCS.sceneToLoad]; - if (disableMasks != null) - { - if (GCS.sceneToLoad == "scnCLS" && scnCLS_searchMode) - { - return true; - } - return disableMasks[(int) keyCode]; - } - return false; - } - - - } -} diff --git a/AsyncInput/HitDisable/HitDisablePatches.cs b/AsyncInput/HitDisable/HitDisablePatches.cs deleted file mode 100644 index 0898c45..0000000 --- a/AsyncInput/HitDisable/HitDisablePatches.cs +++ /dev/null @@ -1,28 +0,0 @@ -using HarmonyLib; - -namespace NoStopMod.AsyncInput.HitDisable -{ - class HitDisablePatches - { - - [HarmonyPatch(typeof(scnCLS), "Refresh")] - private static class scnCLS_Refresh_Patch - { - public static void Postfix(scnCLS __instance, ref bool ___searchMode) - { - NoStopMod.asyncInputManager.hitDisableManager.scnCLS_searchMode = ___searchMode; - } - } - - [HarmonyPatch(typeof(scnCLS), "ToggleSearchMode")] - private static class scnCLS_ToggleSearchMode_Patch - { - public static void Postfix(scnCLS __instance, ref bool ___searchMode) - { - NoStopMod.asyncInputManager.hitDisableManager.scnCLS_searchMode = ___searchMode; - } - } - - - } -} diff --git a/AsyncInput/HitIgnore/HitIgnoreManager.cs b/AsyncInput/HitIgnore/HitIgnoreManager.cs new file mode 100644 index 0000000..3ba076b --- /dev/null +++ b/AsyncInput/HitIgnore/HitIgnoreManager.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace NoStopMod.AsyncInput.HitIgnore +{ + class HitIgnoreManager + { + private Dictionary dictionary; + + public bool scnCLS_searchMode; + public EndLevelType scrController_endLevelType; + + public HitIgnoreManager() + { + if (GCS.sceneToLoad == null) GCS.sceneToLoad = "scnNewIntro"; + + dictionary = new Dictionary(); + + bool[] ignoreScnNewIntro = Enumerable.Repeat(false, 1024).ToArray(); + dictionary["scnNewIntro"] = ignoreScnNewIntro; + ignoreScnNewIntro[(int)KeyCode.BackQuote] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha0] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha1] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha2] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha3] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha4] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha5] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha6] = true; + ignoreScnNewIntro[(int)KeyCode.Alpha7] = true; + + bool[] ignoreScnCLS = Enumerable.Repeat(false, 1024).ToArray(); + dictionary["scnCLS"] = ignoreScnCLS; + ignoreScnCLS[(int)KeyCode.S] = true; + ignoreScnCLS[(int)KeyCode.Delete] = true; + ignoreScnCLS[(int)KeyCode.F] = true; + ignoreScnCLS[(int)KeyCode.O] = true; + ignoreScnCLS[(int)KeyCode.Alpha7] = true; + ignoreScnCLS[(int)KeyCode.UpArrow] = true; + ignoreScnCLS[(int)KeyCode.DownArrow] = true; + + scnCLS_searchMode = false; + } + + public bool shouldBeIgnored(KeyCode keyCode) + { + if (keyCode == KeyCode.Escape) return true; + + bool[] ignoreScnCLS; + if (dictionary.TryGetValue(GCS.sceneToLoad, out ignoreScnCLS)) + { + if (GCS.sceneToLoad == "scnCLS" && scnCLS_searchMode) + { + return true; + } + return ignoreScnCLS[(int) keyCode]; + } + return false; + } + + + } +} diff --git a/AsyncInput/HitIgnore/HitIgnorePatches.cs b/AsyncInput/HitIgnore/HitIgnorePatches.cs new file mode 100644 index 0000000..cafd1aa --- /dev/null +++ b/AsyncInput/HitIgnore/HitIgnorePatches.cs @@ -0,0 +1,47 @@ +using HarmonyLib; + +namespace NoStopMod.AsyncInput.HitIgnore +{ + class HitIgnorePatches + { + + // scnCLS_serachMode //////////////////////////////////// + [HarmonyPatch(typeof(scnCLS), "Refresh")] + private static class scnCLS_Refresh_Patch + { + public static void Postfix(scnCLS __instance, ref bool ___searchMode) + { + NoStopMod.asyncInputManager.hitIgnoreManager.scnCLS_searchMode = ___searchMode; + } + } + + [HarmonyPatch(typeof(scnCLS), "ToggleSearchMode")] + private static class scnCLS_ToggleSearchMode_Patch + { + public static void Postfix(scnCLS __instance, ref bool ___searchMode) + { + NoStopMod.asyncInputManager.hitIgnoreManager.scnCLS_searchMode = ___searchMode; + } + } + + // scrController_endLevelType ////////////////////////// + [HarmonyPatch(typeof(scrController), "Fail2Action")] + private static class scrController_Fail2Action_Patch + { + public static void Postfix(scrController __instance, ref bool ___searchMode) + { + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType = __instance.endLevelType; + } + } + + [HarmonyPatch(typeof(scrController), "OnLandOnPortal")] + private static class scrController_OnLandOnPortal_Patch + { + public static void Postfix(scrController __instance, ref bool ___searchMode) + { + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType = __instance.endLevelType; + } + } + + } +} diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 1bdae94..48c6ba2 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -89,8 +89,8 @@ - - + + From c4439823f57fea5ef0d936e96697840c277ee05f Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 12 Jun 2021 11:03:47 +0900 Subject: [PATCH 19/67] Fix: Fix No such field defined error in HitIgnorePatches --- AsyncInput/HitIgnore/HitIgnorePatches.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AsyncInput/HitIgnore/HitIgnorePatches.cs b/AsyncInput/HitIgnore/HitIgnorePatches.cs index cafd1aa..b3dafab 100644 --- a/AsyncInput/HitIgnore/HitIgnorePatches.cs +++ b/AsyncInput/HitIgnore/HitIgnorePatches.cs @@ -28,7 +28,7 @@ public static void Postfix(scnCLS __instance, ref bool ___searchMode) [HarmonyPatch(typeof(scrController), "Fail2Action")] private static class scrController_Fail2Action_Patch { - public static void Postfix(scrController __instance, ref bool ___searchMode) + public static void Postfix(scrController __instance) { NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType = __instance.endLevelType; } @@ -37,7 +37,7 @@ public static void Postfix(scrController __instance, ref bool ___searchMode) [HarmonyPatch(typeof(scrController), "OnLandOnPortal")] private static class scrController_OnLandOnPortal_Patch { - public static void Postfix(scrController __instance, ref bool ___searchMode) + public static void Postfix(scrController __instance) { NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType = __instance.endLevelType; } From 26ebf773628bdf2a41454f7168a8520f54052532 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 12 Jun 2021 12:12:20 +0900 Subject: [PATCH 20/67] Fix: Fix input when game is end. --- AsyncInput/AsyncInputPatches.cs | 25 ++++-------------------- AsyncInput/HitIgnore/HitIgnoreManager.cs | 3 ++- AsyncInput/HitIgnore/HitIgnorePatches.cs | 14 +++++++------ 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index ee40e0d..c579021 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -59,20 +59,6 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); } - if (__instance.controller.GetState().CompareTo(scrController.States.PlayerControl) != 0) - { - //NoStopMod.mod.Logger.Log("Ignore All " + __instance.controller.GetState() + ", " + GCS.sceneToLoad); - NoStopMod.asyncInputManager.keyQueue.Clear(); - } - - } - } - - [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] - private static class scrController_PlayerControl_Update_Patch - { - public static void Prefix(scrController __instance) - { while (NoStopMod.asyncInputManager.keyQueue.Any()) { long tick; @@ -82,25 +68,22 @@ public static void Prefix(scrController __instance) if (AudioListener.pause || RDC.auto) continue; NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; - NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + "), " + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType); + //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + "), " + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state + ", " + __instance.controller.GetState()); scrController controller = __instance.controller; HitIgnoreManager hitDisableManager = NoStopMod.asyncInputManager.hitIgnoreManager; int count = 0; for (int i = 0; i < keyCodes.Count(); i++) { - if (hitDisableManager.shouldBeIgnored(keyCodes[i])) - { - NoStopMod.mod.Logger.Log("Ignored" + keyCodes[i] + ", " + GCS.sceneToLoad + ", " + __instance.GetState()); - continue; - } + if (hitDisableManager.shouldBeIgnored(keyCodes[i])) continue; if (++count > 4) break; - NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", " + __instance.GetState()); + //NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", "); NoStopMod.asyncInputManager.jumpToOtherClass = true; controller.chosenplanet.Update_RefreshAngles(); controller.Hit(); } } + } } diff --git a/AsyncInput/HitIgnore/HitIgnoreManager.cs b/AsyncInput/HitIgnore/HitIgnoreManager.cs index 3ba076b..a1cc258 100644 --- a/AsyncInput/HitIgnore/HitIgnoreManager.cs +++ b/AsyncInput/HitIgnore/HitIgnoreManager.cs @@ -10,7 +10,7 @@ class HitIgnoreManager private Dictionary dictionary; public bool scnCLS_searchMode; - public EndLevelType scrController_endLevelType; + public scrController.States scrController_state; public HitIgnoreManager() { @@ -46,6 +46,7 @@ public HitIgnoreManager() public bool shouldBeIgnored(KeyCode keyCode) { if (keyCode == KeyCode.Escape) return true; + if (scrController_state != scrController.States.PlayerControl) return true; bool[] ignoreScnCLS; if (dictionary.TryGetValue(GCS.sceneToLoad, out ignoreScnCLS)) diff --git a/AsyncInput/HitIgnore/HitIgnorePatches.cs b/AsyncInput/HitIgnore/HitIgnorePatches.cs index b3dafab..49f6d42 100644 --- a/AsyncInput/HitIgnore/HitIgnorePatches.cs +++ b/AsyncInput/HitIgnore/HitIgnorePatches.cs @@ -1,4 +1,6 @@ using HarmonyLib; +using MonsterLove.StateMachine; +using System; namespace NoStopMod.AsyncInput.HitIgnore { @@ -24,13 +26,13 @@ public static void Postfix(scnCLS __instance, ref bool ___searchMode) } } - // scrController_endLevelType ////////////////////////// - [HarmonyPatch(typeof(scrController), "Fail2Action")] - private static class scrController_Fail2Action_Patch + // scrController_state ////////////////////////// + [HarmonyPatch(typeof(StateEngine), "ChangeState")] + private static class StateEngine_ChangeState_Patch { - public static void Postfix(scrController __instance) + public static void Postfix(StateEngine __instance, Enum newState, StateTransition transition) { - NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType = __instance.endLevelType; + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state = (scrController.States) newState; } } @@ -39,7 +41,7 @@ private static class scrController_OnLandOnPortal_Patch { public static void Postfix(scrController __instance) { - NoStopMod.asyncInputManager.hitIgnoreManager.scrController_endLevelType = __instance.endLevelType; + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state = scrController.States.Won; } } From 4a7852fc702c8412c9ca0444f74a2aa93c8ac22f Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 12 Jun 2021 12:22:42 +0900 Subject: [PATCH 21/67] Feat: Use more native mechanism when dealing with Hit. --- AsyncInput/AsyncInputPatches.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index c579021..1d81550 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -78,10 +78,16 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) if (hitDisableManager.shouldBeIgnored(keyCodes[i])) continue; if (++count > 4) break; //NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", "); + } + controller.keyBufferCount += count; + while (controller.keyBufferCount > 0) + { + controller.keyBufferCount--; NoStopMod.asyncInputManager.jumpToOtherClass = true; controller.chosenplanet.Update_RefreshAngles(); controller.Hit(); } + } } From 7966a2b5f68a7f1051bfb9980c144799790d775b Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 16 Jun 2021 15:51:11 +0900 Subject: [PATCH 22/67] Feat: Create Settings --- Abstraction/SettingsBase.cs | 18 + AsyncInput/AsyncInputManager.cs | 4 + AsyncInput/AsyncInputPatches.cs | 2 +- NoStopMod.cs | 6 +- Settings.cs | 62 ++ lib/SimpleJSON.cs | 1434 +++++++++++++++++++++++++++++++ 6 files changed, 1522 insertions(+), 4 deletions(-) create mode 100644 Abstraction/SettingsBase.cs create mode 100644 Settings.cs create mode 100644 lib/SimpleJSON.cs diff --git a/Abstraction/SettingsBase.cs b/Abstraction/SettingsBase.cs new file mode 100644 index 0000000..6c6e056 --- /dev/null +++ b/Abstraction/SettingsBase.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SimpleJSON; + +namespace NoStopMod.Abstraction +{ + interface SettingsBase + { + + void Load(JSONNode json); + + void Save(JSONNode json); + + } +} diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index f8b1201..15ad0ba 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using UnityEngine; @@ -25,6 +26,9 @@ class AsyncInputManager private bool[] mask; + //[DllImport("USER32.dll")] + //static extern short GetKeyState(VirtualKeyStates nVirtKey); + public AsyncInputManager() { NoStopMod.onToggleListeners.Add(OnToggle); diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 1d81550..6f68442 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -67,7 +67,6 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) if (AudioListener.pause || RDC.auto) continue; - NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + "), " + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state + ", " + __instance.controller.GetState()); scrController controller = __instance.controller; @@ -79,6 +78,7 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) if (++count > 4) break; //NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", "); } + NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; controller.keyBufferCount += count; while (controller.keyBufferCount > 0) { diff --git a/NoStopMod.cs b/NoStopMod.cs index 4f9726d..f589d68 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using NoStopMod.AsyncInput; using NoStopMod.HyperRabbit; +using SimpleJSON; namespace NoStopMod { @@ -23,9 +24,6 @@ class NoStopMod public static AsyncInputManager asyncInputManager; public static HyperRabbitManager hyperRabbitManager; - - //public static bool ready = false; - public static bool Load(UnityModManager.ModEntry modEntry) { modEntry.OnToggle = NoStopMod.OnToggle; @@ -39,6 +37,8 @@ public static bool Load(UnityModManager.ModEntry modEntry) asyncInputManager = new AsyncInputManager(); hyperRabbitManager = new HyperRabbitManager(); + + return true; } diff --git a/Settings.cs b/Settings.cs new file mode 100644 index 0000000..4f7872e --- /dev/null +++ b/Settings.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NoStopMod.Abstraction; +using SimpleJSON; +using UnityEngine; + +namespace NoStopMod +{ + class Settings + { + + public const String path = "\\Mods\\NoStopMod\\settings.json"; + + public static List settings; + + public static void Load() + { + TextAsset json = Resources.Load(Environment.CurrentDirectory + path); + if (json == null) + { + Save(); + return; + } + + JSONNode jsonNode = JSON.Parse(json.text); + for (int i = 0; i < settings.Count(); i++) + { + try + { + settings[i].Load(jsonNode); + } + catch (Exception e) + { + NoStopMod.mod.Logger.Error("While Loading : " + e.Message + ", " + e.StackTrace); + } + } + } + + public static void Save() + { + JSONNode node = JSON.Parse("{}"); + for (int i = 0;i < settings.Count();i++) + { + try + { + settings[i].Save(node); + } + catch (Exception e) + { + NoStopMod.mod.Logger.Error("While Saving : " + e.Message + ", " + e.StackTrace); + } + } + + File.WriteAllText(Environment.CurrentDirectory + path, node.ToString()); + } + + } +} diff --git a/lib/SimpleJSON.cs b/lib/SimpleJSON.cs new file mode 100644 index 0000000..4777724 --- /dev/null +++ b/lib/SimpleJSON.cs @@ -0,0 +1,1434 @@ +/* * * * * + * A simple JSON Parser / builder + * ------------------------------ + * + * It mainly has been written as a simple JSON parser. It can build a JSON string + * from the node-tree, or generate a node tree from any valid JSON string. + * + * Written by Bunny83 + * 2012-06-09 + * + * Changelog now external. See Changelog.txt + * + * The MIT License (MIT) + * + * Copyright (c) 2012-2019 Markus Göbel (Bunny83) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * * * * */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace SimpleJSON +{ + public enum JSONNodeType + { + Array = 1, + Object = 2, + String = 3, + Number = 4, + NullValue = 5, + Boolean = 6, + None = 7, + Custom = 0xFF, + } + public enum JSONTextMode + { + Compact, + Indent + } + + public abstract partial class JSONNode + { + #region Enumerators + public struct Enumerator + { + private enum Type { None, Array, Object } + private Type type; + private Dictionary.Enumerator m_Object; + private List.Enumerator m_Array; + public bool IsValid { get { return type != Type.None; } } + public Enumerator(List.Enumerator aArrayEnum) + { + type = Type.Array; + m_Object = default(Dictionary.Enumerator); + m_Array = aArrayEnum; + } + public Enumerator(Dictionary.Enumerator aDictEnum) + { + type = Type.Object; + m_Object = aDictEnum; + m_Array = default(List.Enumerator); + } + public KeyValuePair Current + { + get + { + if (type == Type.Array) + return new KeyValuePair(string.Empty, m_Array.Current); + else if (type == Type.Object) + return m_Object.Current; + return new KeyValuePair(string.Empty, null); + } + } + public bool MoveNext() + { + if (type == Type.Array) + return m_Array.MoveNext(); + else if (type == Type.Object) + return m_Object.MoveNext(); + return false; + } + } + public struct ValueEnumerator + { + private Enumerator m_Enumerator; + public ValueEnumerator(List.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } + public ValueEnumerator(Dictionary.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } + public ValueEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } + public JSONNode Current { get { return m_Enumerator.Current.Value; } } + public bool MoveNext() { return m_Enumerator.MoveNext(); } + public ValueEnumerator GetEnumerator() { return this; } + } + public struct KeyEnumerator + { + private Enumerator m_Enumerator; + public KeyEnumerator(List.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } + public KeyEnumerator(Dictionary.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } + public KeyEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } + public string Current { get { return m_Enumerator.Current.Key; } } + public bool MoveNext() { return m_Enumerator.MoveNext(); } + public KeyEnumerator GetEnumerator() { return this; } + } + + public class LinqEnumerator : IEnumerator>, IEnumerable> + { + private JSONNode m_Node; + private Enumerator m_Enumerator; + internal LinqEnumerator(JSONNode aNode) + { + m_Node = aNode; + if (m_Node != null) + m_Enumerator = m_Node.GetEnumerator(); + } + public KeyValuePair Current { get { return m_Enumerator.Current; } } + object IEnumerator.Current { get { return m_Enumerator.Current; } } + public bool MoveNext() { return m_Enumerator.MoveNext(); } + + public void Dispose() + { + m_Node = null; + m_Enumerator = new Enumerator(); + } + + public IEnumerator> GetEnumerator() + { + return new LinqEnumerator(m_Node); + } + + public void Reset() + { + if (m_Node != null) + m_Enumerator = m_Node.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new LinqEnumerator(m_Node); + } + } + + #endregion Enumerators + + #region common interface + + public static bool forceASCII = false; // Use Unicode by default + public static bool longAsString = false; // lazy creator creates a JSONString instead of JSONNumber + public static bool allowLineComments = true; // allow "//"-style comments at the end of a line + + public abstract JSONNodeType Tag { get; } + + public virtual JSONNode this[int aIndex] { get { return null; } set { } } + + public virtual JSONNode this[string aKey] { get { return null; } set { } } + + public virtual string Value { get { return ""; } set { } } + + public virtual int Count { get { return 0; } } + + public virtual bool IsNumber { get { return false; } } + public virtual bool IsString { get { return false; } } + public virtual bool IsBoolean { get { return false; } } + public virtual bool IsNull { get { return false; } } + public virtual bool IsArray { get { return false; } } + public virtual bool IsObject { get { return false; } } + + public virtual bool Inline { get { return false; } set { } } + + public virtual void Add(string aKey, JSONNode aItem) + { + } + public virtual void Add(JSONNode aItem) + { + Add("", aItem); + } + + public virtual JSONNode Remove(string aKey) + { + return null; + } + + public virtual JSONNode Remove(int aIndex) + { + return null; + } + + public virtual JSONNode Remove(JSONNode aNode) + { + return aNode; + } + public virtual void Clear() { } + + public virtual JSONNode Clone() + { + return null; + } + + public virtual IEnumerable Children + { + get + { + yield break; + } + } + + public IEnumerable DeepChildren + { + get + { + foreach (var C in Children) + foreach (var D in C.DeepChildren) + yield return D; + } + } + + public virtual bool HasKey(string aKey) + { + return false; + } + + public virtual JSONNode GetValueOrDefault(string aKey, JSONNode aDefault) + { + return aDefault; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + WriteToStringBuilder(sb, 0, 0, JSONTextMode.Compact); + return sb.ToString(); + } + + public virtual string ToString(int aIndent) + { + StringBuilder sb = new StringBuilder(); + WriteToStringBuilder(sb, 0, aIndent, JSONTextMode.Indent); + return sb.ToString(); + } + internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode); + + public abstract Enumerator GetEnumerator(); + public IEnumerable> Linq { get { return new LinqEnumerator(this); } } + public KeyEnumerator Keys { get { return new KeyEnumerator(GetEnumerator()); } } + public ValueEnumerator Values { get { return new ValueEnumerator(GetEnumerator()); } } + + #endregion common interface + + #region typecasting properties + + + public virtual double AsDouble + { + get + { + double v = 0.0; + if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out v)) + return v; + return 0.0; + } + set + { + Value = value.ToString(CultureInfo.InvariantCulture); + } + } + + public virtual int AsInt + { + get { return (int)AsDouble; } + set { AsDouble = value; } + } + + public virtual float AsFloat + { + get { return (float)AsDouble; } + set { AsDouble = value; } + } + + public virtual bool AsBool + { + get + { + bool v = false; + if (bool.TryParse(Value, out v)) + return v; + return !string.IsNullOrEmpty(Value); + } + set + { + Value = (value) ? "true" : "false"; + } + } + + public virtual long AsLong + { + get + { + long val = 0; + if (long.TryParse(Value, out val)) + return val; + return 0L; + } + set + { + Value = value.ToString(); + } + } + + public virtual ulong AsULong + { + get + { + ulong val = 0; + if (ulong.TryParse(Value, out val)) + return val; + return 0; + } + set + { + Value = value.ToString(); + } + } + + public virtual JSONArray AsArray + { + get + { + return this as JSONArray; + } + } + + public virtual JSONObject AsObject + { + get + { + return this as JSONObject; + } + } + + + #endregion typecasting properties + + #region operators + + public static implicit operator JSONNode(string s) + { + return (s == null) ? (JSONNode) JSONNull.CreateOrGet() : new JSONString(s); + } + public static implicit operator string(JSONNode d) + { + return (d == null) ? null : d.Value; + } + + public static implicit operator JSONNode(double n) + { + return new JSONNumber(n); + } + public static implicit operator double(JSONNode d) + { + return (d == null) ? 0 : d.AsDouble; + } + + public static implicit operator JSONNode(float n) + { + return new JSONNumber(n); + } + public static implicit operator float(JSONNode d) + { + return (d == null) ? 0 : d.AsFloat; + } + + public static implicit operator JSONNode(int n) + { + return new JSONNumber(n); + } + public static implicit operator int(JSONNode d) + { + return (d == null) ? 0 : d.AsInt; + } + + public static implicit operator JSONNode(long n) + { + if (longAsString) + return new JSONString(n.ToString()); + return new JSONNumber(n); + } + public static implicit operator long(JSONNode d) + { + return (d == null) ? 0L : d.AsLong; + } + + public static implicit operator JSONNode(ulong n) + { + if (longAsString) + return new JSONString(n.ToString()); + return new JSONNumber(n); + } + public static implicit operator ulong(JSONNode d) + { + return (d == null) ? 0 : d.AsULong; + } + + public static implicit operator JSONNode(bool b) + { + return new JSONBool(b); + } + public static implicit operator bool(JSONNode d) + { + return (d == null) ? false : d.AsBool; + } + + public static implicit operator JSONNode(KeyValuePair aKeyValue) + { + return aKeyValue.Value; + } + + public static bool operator ==(JSONNode a, object b) + { + if (ReferenceEquals(a, b)) + return true; + bool aIsNull = a is JSONNull || ReferenceEquals(a, null) || a is JSONLazyCreator; + bool bIsNull = b is JSONNull || ReferenceEquals(b, null) || b is JSONLazyCreator; + if (aIsNull && bIsNull) + return true; + return !aIsNull && a.Equals(b); + } + + public static bool operator !=(JSONNode a, object b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + return ReferenceEquals(this, obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #endregion operators + + [ThreadStatic] + private static StringBuilder m_EscapeBuilder; + internal static StringBuilder EscapeBuilder + { + get + { + if (m_EscapeBuilder == null) + m_EscapeBuilder = new StringBuilder(); + return m_EscapeBuilder; + } + } + internal static string Escape(string aText) + { + var sb = EscapeBuilder; + sb.Length = 0; + if (sb.Capacity < aText.Length + aText.Length / 10) + sb.Capacity = aText.Length + aText.Length / 10; + foreach (char c in aText) + { + switch (c) + { + case '\\': + sb.Append("\\\\"); + break; + case '\"': + sb.Append("\\\""); + break; + case '\n': + sb.Append("\\n"); + break; + case '\r': + sb.Append("\\r"); + break; + case '\t': + sb.Append("\\t"); + break; + case '\b': + sb.Append("\\b"); + break; + case '\f': + sb.Append("\\f"); + break; + default: + if (c < ' ' || (forceASCII && c > 127)) + { + ushort val = c; + sb.Append("\\u").Append(val.ToString("X4")); + } + else + sb.Append(c); + break; + } + } + string result = sb.ToString(); + sb.Length = 0; + return result; + } + + private static JSONNode ParseElement(string token, bool quoted) + { + if (quoted) + return token; + if (token.Length <= 5) + { + string tmp = token.ToLower(); + if (tmp == "false" || tmp == "true") + return tmp == "true"; + if (tmp == "null") + return JSONNull.CreateOrGet(); + } + double val; + if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out val)) + return val; + else + return token; + } + + public static JSONNode Parse(string aJSON) + { + Stack stack = new Stack(); + JSONNode ctx = null; + int i = 0; + StringBuilder Token = new StringBuilder(); + string TokenName = ""; + bool QuoteMode = false; + bool TokenIsQuoted = false; + bool HasNewlineChar = false; + while (i < aJSON.Length) + { + switch (aJSON[i]) + { + case '{': + if (QuoteMode) + { + Token.Append(aJSON[i]); + break; + } + stack.Push(new JSONObject()); + if (ctx != null) + { + ctx.Add(TokenName, stack.Peek()); + } + TokenName = ""; + Token.Length = 0; + ctx = stack.Peek(); + HasNewlineChar = false; + break; + + case '[': + if (QuoteMode) + { + Token.Append(aJSON[i]); + break; + } + + stack.Push(new JSONArray()); + if (ctx != null) + { + ctx.Add(TokenName, stack.Peek()); + } + TokenName = ""; + Token.Length = 0; + ctx = stack.Peek(); + HasNewlineChar = false; + break; + + case '}': + case ']': + if (QuoteMode) + { + + Token.Append(aJSON[i]); + break; + } + if (stack.Count == 0) + throw new Exception("JSON Parse: Too many closing brackets"); + + stack.Pop(); + if (Token.Length > 0 || TokenIsQuoted) + ctx.Add(TokenName, ParseElement(Token.ToString(), TokenIsQuoted)); + if (ctx != null) + ctx.Inline = !HasNewlineChar; + TokenIsQuoted = false; + TokenName = ""; + Token.Length = 0; + if (stack.Count > 0) + ctx = stack.Peek(); + break; + + case ':': + if (QuoteMode) + { + Token.Append(aJSON[i]); + break; + } + TokenName = Token.ToString(); + Token.Length = 0; + TokenIsQuoted = false; + break; + + case '"': + QuoteMode ^= true; + TokenIsQuoted |= QuoteMode; + break; + + case ',': + if (QuoteMode) + { + Token.Append(aJSON[i]); + break; + } + if (Token.Length > 0 || TokenIsQuoted) + ctx.Add(TokenName, ParseElement(Token.ToString(), TokenIsQuoted)); + TokenIsQuoted = false; + TokenName = ""; + Token.Length = 0; + TokenIsQuoted = false; + break; + + case '\r': + case '\n': + HasNewlineChar = true; + break; + + case ' ': + case '\t': + if (QuoteMode) + Token.Append(aJSON[i]); + break; + + case '\\': + ++i; + if (QuoteMode) + { + char C = aJSON[i]; + switch (C) + { + case 't': + Token.Append('\t'); + break; + case 'r': + Token.Append('\r'); + break; + case 'n': + Token.Append('\n'); + break; + case 'b': + Token.Append('\b'); + break; + case 'f': + Token.Append('\f'); + break; + case 'u': + { + string s = aJSON.Substring(i + 1, 4); + Token.Append((char)int.Parse( + s, + System.Globalization.NumberStyles.AllowHexSpecifier)); + i += 4; + break; + } + default: + Token.Append(C); + break; + } + } + break; + case '/': + if (allowLineComments && !QuoteMode && i + 1 < aJSON.Length && aJSON[i + 1] == '/') + { + while (++i < aJSON.Length && aJSON[i] != '\n' && aJSON[i] != '\r') ; + break; + } + Token.Append(aJSON[i]); + break; + case '\uFEFF': // remove / ignore BOM (Byte Order Mark) + break; + + default: + Token.Append(aJSON[i]); + break; + } + ++i; + } + if (QuoteMode) + { + throw new Exception("JSON Parse: Quotation marks seems to be messed up."); + } + if (ctx == null) + return ParseElement(Token.ToString(), TokenIsQuoted); + return ctx; + } + + } + // End of JSONNode + + public partial class JSONArray : JSONNode + { + private List m_List = new List(); + private bool inline = false; + public override bool Inline + { + get { return inline; } + set { inline = value; } + } + + public override JSONNodeType Tag { get { return JSONNodeType.Array; } } + public override bool IsArray { get { return true; } } + public override Enumerator GetEnumerator() { return new Enumerator(m_List.GetEnumerator()); } + + public override JSONNode this[int aIndex] + { + get + { + if (aIndex < 0 || aIndex >= m_List.Count) + return new JSONLazyCreator(this); + return m_List[aIndex]; + } + set + { + if (value == null) + value = JSONNull.CreateOrGet(); + if (aIndex < 0 || aIndex >= m_List.Count) + m_List.Add(value); + else + m_List[aIndex] = value; + } + } + + public override JSONNode this[string aKey] + { + get { return new JSONLazyCreator(this); } + set + { + if (value == null) + value = JSONNull.CreateOrGet(); + m_List.Add(value); + } + } + + public override int Count + { + get { return m_List.Count; } + } + + public override void Add(string aKey, JSONNode aItem) + { + if (aItem == null) + aItem = JSONNull.CreateOrGet(); + m_List.Add(aItem); + } + + public override JSONNode Remove(int aIndex) + { + if (aIndex < 0 || aIndex >= m_List.Count) + return null; + JSONNode tmp = m_List[aIndex]; + m_List.RemoveAt(aIndex); + return tmp; + } + + public override JSONNode Remove(JSONNode aNode) + { + m_List.Remove(aNode); + return aNode; + } + + public override void Clear() + { + m_List.Clear(); + } + + public override JSONNode Clone() + { + var node = new JSONArray(); + node.m_List.Capacity = m_List.Capacity; + foreach(var n in m_List) + { + if (n != null) + node.Add(n.Clone()); + else + node.Add(null); + } + return node; + } + + public override IEnumerable Children + { + get + { + foreach (JSONNode N in m_List) + yield return N; + } + } + + + internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) + { + aSB.Append('['); + int count = m_List.Count; + if (inline) + aMode = JSONTextMode.Compact; + for (int i = 0; i < count; i++) + { + if (i > 0) + aSB.Append(','); + if (aMode == JSONTextMode.Indent) + aSB.AppendLine(); + + if (aMode == JSONTextMode.Indent) + aSB.Append(' ', aIndent + aIndentInc); + m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); + } + if (aMode == JSONTextMode.Indent) + aSB.AppendLine().Append(' ', aIndent); + aSB.Append(']'); + } + } + // End of JSONArray + + public partial class JSONObject : JSONNode + { + private Dictionary m_Dict = new Dictionary(); + + private bool inline = false; + public override bool Inline + { + get { return inline; } + set { inline = value; } + } + + public override JSONNodeType Tag { get { return JSONNodeType.Object; } } + public override bool IsObject { get { return true; } } + + public override Enumerator GetEnumerator() { return new Enumerator(m_Dict.GetEnumerator()); } + + + public override JSONNode this[string aKey] + { + get + { + if (m_Dict.ContainsKey(aKey)) + return m_Dict[aKey]; + else + return new JSONLazyCreator(this, aKey); + } + set + { + if (value == null) + value = JSONNull.CreateOrGet(); + if (m_Dict.ContainsKey(aKey)) + m_Dict[aKey] = value; + else + m_Dict.Add(aKey, value); + } + } + + public override JSONNode this[int aIndex] + { + get + { + if (aIndex < 0 || aIndex >= m_Dict.Count) + return null; + return m_Dict.ElementAt(aIndex).Value; + } + set + { + if (value == null) + value = JSONNull.CreateOrGet(); + if (aIndex < 0 || aIndex >= m_Dict.Count) + return; + string key = m_Dict.ElementAt(aIndex).Key; + m_Dict[key] = value; + } + } + + public override int Count + { + get { return m_Dict.Count; } + } + + public override void Add(string aKey, JSONNode aItem) + { + if (aItem == null) + aItem = JSONNull.CreateOrGet(); + + if (aKey != null) + { + if (m_Dict.ContainsKey(aKey)) + m_Dict[aKey] = aItem; + else + m_Dict.Add(aKey, aItem); + } + else + m_Dict.Add(Guid.NewGuid().ToString(), aItem); + } + + public override JSONNode Remove(string aKey) + { + if (!m_Dict.ContainsKey(aKey)) + return null; + JSONNode tmp = m_Dict[aKey]; + m_Dict.Remove(aKey); + return tmp; + } + + public override JSONNode Remove(int aIndex) + { + if (aIndex < 0 || aIndex >= m_Dict.Count) + return null; + var item = m_Dict.ElementAt(aIndex); + m_Dict.Remove(item.Key); + return item.Value; + } + + public override JSONNode Remove(JSONNode aNode) + { + try + { + var item = m_Dict.Where(k => k.Value == aNode).First(); + m_Dict.Remove(item.Key); + return aNode; + } + catch + { + return null; + } + } + + public override void Clear() + { + m_Dict.Clear(); + } + + public override JSONNode Clone() + { + var node = new JSONObject(); + foreach (var n in m_Dict) + { + node.Add(n.Key, n.Value.Clone()); + } + return node; + } + + public override bool HasKey(string aKey) + { + return m_Dict.ContainsKey(aKey); + } + + public override JSONNode GetValueOrDefault(string aKey, JSONNode aDefault) + { + JSONNode res; + if (m_Dict.TryGetValue(aKey, out res)) + return res; + return aDefault; + } + + public override IEnumerable Children + { + get + { + foreach (KeyValuePair N in m_Dict) + yield return N.Value; + } + } + + internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) + { + aSB.Append('{'); + bool first = true; + if (inline) + aMode = JSONTextMode.Compact; + foreach (var k in m_Dict) + { + if (!first) + aSB.Append(','); + first = false; + if (aMode == JSONTextMode.Indent) + aSB.AppendLine(); + if (aMode == JSONTextMode.Indent) + aSB.Append(' ', aIndent + aIndentInc); + aSB.Append('\"').Append(Escape(k.Key)).Append('\"'); + if (aMode == JSONTextMode.Compact) + aSB.Append(':'); + else + aSB.Append(" : "); + k.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); + } + if (aMode == JSONTextMode.Indent) + aSB.AppendLine().Append(' ', aIndent); + aSB.Append('}'); + } + + } + // End of JSONObject + + public partial class JSONString : JSONNode + { + private string m_Data; + + public override JSONNodeType Tag { get { return JSONNodeType.String; } } + public override bool IsString { get { return true; } } + + public override Enumerator GetEnumerator() { return new Enumerator(); } + + + public override string Value + { + get { return m_Data; } + set + { + m_Data = value; + } + } + + public JSONString(string aData) + { + m_Data = aData; + } + public override JSONNode Clone() + { + return new JSONString(m_Data); + } + + internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) + { + aSB.Append('\"').Append(Escape(m_Data)).Append('\"'); + } + public override bool Equals(object obj) + { + if (base.Equals(obj)) + return true; + string s = obj as string; + if (s != null) + return m_Data == s; + JSONString s2 = obj as JSONString; + if (s2 != null) + return m_Data == s2.m_Data; + return false; + } + public override int GetHashCode() + { + return m_Data.GetHashCode(); + } + public override void Clear() + { + m_Data = ""; + } + } + // End of JSONString + + public partial class JSONNumber : JSONNode + { + private double m_Data; + + public override JSONNodeType Tag { get { return JSONNodeType.Number; } } + public override bool IsNumber { get { return true; } } + public override Enumerator GetEnumerator() { return new Enumerator(); } + + public override string Value + { + get { return m_Data.ToString(CultureInfo.InvariantCulture); } + set + { + double v; + if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out v)) + m_Data = v; + } + } + + public override double AsDouble + { + get { return m_Data; } + set { m_Data = value; } + } + public override long AsLong + { + get { return (long)m_Data; } + set { m_Data = value; } + } + public override ulong AsULong + { + get { return (ulong)m_Data; } + set { m_Data = value; } + } + + public JSONNumber(double aData) + { + m_Data = aData; + } + + public JSONNumber(string aData) + { + Value = aData; + } + + public override JSONNode Clone() + { + return new JSONNumber(m_Data); + } + + internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) + { + aSB.Append(Value); + } + private static bool IsNumeric(object value) + { + return value is int || value is uint + || value is float || value is double + || value is decimal + || value is long || value is ulong + || value is short || value is ushort + || value is sbyte || value is byte; + } + public override bool Equals(object obj) + { + if (obj == null) + return false; + if (base.Equals(obj)) + return true; + JSONNumber s2 = obj as JSONNumber; + if (s2 != null) + return m_Data == s2.m_Data; + if (IsNumeric(obj)) + return Convert.ToDouble(obj) == m_Data; + return false; + } + public override int GetHashCode() + { + return m_Data.GetHashCode(); + } + public override void Clear() + { + m_Data = 0; + } + } + // End of JSONNumber + + public partial class JSONBool : JSONNode + { + private bool m_Data; + + public override JSONNodeType Tag { get { return JSONNodeType.Boolean; } } + public override bool IsBoolean { get { return true; } } + public override Enumerator GetEnumerator() { return new Enumerator(); } + + public override string Value + { + get { return m_Data.ToString(); } + set + { + bool v; + if (bool.TryParse(value, out v)) + m_Data = v; + } + } + public override bool AsBool + { + get { return m_Data; } + set { m_Data = value; } + } + + public JSONBool(bool aData) + { + m_Data = aData; + } + + public JSONBool(string aData) + { + Value = aData; + } + + public override JSONNode Clone() + { + return new JSONBool(m_Data); + } + + internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) + { + aSB.Append((m_Data) ? "true" : "false"); + } + public override bool Equals(object obj) + { + if (obj == null) + return false; + if (obj is bool) + return m_Data == (bool)obj; + return false; + } + public override int GetHashCode() + { + return m_Data.GetHashCode(); + } + public override void Clear() + { + m_Data = false; + } + } + // End of JSONBool + + public partial class JSONNull : JSONNode + { + static JSONNull m_StaticInstance = new JSONNull(); + public static bool reuseSameInstance = true; + public static JSONNull CreateOrGet() + { + if (reuseSameInstance) + return m_StaticInstance; + return new JSONNull(); + } + private JSONNull() { } + + public override JSONNodeType Tag { get { return JSONNodeType.NullValue; } } + public override bool IsNull { get { return true; } } + public override Enumerator GetEnumerator() { return new Enumerator(); } + + public override string Value + { + get { return "null"; } + set { } + } + public override bool AsBool + { + get { return false; } + set { } + } + + public override JSONNode Clone() + { + return CreateOrGet(); + } + + public override bool Equals(object obj) + { + if (object.ReferenceEquals(this, obj)) + return true; + return (obj is JSONNull); + } + public override int GetHashCode() + { + return 0; + } + + internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) + { + aSB.Append("null"); + } + } + // End of JSONNull + + internal partial class JSONLazyCreator : JSONNode + { + private JSONNode m_Node = null; + private string m_Key = null; + public override JSONNodeType Tag { get { return JSONNodeType.None; } } + public override Enumerator GetEnumerator() { return new Enumerator(); } + + public JSONLazyCreator(JSONNode aNode) + { + m_Node = aNode; + m_Key = null; + } + + public JSONLazyCreator(JSONNode aNode, string aKey) + { + m_Node = aNode; + m_Key = aKey; + } + + private T Set(T aVal) where T : JSONNode + { + if (m_Key == null) + m_Node.Add(aVal); + else + m_Node.Add(m_Key, aVal); + m_Node = null; // Be GC friendly. + return aVal; + } + + public override JSONNode this[int aIndex] + { + get { return new JSONLazyCreator(this); } + set { Set(new JSONArray()).Add(value); } + } + + public override JSONNode this[string aKey] + { + get { return new JSONLazyCreator(this, aKey); } + set { Set(new JSONObject()).Add(aKey, value); } + } + + public override void Add(JSONNode aItem) + { + Set(new JSONArray()).Add(aItem); + } + + public override void Add(string aKey, JSONNode aItem) + { + Set(new JSONObject()).Add(aKey, aItem); + } + + public static bool operator ==(JSONLazyCreator a, object b) + { + if (b == null) + return true; + return System.Object.ReferenceEquals(a, b); + } + + public static bool operator !=(JSONLazyCreator a, object b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + if (obj == null) + return true; + return System.Object.ReferenceEquals(this, obj); + } + + public override int GetHashCode() + { + return 0; + } + + public override int AsInt + { + get { Set(new JSONNumber(0)); return 0; } + set { Set(new JSONNumber(value)); } + } + + public override float AsFloat + { + get { Set(new JSONNumber(0.0f)); return 0.0f; } + set { Set(new JSONNumber(value)); } + } + + public override double AsDouble + { + get { Set(new JSONNumber(0.0)); return 0.0; } + set { Set(new JSONNumber(value)); } + } + + public override long AsLong + { + get + { + if (longAsString) + Set(new JSONString("0")); + else + Set(new JSONNumber(0.0)); + return 0L; + } + set + { + if (longAsString) + Set(new JSONString(value.ToString())); + else + Set(new JSONNumber(value)); + } + } + + public override ulong AsULong + { + get + { + if (longAsString) + Set(new JSONString("0")); + else + Set(new JSONNumber(0.0)); + return 0L; + } + set + { + if (longAsString) + Set(new JSONString(value.ToString())); + else + Set(new JSONNumber(value)); + } + } + + public override bool AsBool + { + get { Set(new JSONBool(false)); return false; } + set { Set(new JSONBool(value)); } + } + + public override JSONArray AsArray + { + get { return Set(new JSONArray()); } + } + + public override JSONObject AsObject + { + get { return Set(new JSONObject()); } + } + internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) + { + aSB.Append("null"); + } + } + // End of JSONLazyCreator + + public static class JSON + { + public static JSONNode Parse(string aJSON) + { + return JSONNode.Parse(aJSON); + } + } +} From 93cd984343752d905ff17f9a990b22001a1eea9c Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 16 Jun 2021 16:00:58 +0900 Subject: [PATCH 23/67] Refactor: Change methods & variables as static --- AsyncInput/AsyncInputManager.cs | 48 ++++++++++++------------ AsyncInput/HitIgnore/HitIgnoreManager.cs | 12 +++--- AsyncInput/HitIgnore/HitIgnorePatches.cs | 8 ++-- GarbageCollection/GCManager.cs | 12 +++--- GarbageCollection/GCPatches.cs | 25 ++++++------ HyperRabbit/HyperRabbitManager.cs | 14 +++---- NoStopMod.cs | 14 ++----- 7 files changed, 62 insertions(+), 71 deletions(-) diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 15ad0ba..7c826e9 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -1,4 +1,5 @@ -using NoStopMod.AsyncInput.HitIgnore; +using NoStopMod.Abstraction; +using NoStopMod.AsyncInput.HitIgnore; using System; using System.Collections.Generic; using System.Linq; @@ -10,26 +11,25 @@ namespace NoStopMod.AsyncInput { class AsyncInputManager { + //public static HitIgnoreManager hitIgnoreManager; - public HitIgnoreManager hitIgnoreManager; + private static Thread thread; + public static Queue>> keyQueue = new Queue>>(); - private Thread thread; - public Queue>> keyQueue = new Queue>>(); + public static long currTick; + public static long prevTick; - public long currTick; - public long prevTick; - - public long offsetTick; - public long currPressTick; + public static long offsetTick; + public static long currPressTick; - public bool jumpToOtherClass = false; + public static bool jumpToOtherClass = false; - private bool[] mask; + private static bool[] mask; //[DllImport("USER32.dll")] //static extern short GetKeyState(VirtualKeyStates nVirtKey); - public AsyncInputManager() + public static void Init() { NoStopMod.onToggleListeners.Add(OnToggle); @@ -38,10 +38,10 @@ public AsyncInputManager() mask = Enumerable.Repeat(false, 1024).ToArray(); - hitIgnoreManager = new HitIgnoreManager(); + HitIgnoreManager.Init(); } - private void OnToggle(bool enabled) + private static void OnToggle(bool enabled) { if (enabled) { @@ -53,14 +53,14 @@ private void OnToggle(bool enabled) } } - public void Start() + public static void Start() { Stop(); thread = new Thread(Run); thread.Start(); } - public void Stop() + public static void Stop() { if (thread != null) { @@ -69,7 +69,7 @@ public void Stop() } } - private bool GetKeyDown(int idx) + private static bool GetKeyDown(int idx) { if (mask[idx]) { @@ -89,7 +89,7 @@ private bool GetKeyDown(int idx) return false; } - private void Run() + private static void Run() { long prevTick = DateTime.Now.Ticks; while (true) @@ -125,13 +125,13 @@ private void Run() } } - public double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) + public static double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) { - return ___snappedLastAngle + (this.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet + return ___snappedLastAngle + (getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); } - public double getSongPosition(scrConductor __instance, long nowTick) + public static double getSongPosition(scrConductor __instance, long nowTick) { if (!GCS.d_oldConductor && !GCS.d_webglConductor) { @@ -143,10 +143,10 @@ public double getSongPosition(scrConductor __instance, long nowTick) } } - public void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) + public static void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) { - NoStopMod.asyncInputManager.offsetTick = NoStopMod.asyncInputManager.currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); + offsetTick = currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); } - + } } diff --git a/AsyncInput/HitIgnore/HitIgnoreManager.cs b/AsyncInput/HitIgnore/HitIgnoreManager.cs index a1cc258..e54e3e0 100644 --- a/AsyncInput/HitIgnore/HitIgnoreManager.cs +++ b/AsyncInput/HitIgnore/HitIgnoreManager.cs @@ -7,12 +7,12 @@ namespace NoStopMod.AsyncInput.HitIgnore { class HitIgnoreManager { - private Dictionary dictionary; + private static Dictionary dictionary; - public bool scnCLS_searchMode; - public scrController.States scrController_state; - - public HitIgnoreManager() + public static bool scnCLS_searchMode; + public static scrController.States scrController_state; + + public static void Init() { if (GCS.sceneToLoad == null) GCS.sceneToLoad = "scnNewIntro"; @@ -43,7 +43,7 @@ public HitIgnoreManager() scnCLS_searchMode = false; } - public bool shouldBeIgnored(KeyCode keyCode) + public static bool shouldBeIgnored(KeyCode keyCode) { if (keyCode == KeyCode.Escape) return true; if (scrController_state != scrController.States.PlayerControl) return true; diff --git a/AsyncInput/HitIgnore/HitIgnorePatches.cs b/AsyncInput/HitIgnore/HitIgnorePatches.cs index 49f6d42..adca4d1 100644 --- a/AsyncInput/HitIgnore/HitIgnorePatches.cs +++ b/AsyncInput/HitIgnore/HitIgnorePatches.cs @@ -13,7 +13,7 @@ private static class scnCLS_Refresh_Patch { public static void Postfix(scnCLS __instance, ref bool ___searchMode) { - NoStopMod.asyncInputManager.hitIgnoreManager.scnCLS_searchMode = ___searchMode; + HitIgnoreManager.scnCLS_searchMode = ___searchMode; } } @@ -22,7 +22,7 @@ private static class scnCLS_ToggleSearchMode_Patch { public static void Postfix(scnCLS __instance, ref bool ___searchMode) { - NoStopMod.asyncInputManager.hitIgnoreManager.scnCLS_searchMode = ___searchMode; + HitIgnoreManager.scnCLS_searchMode = ___searchMode; } } @@ -32,7 +32,7 @@ private static class StateEngine_ChangeState_Patch { public static void Postfix(StateEngine __instance, Enum newState, StateTransition transition) { - NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state = (scrController.States) newState; + HitIgnoreManager.scrController_state = (scrController.States) newState; } } @@ -41,7 +41,7 @@ private static class scrController_OnLandOnPortal_Patch { public static void Postfix(scrController __instance) { - NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state = scrController.States.Won; + HitIgnoreManager.scrController_state = scrController.States.Won; } } diff --git a/GarbageCollection/GCManager.cs b/GarbageCollection/GCManager.cs index 2826bdc..cb1407d 100644 --- a/GarbageCollection/GCManager.cs +++ b/GarbageCollection/GCManager.cs @@ -6,24 +6,24 @@ namespace NoStopMod.GarbageCollection public class GCManager { - private bool gcEnabled = true; + private static bool gcEnabled = true; - public GCManager() + public static void Init() { NoStopMod.onToggleListeners.Add(OnToggle); } - private void OnToggle(bool enabled) + private static void OnToggle(bool enabled) { EnableGC(); } - public bool GetDisableAutoSave() + public static bool GetDisableAutoSave() { return !gcEnabled; } - public void DisableGC() + public static void DisableGC() { try { @@ -39,7 +39,7 @@ public void DisableGC() } } - public void EnableGC() + public static void EnableGC() { try { diff --git a/GarbageCollection/GCPatches.cs b/GarbageCollection/GCPatches.cs index de70021..9b0d91e 100644 --- a/GarbageCollection/GCPatches.cs +++ b/GarbageCollection/GCPatches.cs @@ -1,6 +1,5 @@ -using System; -using HarmonyLib; -using UnityEngine; +using HarmonyLib; +using NoStopMod.GarbageCollection; namespace NoStopMod.Patches { @@ -12,7 +11,7 @@ private static class CustomLevel_Play_Patch private static void Prefix(CustomLevel __instance) { //NoStopMod.mod.Logger.Log("Play"); - NoStopMod.gcManager.DisableGC(); + GCManager.DisableGC(); } } @@ -22,7 +21,7 @@ private static class scnEditor_ResetScene_Patch private static void Postfix(scnEditor __instance) { //NoStopMod.mod.Logger.Log("ResetScene"); - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } @@ -32,7 +31,7 @@ private static class scnEditor_SaveBackup_Patch private static bool Prefix(scnEditor __instance) { //NoStopMod.mod.Logger.Log("SaveBackup"); - if (NoStopMod.gcManager.GetDisableAutoSave()) + if (GCManager.GetDisableAutoSave()) { //NoStopMod.mod.Logger.Log("Cancel AutoSave"); return false; @@ -48,7 +47,7 @@ private static class scrController_Awake_Patch public static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("Awake"); - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } @@ -57,7 +56,7 @@ private static class scrController_FailAction_Patch { private static void Prefix(scrController __instance) { - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } @@ -67,7 +66,7 @@ private static class scrController_QuitToMainMenu_Patch private static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("StartLoadingScene"); - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } @@ -77,7 +76,7 @@ private static class scrController_ResetCustomLevel_Patch private static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("ResetCustomLevel"); - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } @@ -87,7 +86,7 @@ private static class scrController_Restart_Patch private static void Prefix(scrController __instance) { //NoStopMod.mod.Logger.Log("Restart"); - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } @@ -97,7 +96,7 @@ private static class scrController_StartLoadingScene_Patch private static void Postfix(scrController __instance) { //NoStopMod.mod.Logger.Log("StartLoadingScene"); - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } @@ -108,7 +107,7 @@ private static class scrUIController_WipeToBlack_Patch private static void Postfix(scrUIController __instance) { //NoStopMod.mod.Logger.Log("WipeToBlack"); - NoStopMod.gcManager.EnableGC(); + GCManager.EnableGC(); } } diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitManager.cs index 3206b90..64ffcda 100644 --- a/HyperRabbit/HyperRabbitManager.cs +++ b/HyperRabbit/HyperRabbitManager.cs @@ -11,10 +11,8 @@ namespace NoStopMod.HyperRabbit class HyperRabbitManager { - - public bool isEnabled; - - + public static bool isEnabled; + enum Status { OFF, @@ -22,18 +20,18 @@ enum Status HYPER_RABBIT, } - public HyperRabbitManager() + public static void Init() { NoStopMod.onToggleListeners.Add(OnToggle); NoStopMod.onGUIListeners.Add(OnGUI); } - private void OnToggle(bool enabled) + private static void OnToggle(bool enabled) { - this.isEnabled = enabled; + isEnabled = enabled; } - private void OnGUI(UnityModManager.ModEntry modEntry) + private static void OnGUI(UnityModManager.ModEntry modEntry) { GUILayout.BeginHorizontal("HyperRabbit"); GUILayout.TextArea("HyperRabbit Status", 20); diff --git a/NoStopMod.cs b/NoStopMod.cs index f589d68..78fa428 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -19,11 +19,7 @@ class NoStopMod public static List> onToggleListeners; public static List> onGUIListeners; - - public static GCManager gcManager; - public static AsyncInputManager asyncInputManager; - public static HyperRabbitManager hyperRabbitManager; - + public static bool Load(UnityModManager.ModEntry modEntry) { modEntry.OnToggle = NoStopMod.OnToggle; @@ -33,11 +29,9 @@ public static bool Load(UnityModManager.ModEntry modEntry) NoStopMod.onToggleListeners = new List>(); NoStopMod.onGUIListeners = new List>(); - gcManager = new GCManager(); - asyncInputManager = new AsyncInputManager(); - hyperRabbitManager = new HyperRabbitManager(); - - + GCManager.Init(); + AsyncInputManager.Init(); + HyperRabbitManager.Init(); return true; } From 842834f32bc6ec007ac8d6f5e937215e50f82e7a Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 16 Jun 2021 16:45:47 +0900 Subject: [PATCH 24/67] Feat: Create AsyncInputSetting, OnApplicationQuitListener --- Abstraction/SettingsBase.cs | 4 +- AsyncInput/AsyncInputManager.cs | 12 ++-- AsyncInput/AsyncInputPatches.cs | 100 +++++++++++++++++------------- AsyncInput/AsyncInputSettings.cs | 27 ++++++++ HyperRabbit/HyperRabbitManager.cs | 2 +- NoStopMod.cs | 43 ++++++++----- NoStopMod.csproj | 4 ++ Settings.cs | 9 ++- 8 files changed, 133 insertions(+), 68 deletions(-) create mode 100644 AsyncInput/AsyncInputSettings.cs diff --git a/Abstraction/SettingsBase.cs b/Abstraction/SettingsBase.cs index 6c6e056..666039b 100644 --- a/Abstraction/SettingsBase.cs +++ b/Abstraction/SettingsBase.cs @@ -10,9 +10,9 @@ namespace NoStopMod.Abstraction interface SettingsBase { - void Load(JSONNode json); + void Load(ref JSONNode json); - void Save(JSONNode json); + void Save(ref JSONNode json); } } diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index 7c826e9..a9c4660 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -11,8 +11,8 @@ namespace NoStopMod.AsyncInput { class AsyncInputManager { - //public static HitIgnoreManager hitIgnoreManager; - + public static AsyncInputSettings settings; + private static Thread thread; public static Queue>> keyQueue = new Queue>>(); @@ -32,6 +32,7 @@ class AsyncInputManager public static void Init() { NoStopMod.onToggleListeners.Add(OnToggle); + settings = new AsyncInputSettings(); prevTick = DateTime.Now.Ticks; currTick = prevTick; @@ -56,8 +57,10 @@ private static void OnToggle(bool enabled) public static void Start() { Stop(); - thread = new Thread(Run); - thread.Start(); + if (settings.enableAsync) { + thread = new Thread(Run); + thread.Start(); + } } public static void Stop() @@ -67,6 +70,7 @@ public static void Stop() thread.Abort(); thread = null; } + keyQueue.Clear(); } private static bool GetKeyDown(int idx) diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index 6f68442..dde7411 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -28,9 +28,9 @@ private static class scrController_Awake_Patch { public static void Postfix(scrController __instance) { - NoStopMod.asyncInputManager.jumpToOtherClass = true; + AsyncInputManager.jumpToOtherClass = true; __instance.conductor.Start(); - NoStopMod.asyncInputManager.Start(); + AsyncInputManager.Start(); } } @@ -39,7 +39,7 @@ private static class scrController_OnApplicationQuit_Patch { public static void Prefix(scrController __instance) { - NoStopMod.asyncInputManager.Stop(); + AsyncInputManager.Stop(); } } @@ -48,46 +48,62 @@ private static class scrConductor_Update_Patch_Time { public static void Prefix(scrConductor __instance) { - NoStopMod.asyncInputManager.prevTick = NoStopMod.asyncInputManager.currTick; - NoStopMod.asyncInputManager.currTick = DateTime.Now.Ticks; + AsyncInputManager.prevTick = AsyncInputManager.currTick; + AsyncInputManager.currTick = DateTime.Now.Ticks; } public static void Postfix(scrConductor __instance, double ___dspTimeSong) { if (AudioListener.pause) { - NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); } - while (NoStopMod.asyncInputManager.keyQueue.Any()) + if (AsyncInputManager.settings.enableAsync) { - long tick; - List keyCodes; - NoStopMod.asyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); + while (AsyncInputManager.keyQueue.Any()) + { + long tick; + List keyCodes; + AsyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); - if (AudioListener.pause || RDC.auto) continue; + if (AudioListener.pause || RDC.auto) continue; - //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + "), " + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state + ", " + __instance.controller.GetState()); + //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + "), " + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state + ", " + __instance.controller.GetState()); - scrController controller = __instance.controller; - HitIgnoreManager hitDisableManager = NoStopMod.asyncInputManager.hitIgnoreManager; - int count = 0; - for (int i = 0; i < keyCodes.Count(); i++) - { - if (hitDisableManager.shouldBeIgnored(keyCodes[i])) continue; - if (++count > 4) break; - //NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", "); + scrController controller = __instance.controller; + int count = 0; + for (int i = 0; i < keyCodes.Count(); i++) + { + if (HitIgnoreManager.shouldBeIgnored(keyCodes[i])) continue; + if (++count > 4) break; + //NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", "); + } + AsyncInputManager.currPressTick = tick - AsyncInputManager.offsetTick; + controller.keyBufferCount += count; + while (controller.keyBufferCount > 0) + { + controller.keyBufferCount--; + AsyncInputManager.jumpToOtherClass = true; + controller.chosenplanet.Update_RefreshAngles(); + controller.Hit(); + } } - NoStopMod.asyncInputManager.currPressTick = tick - NoStopMod.asyncInputManager.offsetTick; - controller.keyBufferCount += count; - while (controller.keyBufferCount > 0) + } + else + { + if (__instance.controller.keyBufferCount > 0) { - controller.keyBufferCount--; - NoStopMod.asyncInputManager.jumpToOtherClass = true; - controller.chosenplanet.Update_RefreshAngles(); - controller.Hit(); + AsyncInputManager.currPressTick = AsyncInputManager.currTick - AsyncInputManager.offsetTick; + scrController controller = __instance.controller; + while (controller.keyBufferCount > 0) + { + controller.keyBufferCount--; + AsyncInputManager.jumpToOtherClass = true; + controller.chosenplanet.Update_RefreshAngles(); + controller.Hit(); + } } - } } @@ -98,7 +114,7 @@ private static class scrController_CountValidKeysPressed_Patch { public static void Postfix(scrController __instance, ref int __result) { - if (__result != 0) + if (AsyncInputManager.settings.enableAsync) { __result = 0; } @@ -111,10 +127,10 @@ private static class scrPlanet_Update_RefreshAngles_Patch public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) { - if (NoStopMod.asyncInputManager.jumpToOtherClass) + if (AsyncInputManager.jumpToOtherClass) { - NoStopMod.asyncInputManager.jumpToOtherClass = false; - __instance.angle = NoStopMod.asyncInputManager.getAngle(__instance, ___snappedLastAngle, NoStopMod.asyncInputManager.currPressTick); + AsyncInputManager.jumpToOtherClass = false; + __instance.angle = AsyncInputManager.getAngle(__instance, ___snappedLastAngle, AsyncInputManager.currPressTick); return false; } @@ -123,8 +139,8 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) if (!GCS.d_stationary) { - long nowTick = NoStopMod.asyncInputManager.currTick - NoStopMod.asyncInputManager.offsetTick; - __instance.angle = NoStopMod.asyncInputManager.getAngle(__instance, ___snappedLastAngle, nowTick); + long nowTick = AsyncInputManager.currTick - AsyncInputManager.offsetTick; + __instance.angle = AsyncInputManager.getAngle(__instance, ___snappedLastAngle, nowTick); if (__instance.shouldPrint) { @@ -174,7 +190,7 @@ private static class scrController_Rewind_Patch { public static void Postfix(scrController __instance) { - NoStopMod.asyncInputManager.jumpToOtherClass = true; + AsyncInputManager.jumpToOtherClass = true; __instance.conductor.Start(); } } @@ -184,10 +200,10 @@ private static class scrConductor_Start_Patch { public static bool Prefix(scrConductor __instance, double ___dspTimeSong) { - if (NoStopMod.asyncInputManager.jumpToOtherClass) + if (AsyncInputManager.jumpToOtherClass) { - NoStopMod.asyncInputManager.jumpToOtherClass = false; - NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + AsyncInputManager.jumpToOtherClass = false; + AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); return false; } return true; @@ -199,7 +215,7 @@ private static class scrConductor_Rewind_Patch { public static void Postfix(scrConductor __instance, double ___dspTimeSong) { - NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("Rewind"); } } @@ -209,7 +225,7 @@ private static class scrConductor_StartMusicCo_Patch { public static void Prefix(scrConductor __instance, double ___dspTimeSong) { - NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("StartMusicCo"); } } @@ -219,7 +235,7 @@ private static class scrConductor_ScrubMusicToTile_Patch { public static void Postfix(scrConductor __instance, double ___dspTimeSong) { - NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); } } @@ -229,7 +245,7 @@ private static class scrConductor_DesyncFix_Patch { public static void Postfix(scrConductor __instance, double ___dspTimeSong) { - NoStopMod.asyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("DesyncFix"); } } diff --git a/AsyncInput/AsyncInputSettings.cs b/AsyncInput/AsyncInputSettings.cs new file mode 100644 index 0000000..cae04ab --- /dev/null +++ b/AsyncInput/AsyncInputSettings.cs @@ -0,0 +1,27 @@ +using NoStopMod.Abstraction; +using SimpleJSON; +using System; + +namespace NoStopMod.AsyncInput +{ + class AsyncInputSettings : SettingsBase + { + public bool enableAsync; + + public void Load(ref JSONNode json) + { + JSONNode node = json["AsyncInput"]; + + enableAsync = node["enableAsync"]; + throw new NotImplementedException(); + } + + public void Save(ref JSONNode json) + { + JSONNode node = JSON.Parse("{}"); + node["enableAsync"].AsBool = enableAsync; + + json["AsyncInput"] = node; + } + } +} diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitManager.cs index 64ffcda..5d200bb 100644 --- a/HyperRabbit/HyperRabbitManager.cs +++ b/HyperRabbit/HyperRabbitManager.cs @@ -23,7 +23,7 @@ enum Status public static void Init() { NoStopMod.onToggleListeners.Add(OnToggle); - NoStopMod.onGUIListeners.Add(OnGUI); + //NoStopMod.onGUIListeners.Add(OnGUI); } private static void OnToggle(bool enabled) diff --git a/NoStopMod.cs b/NoStopMod.cs index 78fa428..db5b34a 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -19,15 +19,18 @@ class NoStopMod public static List> onToggleListeners; public static List> onGUIListeners; - + public static List> onApplicationQuitListeners; + public static bool Load(UnityModManager.ModEntry modEntry) { modEntry.OnToggle = NoStopMod.OnToggle; - //modEntry.OnGUI = NoStopMod.OnGUI; + modEntry.OnGUI = NoStopMod.OnGUI; NoStopMod.harmony = new Harmony(modEntry.Info.Id); NoStopMod.mod = modEntry; + NoStopMod.onToggleListeners = new List>(); NoStopMod.onGUIListeners = new List>(); + NoStopMod.onApplicationQuitListeners = new List>(); GCManager.Init(); AsyncInputManager.Init(); @@ -50,17 +53,7 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) } isEnabled = enabled; - foreach (Action listener in onToggleListeners) - { - try - { - listener.Invoke(enabled); - } - catch (Exception e) - { - mod.Logger.Error("Error on OnToggle : " + e.Message); - } - } + executeListeners(onToggleListeners, enabled, "OnToggle"); return true; } @@ -68,18 +61,34 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) public static void OnGUI(UnityModManager.ModEntry modEntry) { NoStopMod.mod = modEntry; - foreach (Action listener in onGUIListeners) + executeListeners(onGUIListeners, modEntry, "OnGUI"); + } + + + [HarmonyPatch(typeof(scrController), "OnApplicationQuit")] + private static class scrController_OnApplicationQuit_Patch + { + public static void Prefix(scrController __instance) + { + executeListeners(onApplicationQuitListeners, __instance, "OnApplicationQuit"); + } + } + + private static void executeListeners(List> listeners, T obj, String guiMessage) + { + for (int i=0;i< listeners.Count;i++) { try - { - listener.Invoke(modEntry); + { + listeners[i].Invoke(obj); } catch (Exception e) { - mod.Logger.Error("Error on ONGUI : " + e.Message); + mod.Logger.Error("Error on " + guiMessage + " : " + e.Message + ", " + e.StackTrace); } } } + } } diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 48c6ba2..c0c64eb 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -87,16 +87,20 @@ + + + + diff --git a/Settings.cs b/Settings.cs index 4f7872e..7b98113 100644 --- a/Settings.cs +++ b/Settings.cs @@ -17,6 +17,11 @@ class Settings public static List settings; + public static void Init() + { + + } + public static void Load() { TextAsset json = Resources.Load(Environment.CurrentDirectory + path); @@ -31,7 +36,7 @@ public static void Load() { try { - settings[i].Load(jsonNode); + settings[i].Load(ref jsonNode); } catch (Exception e) { @@ -47,7 +52,7 @@ public static void Save() { try { - settings[i].Save(node); + settings[i].Save(ref node); } catch (Exception e) { From b0a6e0e49a61c86cf4bff2096277de7c6fc6eb40 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 18 Jun 2021 23:59:02 +0900 Subject: [PATCH 25/67] Feat: Create SimpleGUI, Stabilize setting save logic --- AsyncInput/AsyncInputManager.cs | 44 ++++++++++++++++++++++++++------ AsyncInput/AsyncInputPatches.cs | 9 ------- AsyncInput/AsyncInputSettings.cs | 5 ++-- CustomLayout/SimpleGUI.cs | 25 ++++++++++++++++++ NoStopMod.cs | 17 +++++------- NoStopMod.csproj | 1 + Settings.cs | 21 +++++++++++---- 7 files changed, 86 insertions(+), 36 deletions(-) create mode 100644 CustomLayout/SimpleGUI.cs diff --git a/AsyncInput/AsyncInputManager.cs b/AsyncInput/AsyncInputManager.cs index a9c4660..3e1429f 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/AsyncInput/AsyncInputManager.cs @@ -1,11 +1,11 @@ -using NoStopMod.Abstraction; -using NoStopMod.AsyncInput.HitIgnore; +using NoStopMod.AsyncInput.HitIgnore; +using NoStopMod.CustomLayout; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using System.Threading; using UnityEngine; +using UnityModManagerNet; namespace NoStopMod.AsyncInput { @@ -25,14 +25,15 @@ class AsyncInputManager public static bool jumpToOtherClass = false; private static bool[] mask; - - //[DllImport("USER32.dll")] - //static extern short GetKeyState(VirtualKeyStates nVirtKey); - + public static void Init() { NoStopMod.onToggleListeners.Add(OnToggle); + NoStopMod.onGUIListeners.Add(OnGUI); + NoStopMod.onApplicationQuitListeners.Add(OnApplicationQuit); + settings = new AsyncInputSettings(); + Settings.settings.Add(settings); prevTick = DateTime.Now.Ticks; currTick = prevTick; @@ -44,7 +45,19 @@ public static void Init() private static void OnToggle(bool enabled) { - if (enabled) + UpdateEnableAsync(enabled); + } + + private static void OnGUI(UnityModManager.ModEntry modEntry) + { + GUILayout.BeginVertical("Input"); + SimpleGUI.Toggle(ref settings.enableAsync, "Toggle Input Asynchronously", UpdateEnableAsync); + GUILayout.EndVertical(); + } + + private static void UpdateEnableAsync(bool value) + { + if (value) { Start(); } @@ -54,9 +67,15 @@ private static void OnToggle(bool enabled) } } + private static void OnApplicationQuit(scrController __instance) + { + Stop(); + } + public static void Start() { Stop(); + adjustOffsetTick(); if (settings.enableAsync) { thread = new Thread(Run); thread.Start(); @@ -147,6 +166,15 @@ public static double getSongPosition(scrConductor __instance, long nowTick) } } + public static void adjustOffsetTick() + { + if (scrConductor.instance != null) + { + AsyncInputManager.jumpToOtherClass = true; + scrConductor.instance.Start(); + } + } + public static void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) { offsetTick = currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); diff --git a/AsyncInput/AsyncInputPatches.cs b/AsyncInput/AsyncInputPatches.cs index dde7411..5b3b761 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/AsyncInput/AsyncInputPatches.cs @@ -33,15 +33,6 @@ public static void Postfix(scrController __instance) AsyncInputManager.Start(); } } - - [HarmonyPatch(typeof(scrController), "OnApplicationQuit")] - private static class scrController_OnApplicationQuit_Patch - { - public static void Prefix(scrController __instance) - { - AsyncInputManager.Stop(); - } - } [HarmonyPatch(typeof(scrConductor), "Update")] private static class scrConductor_Update_Patch_Time diff --git a/AsyncInput/AsyncInputSettings.cs b/AsyncInput/AsyncInputSettings.cs index cae04ab..bea63fe 100644 --- a/AsyncInput/AsyncInputSettings.cs +++ b/AsyncInput/AsyncInputSettings.cs @@ -6,14 +6,13 @@ namespace NoStopMod.AsyncInput { class AsyncInputSettings : SettingsBase { - public bool enableAsync; + public bool enableAsync = false; public void Load(ref JSONNode json) { JSONNode node = json["AsyncInput"]; - enableAsync = node["enableAsync"]; - throw new NotImplementedException(); + enableAsync = node["enableAsync"].AsBool; } public void Save(ref JSONNode json) diff --git a/CustomLayout/SimpleGUI.cs b/CustomLayout/SimpleGUI.cs new file mode 100644 index 0000000..04b3bcf --- /dev/null +++ b/CustomLayout/SimpleGUI.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NoStopMod.CustomLayout +{ + class SimpleGUI + { + + public static void Toggle(ref bool previous, string message, Action callback) + { + bool current = GUILayout.Toggle(previous, message); + if (current != previous) + { + previous = current; + callback.Invoke(current); + } + } + + + } +} diff --git a/NoStopMod.cs b/NoStopMod.cs index db5b34a..0170ce5 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -17,9 +17,9 @@ class NoStopMod public static Harmony harmony; public static bool isEnabled = false; - public static List> onToggleListeners; - public static List> onGUIListeners; - public static List> onApplicationQuitListeners; + public static List> onToggleListeners = new List>(); + public static List> onGUIListeners = new List>(); + public static List> onApplicationQuitListeners = new List>(); public static bool Load(UnityModManager.ModEntry modEntry) { @@ -27,15 +27,12 @@ public static bool Load(UnityModManager.ModEntry modEntry) modEntry.OnGUI = NoStopMod.OnGUI; NoStopMod.harmony = new Harmony(modEntry.Info.Id); NoStopMod.mod = modEntry; - - NoStopMod.onToggleListeners = new List>(); - NoStopMod.onGUIListeners = new List>(); - NoStopMod.onApplicationQuitListeners = new List>(); - + GCManager.Init(); AsyncInputManager.Init(); HyperRabbitManager.Init(); + Settings.Init(); return true; } @@ -54,7 +51,6 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) isEnabled = enabled; executeListeners(onToggleListeners, enabled, "OnToggle"); - return true; } @@ -88,7 +84,6 @@ private static void executeListeners(List> listeners, T obj, String } } } - - + } } diff --git a/NoStopMod.csproj b/NoStopMod.csproj index c0c64eb..89587d2 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -93,6 +93,7 @@ + diff --git a/Settings.cs b/Settings.cs index 7b98113..258168d 100644 --- a/Settings.cs +++ b/Settings.cs @@ -15,23 +15,34 @@ class Settings public const String path = "\\Mods\\NoStopMod\\settings.json"; - public static List settings; + public static List settings = new List(); public static void Init() { + NoStopMod.onToggleListeners.Add(onToggle); + NoStopMod.onApplicationQuitListeners.Add(onApplicationQuit); + } + private static void onToggle(bool enabled) + { + Load(); + } + + private static void onApplicationQuit(scrController __instance) + { + Save(); } public static void Load() { - TextAsset json = Resources.Load(Environment.CurrentDirectory + path); - if (json == null) + string text = File.ReadAllText(Environment.CurrentDirectory + path); + if (text == null) { Save(); return; } - JSONNode jsonNode = JSON.Parse(json.text); + JSONNode jsonNode = JSON.Parse(text); for (int i = 0; i < settings.Count(); i++) { try @@ -48,7 +59,7 @@ public static void Load() public static void Save() { JSONNode node = JSON.Parse("{}"); - for (int i = 0;i < settings.Count();i++) + for (int i = 0; i < settings.Count();i++) { try { From 9d3c456d2f83e8b92db81a4bada7883897e2b3e4 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 14:56:04 +0900 Subject: [PATCH 26/67] Refactor: Change AsyncInput to InputFixer --- .../HitIgnore/HitIgnoreManager.cs | 2 +- .../HitIgnore/HitIgnorePatches.cs | 2 +- .../InputFixerManager.cs | 75 ++++++----- .../InputFixerPatches.cs | 121 ++++++++---------- .../InputFixerSettings.cs | 13 +- NoStopMod.cs | 4 +- 6 files changed, 112 insertions(+), 105 deletions(-) rename {AsyncInput => InputFixer}/HitIgnore/HitIgnoreManager.cs (98%) rename {AsyncInput => InputFixer}/HitIgnore/HitIgnorePatches.cs (97%) rename AsyncInput/AsyncInputManager.cs => InputFixer/InputFixerManager.cs (77%) rename AsyncInput/AsyncInputPatches.cs => InputFixer/InputFixerPatches.cs (62%) rename AsyncInput/AsyncInputSettings.cs => InputFixer/InputFixerSettings.cs (50%) diff --git a/AsyncInput/HitIgnore/HitIgnoreManager.cs b/InputFixer/HitIgnore/HitIgnoreManager.cs similarity index 98% rename from AsyncInput/HitIgnore/HitIgnoreManager.cs rename to InputFixer/HitIgnore/HitIgnoreManager.cs index e54e3e0..82bc22a 100644 --- a/AsyncInput/HitIgnore/HitIgnoreManager.cs +++ b/InputFixer/HitIgnore/HitIgnoreManager.cs @@ -3,7 +3,7 @@ using System.Linq; using UnityEngine; -namespace NoStopMod.AsyncInput.HitIgnore +namespace NoStopMod.InputFixer.HitIgnore { class HitIgnoreManager { diff --git a/AsyncInput/HitIgnore/HitIgnorePatches.cs b/InputFixer/HitIgnore/HitIgnorePatches.cs similarity index 97% rename from AsyncInput/HitIgnore/HitIgnorePatches.cs rename to InputFixer/HitIgnore/HitIgnorePatches.cs index adca4d1..41e553b 100644 --- a/AsyncInput/HitIgnore/HitIgnorePatches.cs +++ b/InputFixer/HitIgnore/HitIgnorePatches.cs @@ -2,7 +2,7 @@ using MonsterLove.StateMachine; using System; -namespace NoStopMod.AsyncInput.HitIgnore +namespace NoStopMod.InputFixer.HitIgnore { class HitIgnorePatches { diff --git a/AsyncInput/AsyncInputManager.cs b/InputFixer/InputFixerManager.cs similarity index 77% rename from AsyncInput/AsyncInputManager.cs rename to InputFixer/InputFixerManager.cs index 3e1429f..e188c3c 100644 --- a/AsyncInput/AsyncInputManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -1,4 +1,4 @@ -using NoStopMod.AsyncInput.HitIgnore; +using NoStopMod.InputFixer.HitIgnore; using NoStopMod.CustomLayout; using System; using System.Collections.Generic; @@ -7,11 +7,11 @@ using UnityEngine; using UnityModManagerNet; -namespace NoStopMod.AsyncInput +namespace NoStopMod.InputFixer { - class AsyncInputManager + class InputFixerManager { - public static AsyncInputSettings settings; + public static InputFixerSettings settings; private static Thread thread; public static Queue>> keyQueue = new Queue>>(); @@ -21,8 +21,9 @@ class AsyncInputManager public static long offsetTick; public static long currPressTick; - + public static bool jumpToOtherClass = false; + public static bool editInputLimit = false; private static bool[] mask; @@ -32,7 +33,7 @@ public static void Init() NoStopMod.onGUIListeners.Add(OnGUI); NoStopMod.onApplicationQuitListeners.Add(OnApplicationQuit); - settings = new AsyncInputSettings(); + settings = new InputFixerSettings(); Settings.settings.Add(settings); prevTick = DateTime.Now.Ticks; @@ -50,9 +51,9 @@ private static void OnToggle(bool enabled) private static void OnGUI(UnityModManager.ModEntry modEntry) { - GUILayout.BeginVertical("Input"); + //GUILayout.BeginVertical("Input"); SimpleGUI.Toggle(ref settings.enableAsync, "Toggle Input Asynchronously", UpdateEnableAsync); - GUILayout.EndVertical(); + //GUILayout.EndVertical(); } private static void UpdateEnableAsync(bool value) @@ -118,34 +119,44 @@ private static void Run() while (true) { long currTick = DateTime.Now.Ticks; - if (currTick > prevTick) { prevTick = currTick; - List keyCodes = new List(); - - for (int i = 0; i < 320; i++) - { - if (GetKeyDown(i)) - { - keyCodes.Add((KeyCode)i); - } - } - - for (int i = 323; i <= 329; i++) - { - if (GetKeyDown(i)) - { - keyCodes.Add((KeyCode)i); - } - } - - if (keyCodes.Any()) - { - keyQueue.Enqueue(new Tuple>(currTick, keyCodes)); - } + UpdateKeyQueue(currTick); + } + } + } + + public static void UpdateKeyQueue(long currTick) + { + List keyCodes = getPressedKeys(); + if (keyCodes.Any()) + { + keyQueue.Enqueue(new Tuple>(currTick, keyCodes)); + } + } + + private static List getPressedKeys() + { + List keyCodes = new List(); + + for (int i = 0; i < 320; i++) + { + if (GetKeyDown(i)) + { + keyCodes.Add((KeyCode)i); } } + + for (int i = 323; i <= 329; i++) + { + if (GetKeyDown(i)) + { + keyCodes.Add((KeyCode)i); + } + } + + return keyCodes; } public static double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) @@ -170,7 +181,7 @@ public static void adjustOffsetTick() { if (scrConductor.instance != null) { - AsyncInputManager.jumpToOtherClass = true; + InputFixerManager.jumpToOtherClass = true; scrConductor.instance.Start(); } } diff --git a/AsyncInput/AsyncInputPatches.cs b/InputFixer/InputFixerPatches.cs similarity index 62% rename from AsyncInput/AsyncInputPatches.cs rename to InputFixer/InputFixerPatches.cs index 5b3b761..eaf7f88 100644 --- a/AsyncInput/AsyncInputPatches.cs +++ b/InputFixer/InputFixerPatches.cs @@ -1,12 +1,12 @@ using DG.Tweening; using HarmonyLib; -using NoStopMod.AsyncInput.HitIgnore; +using NoStopMod.InputFixer.HitIgnore; using System; using System.Collections.Generic; using System.Linq; using UnityEngine; -namespace NoStopMod.AsyncInput +namespace NoStopMod.InputFixer { public static class AsyncInputPatches { @@ -28,9 +28,9 @@ private static class scrController_Awake_Patch { public static void Postfix(scrController __instance) { - AsyncInputManager.jumpToOtherClass = true; + InputFixerManager.jumpToOtherClass = true; __instance.conductor.Start(); - AsyncInputManager.Start(); + InputFixerManager.Start(); } } @@ -39,61 +39,46 @@ private static class scrConductor_Update_Patch_Time { public static void Prefix(scrConductor __instance) { - AsyncInputManager.prevTick = AsyncInputManager.currTick; - AsyncInputManager.currTick = DateTime.Now.Ticks; + InputFixerManager.prevTick = InputFixerManager.currTick; + InputFixerManager.currTick = DateTime.Now.Ticks; } public static void Postfix(scrConductor __instance, double ___dspTimeSong) { if (AudioListener.pause) { - AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); + } + + if (!InputFixerManager.settings.enableAsync) + { + InputFixerManager.UpdateKeyQueue(InputFixerManager.currTick); } - if (AsyncInputManager.settings.enableAsync) + while (InputFixerManager.keyQueue.Any()) { - while (AsyncInputManager.keyQueue.Any()) + long tick; + List keyCodes; + InputFixerManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); + + if (AudioListener.pause || RDC.auto) continue; + + scrController controller = __instance.controller; + int count = 0; + for (int i = 0; i < keyCodes.Count(); i++) { - long tick; - List keyCodes; - AsyncInputManager.keyQueue.Dequeue().Deconstruct(out tick, out keyCodes); - - if (AudioListener.pause || RDC.auto) continue; - - //NoStopMod.mod.Logger.Log("Hit:" + keyCodes.Count() + "(" + GCS.sceneToLoad + "), " + NoStopMod.asyncInputManager.hitIgnoreManager.scrController_state + ", " + __instance.controller.GetState()); - - scrController controller = __instance.controller; - int count = 0; - for (int i = 0; i < keyCodes.Count(); i++) - { - if (HitIgnoreManager.shouldBeIgnored(keyCodes[i])) continue; - if (++count > 4) break; - //NoStopMod.mod.Logger.Log("Hit " + keyCodes[i] + ", " + GCS.sceneToLoad + ", "); - } - AsyncInputManager.currPressTick = tick - AsyncInputManager.offsetTick; - controller.keyBufferCount += count; - while (controller.keyBufferCount > 0) - { - controller.keyBufferCount--; - AsyncInputManager.jumpToOtherClass = true; - controller.chosenplanet.Update_RefreshAngles(); - controller.Hit(); - } + if (HitIgnoreManager.shouldBeIgnored(keyCodes[i])) continue; + if (++count > 4) break; } - } - else - { - if (__instance.controller.keyBufferCount > 0) + + InputFixerManager.currPressTick = tick - InputFixerManager.offsetTick; + controller.keyBufferCount += count; + while (controller.keyBufferCount > 0) { - AsyncInputManager.currPressTick = AsyncInputManager.currTick - AsyncInputManager.offsetTick; - scrController controller = __instance.controller; - while (controller.keyBufferCount > 0) - { - controller.keyBufferCount--; - AsyncInputManager.jumpToOtherClass = true; - controller.chosenplanet.Update_RefreshAngles(); - controller.Hit(); - } + controller.keyBufferCount--; + InputFixerManager.jumpToOtherClass = true; + controller.chosenplanet.Update_RefreshAngles(); + controller.Hit(); } } @@ -103,13 +88,19 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) [HarmonyPatch(typeof(scrController), "CountValidKeysPressed")] private static class scrController_CountValidKeysPressed_Patch { - public static void Postfix(scrController __instance, ref int __result) + public static bool Prefix(scrController __instance, ref int __result) { - if (AsyncInputManager.settings.enableAsync) - { - __result = 0; - } + __result = 0; + return false; } + + //public static void Postfix(scrController __instance, ref int __result) + //{ + // if (InputFixerManager.settings.enableAsync) + // { + // __result = 0; + // } + //} } [HarmonyPatch(typeof(scrPlanet), "Update_RefreshAngles")] @@ -118,10 +109,10 @@ private static class scrPlanet_Update_RefreshAngles_Patch public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) { - if (AsyncInputManager.jumpToOtherClass) + if (InputFixerManager.jumpToOtherClass) { - AsyncInputManager.jumpToOtherClass = false; - __instance.angle = AsyncInputManager.getAngle(__instance, ___snappedLastAngle, AsyncInputManager.currPressTick); + InputFixerManager.jumpToOtherClass = false; + __instance.angle = InputFixerManager.getAngle(__instance, ___snappedLastAngle, InputFixerManager.currPressTick); return false; } @@ -130,8 +121,8 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) if (!GCS.d_stationary) { - long nowTick = AsyncInputManager.currTick - AsyncInputManager.offsetTick; - __instance.angle = AsyncInputManager.getAngle(__instance, ___snappedLastAngle, nowTick); + long nowTick = InputFixerManager.currTick - InputFixerManager.offsetTick; + __instance.angle = InputFixerManager.getAngle(__instance, ___snappedLastAngle, nowTick); if (__instance.shouldPrint) { @@ -181,7 +172,7 @@ private static class scrController_Rewind_Patch { public static void Postfix(scrController __instance) { - AsyncInputManager.jumpToOtherClass = true; + InputFixerManager.jumpToOtherClass = true; __instance.conductor.Start(); } } @@ -191,10 +182,10 @@ private static class scrConductor_Start_Patch { public static bool Prefix(scrConductor __instance, double ___dspTimeSong) { - if (AsyncInputManager.jumpToOtherClass) + if (InputFixerManager.jumpToOtherClass) { - AsyncInputManager.jumpToOtherClass = false; - AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + InputFixerManager.jumpToOtherClass = false; + InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); return false; } return true; @@ -206,7 +197,7 @@ private static class scrConductor_Rewind_Patch { public static void Postfix(scrConductor __instance, double ___dspTimeSong) { - AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("Rewind"); } } @@ -216,7 +207,7 @@ private static class scrConductor_StartMusicCo_Patch { public static void Prefix(scrConductor __instance, double ___dspTimeSong) { - AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("StartMusicCo"); } } @@ -226,7 +217,7 @@ private static class scrConductor_ScrubMusicToTile_Patch { public static void Postfix(scrConductor __instance, double ___dspTimeSong) { - AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); } } @@ -236,7 +227,7 @@ private static class scrConductor_DesyncFix_Patch { public static void Postfix(scrConductor __instance, double ___dspTimeSong) { - AsyncInputManager.adjustOffsetTick(__instance, ___dspTimeSong); + InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); //NoStopMod.mod.Logger.Log("DesyncFix"); } } diff --git a/AsyncInput/AsyncInputSettings.cs b/InputFixer/InputFixerSettings.cs similarity index 50% rename from AsyncInput/AsyncInputSettings.cs rename to InputFixer/InputFixerSettings.cs index bea63fe..ae7eecd 100644 --- a/AsyncInput/AsyncInputSettings.cs +++ b/InputFixer/InputFixerSettings.cs @@ -2,25 +2,30 @@ using SimpleJSON; using System; -namespace NoStopMod.AsyncInput +namespace NoStopMod.InputFixer { - class AsyncInputSettings : SettingsBase + class InputFixerSettings : SettingsBase { public bool enableAsync = false; + public bool enableKeyLimit = false; public void Load(ref JSONNode json) { - JSONNode node = json["AsyncInput"]; + JSONNode node = json["InputFixer"]; enableAsync = node["enableAsync"].AsBool; + enableKeyLimit = node["enableKeyLimit"].AsBool; + JSONArray array = node["LimitKeys"].AsArray; + } public void Save(ref JSONNode json) { JSONNode node = JSON.Parse("{}"); node["enableAsync"].AsBool = enableAsync; + node["enableKeyLimit"].AsBool = enableKeyLimit; - json["AsyncInput"] = node; + json["InputFixer"] = node; } } } diff --git a/NoStopMod.cs b/NoStopMod.cs index 0170ce5..739633a 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -4,7 +4,7 @@ using UnityModManagerNet; using NoStopMod.GarbageCollection; using System.Collections.Generic; -using NoStopMod.AsyncInput; +using NoStopMod.InputFixer; using NoStopMod.HyperRabbit; using SimpleJSON; @@ -29,7 +29,7 @@ public static bool Load(UnityModManager.ModEntry modEntry) NoStopMod.mod = modEntry; GCManager.Init(); - AsyncInputManager.Init(); + InputFixerManager.Init(); HyperRabbitManager.Init(); Settings.Init(); From 9cbc7541fd20d56714be5c21398eab45a00df2ef Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 15:41:17 +0900 Subject: [PATCH 27/67] Feat: Create JSONHelper, KeyLimiter --- Helper/JSONHelper.cs | 48 +++++++++++++++++++ .../HitIgnore/KeyLimiter/KeyLimiterManager.cs | 30 ++++++++++++ .../KeyLimiter/KeyLimiterSettings.cs | 38 +++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 Helper/JSONHelper.cs create mode 100644 InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs create mode 100644 InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs diff --git a/Helper/JSONHelper.cs b/Helper/JSONHelper.cs new file mode 100644 index 0000000..592a0be --- /dev/null +++ b/Helper/JSONHelper.cs @@ -0,0 +1,48 @@ +using SimpleJSON; +using System; +using System.Collections.Generic; + +namespace NoStopMod.Helper +{ + class JSONHelper + { + + public static JSONNode CreateEmptyNode() + { + return JSON.Parse("{}"); + } + + public static long ConvertLong(JSONNode node) + { + return node.AsLong; + } + + public static int ConvertInt(JSONNode node) + { + return node.AsInt; + } + + public static List ReadArray(ref JSONNode node, string name, Func converter) + { + JSONArray array = node[name].AsArray; + + List results = new List(array.Count); + for (int i = 0; i < array.Count; i++) + { + results.Add(converter.Invoke(array[i])); + } + return results; + } + + public static JSONArray WriteArray(List list, Func converter) + { + JSONArray array = new JSONArray(); + for (int i = 0; i < list.Count; i++) + { + array.Add(converter.Invoke(list[i])); + } + return array; + } + + } +} diff --git a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs new file mode 100644 index 0000000..490a255 --- /dev/null +++ b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityModManagerNet; + +namespace NoStopMod.InputFixer.HitIgnore.KeyLimiter +{ + class KeyLimiterManager + { + + public static KeyLimiterSettings settings; + + public static void Init() + { + NoStopMod.onGUIListeners.Add(OnGUI); + + settings = new KeyLimiterSettings(); + Settings.settings.Add(settings); + + } + + private static void OnGUI(UnityModManager.ModEntry entry) + { + + } + + } +} diff --git a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs new file mode 100644 index 0000000..d2d55d7 --- /dev/null +++ b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs @@ -0,0 +1,38 @@ +using NoStopMod.Helper; +using NoStopMod.Helper.Abstraction; +using SimpleJSON; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NoStopMod.InputFixer.HitIgnore.KeyLimiter +{ + class KeyLimiterSettings : SettingsBase + { + + public bool enable; + public List limitKeys; + + public void Load(ref JSONNode json) + { + JSONNode node = json["KeyLimiter"]; + + enable = node["enable"].AsBool; + limitKeys = JSONHelper.ReadArray(ref node, "limitKeys", (arrayNode) => { return (KeyCode) arrayNode.AsInt; }); + + throw new NotImplementedException(); + } + + public void Save(ref JSONNode json) + { + JSONNode node = JSONHelper.CreateEmptyNode(); + node["enable"].AsBool = enable; + node["limitKeys"] = JSONHelper.WriteArray(limitKeys, (element) => { return (int) element; }); + + json["KeyLimiter"] = node; + } + } +} From 093ae723334338e3745c0cd08e0f1790b1c8dbd6 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 15:41:39 +0900 Subject: [PATCH 28/67] Feat: Move SimpleGUI, SettingsBase to Helper --- {Abstraction => Helper/Abstraction}/SettingsBase.cs | 5 ++--- {CustomLayout => Helper}/SimpleGUI.cs | 2 +- InputFixer/HitIgnore/HitIgnoreManager.cs | 5 ++++- InputFixer/InputFixerManager.cs | 2 +- InputFixer/InputFixerPatches.cs | 2 +- InputFixer/InputFixerSettings.cs | 5 +++-- Settings.cs | 5 +++-- 7 files changed, 15 insertions(+), 11 deletions(-) rename {Abstraction => Helper/Abstraction}/SettingsBase.cs (86%) rename {CustomLayout => Helper}/SimpleGUI.cs (93%) diff --git a/Abstraction/SettingsBase.cs b/Helper/Abstraction/SettingsBase.cs similarity index 86% rename from Abstraction/SettingsBase.cs rename to Helper/Abstraction/SettingsBase.cs index 666039b..2d91598 100644 --- a/Abstraction/SettingsBase.cs +++ b/Helper/Abstraction/SettingsBase.cs @@ -5,14 +5,13 @@ using System.Threading.Tasks; using SimpleJSON; -namespace NoStopMod.Abstraction +namespace NoStopMod.Helper.Abstraction { interface SettingsBase { - void Load(ref JSONNode json); void Save(ref JSONNode json); - + } } diff --git a/CustomLayout/SimpleGUI.cs b/Helper/SimpleGUI.cs similarity index 93% rename from CustomLayout/SimpleGUI.cs rename to Helper/SimpleGUI.cs index 04b3bcf..cc831c6 100644 --- a/CustomLayout/SimpleGUI.cs +++ b/Helper/SimpleGUI.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using UnityEngine; -namespace NoStopMod.CustomLayout +namespace NoStopMod.Helper { class SimpleGUI { diff --git a/InputFixer/HitIgnore/HitIgnoreManager.cs b/InputFixer/HitIgnore/HitIgnoreManager.cs index 82bc22a..5543929 100644 --- a/InputFixer/HitIgnore/HitIgnoreManager.cs +++ b/InputFixer/HitIgnore/HitIgnoreManager.cs @@ -1,4 +1,5 @@ -using System; +using NoStopMod.InputFixer.HitIgnore.KeyLimiter; +using System; using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -41,6 +42,8 @@ public static void Init() ignoreScnCLS[(int)KeyCode.DownArrow] = true; scnCLS_searchMode = false; + + KeyLimiterManager.Init(); } public static bool shouldBeIgnored(KeyCode keyCode) diff --git a/InputFixer/InputFixerManager.cs b/InputFixer/InputFixerManager.cs index e188c3c..250015a 100644 --- a/InputFixer/InputFixerManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -1,5 +1,5 @@ using NoStopMod.InputFixer.HitIgnore; -using NoStopMod.CustomLayout; +using NoStopMod.Helper; using System; using System.Collections.Generic; using System.Linq; diff --git a/InputFixer/InputFixerPatches.cs b/InputFixer/InputFixerPatches.cs index eaf7f88..1eb9215 100644 --- a/InputFixer/InputFixerPatches.cs +++ b/InputFixer/InputFixerPatches.cs @@ -44,7 +44,7 @@ public static void Prefix(scrConductor __instance) } public static void Postfix(scrConductor __instance, double ___dspTimeSong) - { + { if (AudioListener.pause) { InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); diff --git a/InputFixer/InputFixerSettings.cs b/InputFixer/InputFixerSettings.cs index ae7eecd..6d1b1e3 100644 --- a/InputFixer/InputFixerSettings.cs +++ b/InputFixer/InputFixerSettings.cs @@ -1,4 +1,5 @@ -using NoStopMod.Abstraction; +using NoStopMod.Helper; +using NoStopMod.Helper.Abstraction; using SimpleJSON; using System; @@ -21,7 +22,7 @@ public void Load(ref JSONNode json) public void Save(ref JSONNode json) { - JSONNode node = JSON.Parse("{}"); + JSONNode node = JSONHelper.CreateEmptyNode(); node["enableAsync"].AsBool = enableAsync; node["enableKeyLimit"].AsBool = enableKeyLimit; diff --git a/Settings.cs b/Settings.cs index 258168d..2fb83e7 100644 --- a/Settings.cs +++ b/Settings.cs @@ -4,7 +4,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using NoStopMod.Abstraction; +using NoStopMod.Helper; +using NoStopMod.Helper.Abstraction; using SimpleJSON; using UnityEngine; @@ -58,7 +59,7 @@ public static void Load() public static void Save() { - JSONNode node = JSON.Parse("{}"); + JSONNode node = JSONHelper.CreateEmptyNode(); for (int i = 0; i < settings.Count();i++) { try From b81daa9015d5909a8ee494b2a50769631202a142 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 16:06:14 +0900 Subject: [PATCH 29/67] Feat: Create EventListener and generalize --- GarbageCollection/GCManager.cs | 2 +- Helper/EventListener.cs | 42 +++++++++++++++++++++++++++++++ HyperRabbit/HyperRabbitManager.cs | 2 +- InputFixer/InputFixerManager.cs | 6 ++--- NoStopMod.cs | 13 +++++----- NoStopMod.csproj | 18 +++++++------ Settings.cs | 4 +-- 7 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 Helper/EventListener.cs diff --git a/GarbageCollection/GCManager.cs b/GarbageCollection/GCManager.cs index cb1407d..697d0d3 100644 --- a/GarbageCollection/GCManager.cs +++ b/GarbageCollection/GCManager.cs @@ -10,7 +10,7 @@ public class GCManager public static void Init() { - NoStopMod.onToggleListeners.Add(OnToggle); + NoStopMod.onToggleListener.Add(OnToggle); } private static void OnToggle(bool enabled) diff --git a/Helper/EventListener.cs b/Helper/EventListener.cs new file mode 100644 index 0000000..d1c9d55 --- /dev/null +++ b/Helper/EventListener.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NoStopMod.Helper +{ + class EventListener + { + + public readonly List> listeners = new List>(); + + private readonly string errorMessage; + + public EventListener(string errorMessage) + { + this.errorMessage = errorMessage; + } + + public void Add(Action listener) + { + listeners.Add(listener); + } + + public void Invoke(T value) + { + for (int i = 0; i < listeners.Count; i++) + { + try + { + listeners[i].Invoke(value); + } + catch (Exception e) + { + NoStopMod.mod.Logger.Error("Error on " + errorMessage + " : " + e.Message + ", " + e.StackTrace); + } + } + } + + } +} diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitManager.cs index 5d200bb..fea34d5 100644 --- a/HyperRabbit/HyperRabbitManager.cs +++ b/HyperRabbit/HyperRabbitManager.cs @@ -22,7 +22,7 @@ enum Status public static void Init() { - NoStopMod.onToggleListeners.Add(OnToggle); + NoStopMod.onToggleListener.Add(OnToggle); //NoStopMod.onGUIListeners.Add(OnGUI); } diff --git a/InputFixer/InputFixerManager.cs b/InputFixer/InputFixerManager.cs index 250015a..4c6d2af 100644 --- a/InputFixer/InputFixerManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -29,9 +29,9 @@ class InputFixerManager public static void Init() { - NoStopMod.onToggleListeners.Add(OnToggle); - NoStopMod.onGUIListeners.Add(OnGUI); - NoStopMod.onApplicationQuitListeners.Add(OnApplicationQuit); + NoStopMod.onToggleListener.Add(OnToggle); + NoStopMod.onGUIListener.Add(OnGUI); + NoStopMod.onApplicationQuitListener.Add(OnApplicationQuit); settings = new InputFixerSettings(); Settings.settings.Add(settings); diff --git a/NoStopMod.cs b/NoStopMod.cs index 739633a..4edd747 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -7,6 +7,7 @@ using NoStopMod.InputFixer; using NoStopMod.HyperRabbit; using SimpleJSON; +using NoStopMod.Helper; namespace NoStopMod { @@ -17,9 +18,9 @@ class NoStopMod public static Harmony harmony; public static bool isEnabled = false; - public static List> onToggleListeners = new List>(); - public static List> onGUIListeners = new List>(); - public static List> onApplicationQuitListeners = new List>(); + public static EventListener onToggleListener = new EventListener("OnToggle"); + public static EventListener onGUIListener = new EventListener("OnGUI"); + public static EventListener onApplicationQuitListener = new EventListener("OnApplicationQuit"); public static bool Load(UnityModManager.ModEntry modEntry) { @@ -50,14 +51,14 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) } isEnabled = enabled; - executeListeners(onToggleListeners, enabled, "OnToggle"); + onToggleListener.Invoke(enabled); return true; } public static void OnGUI(UnityModManager.ModEntry modEntry) { NoStopMod.mod = modEntry; - executeListeners(onGUIListeners, modEntry, "OnGUI"); + onGUIListener.Invoke(modEntry); } @@ -66,7 +67,7 @@ private static class scrController_OnApplicationQuit_Patch { public static void Prefix(scrController __instance) { - executeListeners(onApplicationQuitListeners, __instance, "OnApplicationQuit"); + onApplicationQuitListener.Invoke(__instance); } } diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 89587d2..3aeba95 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -87,13 +87,17 @@ - - - - - - - + + + + + + + + + + + diff --git a/Settings.cs b/Settings.cs index 2fb83e7..1c819ce 100644 --- a/Settings.cs +++ b/Settings.cs @@ -20,8 +20,8 @@ class Settings public static void Init() { - NoStopMod.onToggleListeners.Add(onToggle); - NoStopMod.onApplicationQuitListeners.Add(onApplicationQuit); + NoStopMod.onToggleListener.Add(onToggle); + NoStopMod.onApplicationQuitListener.Add(onApplicationQuit); } private static void onToggle(bool enabled) From 83431b92953ccdec87adbd4dc0ca0e1a0a1d2044 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 16:29:29 +0900 Subject: [PATCH 30/67] Feat: Create KeyLimiter --- .../HitIgnore/KeyLimiter/KeyLimiterManager.cs | 47 +++++++++++++++++-- .../KeyLimiter/KeyLimiterSettings.cs | 7 ++- NoStopMod.cs | 29 ++---------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs index 490a255..2cc5bfc 100644 --- a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs +++ b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using UnityEngine; using UnityModManagerNet; namespace NoStopMod.InputFixer.HitIgnore.KeyLimiter @@ -12,9 +9,12 @@ class KeyLimiterManager public static KeyLimiterSettings settings; + public static bool isChangingLimitedKeys = false; + public static void Init() { - NoStopMod.onGUIListeners.Add(OnGUI); + NoStopMod.onGUIListener.Add(OnGUI); + NoStopMod.onHideGUIListener.Add(OnHideGUI); settings = new KeyLimiterSettings(); Settings.settings.Add(settings); @@ -23,7 +23,44 @@ public static void Init() private static void OnGUI(UnityModManager.ModEntry entry) { + settings.enable = GUILayout.Toggle(settings.enable, "Enable key limiter"); + if (settings.enable) + { + //GUILayout.Label("", Array.Empty()); + GUILayout.BeginHorizontal(Array.Empty()); + GUILayout.Space(20f); + + GUILayout.BeginVertical(Array.Empty()); + GUILayout.Space(8f); + GUILayout.EndVertical(); + + for (int i = 0; i < settings.limitKeys.Count; i++) + { + GUILayout.Label(settings.limitKeys[i].ToString(), Array.Empty()); + GUILayout.Space(8f); + } + + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(Array.Empty()); + if (GUILayout.Button(isChangingLimitedKeys ? "Complete" : "Change Limited Keys", Array.Empty())) + { + isChangingLimitedKeys = !isChangingLimitedKeys; + } + if (isChangingLimitedKeys) + { + GUILayout.Label("Press keys to add / remove limited key", Array.Empty()); + } + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + + } + } + + private static void OnHideGUI(UnityModManager.ModEntry entry) + { + isChangingLimitedKeys = false; } } diff --git a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs index d2d55d7..ac76522 100644 --- a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs +++ b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs @@ -13,8 +13,8 @@ namespace NoStopMod.InputFixer.HitIgnore.KeyLimiter class KeyLimiterSettings : SettingsBase { - public bool enable; - public List limitKeys; + public bool enable = false; + public List limitKeys = new List(); public void Load(ref JSONNode json) { @@ -22,8 +22,7 @@ public void Load(ref JSONNode json) enable = node["enable"].AsBool; limitKeys = JSONHelper.ReadArray(ref node, "limitKeys", (arrayNode) => { return (KeyCode) arrayNode.AsInt; }); - - throw new NotImplementedException(); + } public void Save(ref JSONNode json) diff --git a/NoStopMod.cs b/NoStopMod.cs index 4edd747..fb714a4 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -20,12 +20,15 @@ class NoStopMod public static EventListener onToggleListener = new EventListener("OnToggle"); public static EventListener onGUIListener = new EventListener("OnGUI"); + public static EventListener onHideGUIListener = new EventListener("OnHideGUI"); public static EventListener onApplicationQuitListener = new EventListener("OnApplicationQuit"); public static bool Load(UnityModManager.ModEntry modEntry) { modEntry.OnToggle = NoStopMod.OnToggle; - modEntry.OnGUI = NoStopMod.OnGUI; + modEntry.OnGUI = onGUIListener.Invoke; + modEntry.OnHideGUI = onHideGUIListener.Invoke; + NoStopMod.harmony = new Harmony(modEntry.Info.Id); NoStopMod.mod = modEntry; @@ -54,14 +57,7 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) onToggleListener.Invoke(enabled); return true; } - - public static void OnGUI(UnityModManager.ModEntry modEntry) - { - NoStopMod.mod = modEntry; - onGUIListener.Invoke(modEntry); - } - - + [HarmonyPatch(typeof(scrController), "OnApplicationQuit")] private static class scrController_OnApplicationQuit_Patch { @@ -70,21 +66,6 @@ public static void Prefix(scrController __instance) onApplicationQuitListener.Invoke(__instance); } } - - private static void executeListeners(List> listeners, T obj, String guiMessage) - { - for (int i=0;i< listeners.Count;i++) - { - try - { - listeners[i].Invoke(obj); - } - catch (Exception e) - { - mod.Logger.Error("Error on " + guiMessage + " : " + e.Message + ", " + e.StackTrace); - } - } - } } } From d353ce9acaf9f3261cb228c9c54204f6a3fbbea1 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 17:32:28 +0900 Subject: [PATCH 31/67] Feat: Complete KeyLimiter --- Helper/EventListener.cs | 3 -- InputFixer/HitIgnore/HitIgnoreManager.cs | 16 +++++++-- .../HitIgnore/KeyLimiter/KeyLimiterManager.cs | 35 ++++++++++++++++++- .../KeyLimiter/KeyLimiterSettings.cs | 4 --- NoStopMod.cs | 5 +-- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Helper/EventListener.cs b/Helper/EventListener.cs index d1c9d55..d71c311 100644 --- a/Helper/EventListener.cs +++ b/Helper/EventListener.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace NoStopMod.Helper { diff --git a/InputFixer/HitIgnore/HitIgnoreManager.cs b/InputFixer/HitIgnore/HitIgnoreManager.cs index 5543929..e508c2d 100644 --- a/InputFixer/HitIgnore/HitIgnoreManager.cs +++ b/InputFixer/HitIgnore/HitIgnoreManager.cs @@ -49,8 +49,14 @@ public static void Init() public static bool shouldBeIgnored(KeyCode keyCode) { if (keyCode == KeyCode.Escape) return true; + if (KeyLimiterManager.isChangingLimitedKeys) + { + KeyLimiterManager.UpdateKeyLimiter(keyCode); + return true; + } + if (scrController_state != scrController.States.PlayerControl) return true; - + bool[] ignoreScnCLS; if (dictionary.TryGetValue(GCS.sceneToLoad, out ignoreScnCLS)) { @@ -58,8 +64,14 @@ public static bool shouldBeIgnored(KeyCode keyCode) { return true; } - return ignoreScnCLS[(int) keyCode]; + if(ignoreScnCLS[(int) keyCode]) return true; } + + if(KeyLimiterManager.settings.enable) + { + return !KeyLimiterManager.IsKeyEnabled(keyCode); + } + return false; } diff --git a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs index 2cc5bfc..75bc237 100644 --- a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs +++ b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterManager.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using UnityEngine; using UnityModManagerNet; @@ -11,14 +12,25 @@ class KeyLimiterManager public static bool isChangingLimitedKeys = false; + private static bool[] enableKey = Enumerable.Repeat(false, 1024).ToArray(); + public static void Init() { NoStopMod.onGUIListener.Add(OnGUI); NoStopMod.onHideGUIListener.Add(OnHideGUI); + Settings.settingsLoadListener.Add(_ => InitEnableKey()); settings = new KeyLimiterSettings(); Settings.settings.Add(settings); - + } + + private static void InitEnableKey() + { + enableKey = Enumerable.Repeat(false, 1024).ToArray(); + for (int i = 0; i < settings.limitKeys.Count; i++) + { + enableKey[(int)settings.limitKeys[i]] = true; + } } private static void OnGUI(UnityModManager.ModEntry entry) @@ -63,5 +75,26 @@ private static void OnHideGUI(UnityModManager.ModEntry entry) isChangingLimitedKeys = false; } + public static bool IsKeyEnabled(KeyCode keyCode) + { + return enableKey[(int) keyCode]; + } + + public static void UpdateKeyLimiter(KeyCode keyCode) + { + int idx = settings.limitKeys.IndexOf(keyCode); + if (idx == -1) + { + settings.limitKeys.Add(keyCode); + enableKey[(int)keyCode] = true; + } + else + { + settings.limitKeys.RemoveAt(idx); + enableKey[(int)keyCode] = false; + } + + } + } } diff --git a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs index ac76522..e63ab50 100644 --- a/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs +++ b/InputFixer/HitIgnore/KeyLimiter/KeyLimiterSettings.cs @@ -1,11 +1,7 @@ using NoStopMod.Helper; using NoStopMod.Helper.Abstraction; using SimpleJSON; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; namespace NoStopMod.InputFixer.HitIgnore.KeyLimiter diff --git a/NoStopMod.cs b/NoStopMod.cs index fb714a4..699b47b 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -1,12 +1,9 @@ -using System; -using System.Reflection; +using System.Reflection; using HarmonyLib; using UnityModManagerNet; using NoStopMod.GarbageCollection; -using System.Collections.Generic; using NoStopMod.InputFixer; using NoStopMod.HyperRabbit; -using SimpleJSON; using NoStopMod.Helper; namespace NoStopMod From b98fca313a2360cba210060802f33cd7f0b95570 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 17:32:43 +0900 Subject: [PATCH 32/67] Fix: Fix initially file load fail --- Settings.cs | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/Settings.cs b/Settings.cs index 1c819ce..245dab7 100644 --- a/Settings.cs +++ b/Settings.cs @@ -17,43 +17,38 @@ class Settings public const String path = "\\Mods\\NoStopMod\\settings.json"; public static List settings = new List(); + public static EventListener settingsLoadListener = new EventListener("SettingsLoad"); public static void Init() { - NoStopMod.onToggleListener.Add(onToggle); - NoStopMod.onApplicationQuitListener.Add(onApplicationQuit); - } - - private static void onToggle(bool enabled) - { - Load(); - } - - private static void onApplicationQuit(scrController __instance) - { - Save(); + NoStopMod.onToggleListener.Add(_ => Load()); + NoStopMod.onApplicationQuitListener.Add(_ => Save()); } public static void Load() { - string text = File.ReadAllText(Environment.CurrentDirectory + path); - if (text == null) + try { - Save(); - return; - } + string text = File.ReadAllText(Environment.CurrentDirectory + path); - JSONNode jsonNode = JSON.Parse(text); - for (int i = 0; i < settings.Count(); i++) - { - try - { - settings[i].Load(ref jsonNode); - } - catch (Exception e) + JSONNode jsonNode = JSON.Parse(text); + for (int i = 0; i < settings.Count(); i++) { - NoStopMod.mod.Logger.Error("While Loading : " + e.Message + ", " + e.StackTrace); + try + { + settings[i].Load(ref jsonNode); + } + catch (Exception e) + { + NoStopMod.mod.Logger.Error("While Loading : " + e.Message + ", " + e.StackTrace); + } } + settingsLoadListener.Invoke(true); + } + catch + { + Save(); + settingsLoadListener.Invoke(false); } } From e6bd61ff8d92a4d365cd9477ae521e66230566c7 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 19 Jun 2021 18:40:33 +0900 Subject: [PATCH 33/67] Fix: Fix can't hit when first enable mod --- InputFixer/HitIgnore/HitIgnoreManager.cs | 14 +++++++++++--- InputFixer/InputFixerManager.cs | 16 ++++------------ InputFixer/InputFixerPatches.cs | 9 --------- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/InputFixer/HitIgnore/HitIgnoreManager.cs b/InputFixer/HitIgnore/HitIgnoreManager.cs index e508c2d..9289276 100644 --- a/InputFixer/HitIgnore/HitIgnoreManager.cs +++ b/InputFixer/HitIgnore/HitIgnoreManager.cs @@ -43,6 +43,11 @@ public static void Init() scnCLS_searchMode = false; + if (scrController.instance != null) + { + scrController_state = (scrController.States) scrController.instance.GetState(); + } + KeyLimiterManager.Init(); } @@ -54,9 +59,12 @@ public static bool shouldBeIgnored(KeyCode keyCode) KeyLimiterManager.UpdateKeyLimiter(keyCode); return true; } - - if (scrController_state != scrController.States.PlayerControl) return true; - + + if (scrController_state != scrController.States.PlayerControl) + { + return true; + } + bool[] ignoreScnCLS; if (dictionary.TryGetValue(GCS.sceneToLoad, out ignoreScnCLS)) { diff --git a/InputFixer/InputFixerManager.cs b/InputFixer/InputFixerManager.cs index 4c6d2af..effe688 100644 --- a/InputFixer/InputFixerManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -29,9 +29,10 @@ class InputFixerManager public static void Init() { - NoStopMod.onToggleListener.Add(OnToggle); + NoStopMod.onToggleListener.Add(UpdateEnableAsync); NoStopMod.onGUIListener.Add(OnGUI); - NoStopMod.onApplicationQuitListener.Add(OnApplicationQuit); + NoStopMod.onApplicationQuitListener.Add(_ => Stop()); + Settings.settingsLoadListener.Add(_ => UpdateEnableAsync(settings.enableAsync)); settings = new InputFixerSettings(); Settings.settings.Add(settings); @@ -44,11 +45,6 @@ public static void Init() HitIgnoreManager.Init(); } - private static void OnToggle(bool enabled) - { - UpdateEnableAsync(enabled); - } - private static void OnGUI(UnityModManager.ModEntry modEntry) { //GUILayout.BeginVertical("Input"); @@ -68,11 +64,6 @@ private static void UpdateEnableAsync(bool value) } } - private static void OnApplicationQuit(scrController __instance) - { - Stop(); - } - public static void Start() { Stop(); @@ -181,6 +172,7 @@ public static void adjustOffsetTick() { if (scrConductor.instance != null) { + long prevOffset = offsetTick; InputFixerManager.jumpToOtherClass = true; scrConductor.instance.Start(); } diff --git a/InputFixer/InputFixerPatches.cs b/InputFixer/InputFixerPatches.cs index 1eb9215..6cd5f76 100644 --- a/InputFixer/InputFixerPatches.cs +++ b/InputFixer/InputFixerPatches.cs @@ -93,14 +93,6 @@ public static bool Prefix(scrController __instance, ref int __result) __result = 0; return false; } - - //public static void Postfix(scrController __instance, ref int __result) - //{ - // if (InputFixerManager.settings.enableAsync) - // { - // __result = 0; - // } - //} } [HarmonyPatch(typeof(scrPlanet), "Update_RefreshAngles")] @@ -113,7 +105,6 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) { InputFixerManager.jumpToOtherClass = false; __instance.angle = InputFixerManager.getAngle(__instance, ___snappedLastAngle, InputFixerManager.currPressTick); - return false; } From 42c9fb40fa0b7adffca2be16533834dab284aa34 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sun, 20 Jun 2021 15:36:15 +0900 Subject: [PATCH 34/67] Refactor: Move currFrameTick calculation to NoStopMod class --- InputFixer/InputFixerManager.cs | 16 ++++++---------- InputFixer/InputFixerPatches.cs | 10 ++-------- InputFixer/InputFixerSettings.cs | 1 - NoStopMod.cs | 29 ++++++++++++++++++++++++++++- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/InputFixer/InputFixerManager.cs b/InputFixer/InputFixerManager.cs index effe688..07cf13f 100644 --- a/InputFixer/InputFixerManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -15,9 +15,7 @@ class InputFixerManager private static Thread thread; public static Queue>> keyQueue = new Queue>>(); - - public static long currTick; - public static long prevTick; + public static long offsetTick; public static long currPressTick; @@ -36,9 +34,6 @@ public static void Init() settings = new InputFixerSettings(); Settings.settings.Add(settings); - - prevTick = DateTime.Now.Ticks; - currTick = prevTick; mask = Enumerable.Repeat(false, 1024).ToArray(); @@ -106,10 +101,11 @@ private static bool GetKeyDown(int idx) private static void Run() { - long prevTick = DateTime.Now.Ticks; - while (true) + long prevTick, currTick; + prevTick = DateTime.Now.Ticks; + while (settings.enableAsync) { - long currTick = DateTime.Now.Ticks; + currTick = DateTime.Now.Ticks; if (currTick > prevTick) { prevTick = currTick; @@ -180,7 +176,7 @@ public static void adjustOffsetTick() public static void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) { - offsetTick = currTick - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); + offsetTick = NoStopMod.CurrFrameTick() - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); } } diff --git a/InputFixer/InputFixerPatches.cs b/InputFixer/InputFixerPatches.cs index 6cd5f76..6bc995e 100644 --- a/InputFixer/InputFixerPatches.cs +++ b/InputFixer/InputFixerPatches.cs @@ -37,12 +37,6 @@ public static void Postfix(scrController __instance) [HarmonyPatch(typeof(scrConductor), "Update")] private static class scrConductor_Update_Patch_Time { - public static void Prefix(scrConductor __instance) - { - InputFixerManager.prevTick = InputFixerManager.currTick; - InputFixerManager.currTick = DateTime.Now.Ticks; - } - public static void Postfix(scrConductor __instance, double ___dspTimeSong) { if (AudioListener.pause) @@ -52,7 +46,7 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) if (!InputFixerManager.settings.enableAsync) { - InputFixerManager.UpdateKeyQueue(InputFixerManager.currTick); + InputFixerManager.UpdateKeyQueue(NoStopMod.CurrFrameTick()); } while (InputFixerManager.keyQueue.Any()) @@ -112,7 +106,7 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) if (!GCS.d_stationary) { - long nowTick = InputFixerManager.currTick - InputFixerManager.offsetTick; + long nowTick = NoStopMod.CurrFrameTick() - InputFixerManager.offsetTick; __instance.angle = InputFixerManager.getAngle(__instance, ___snappedLastAngle, nowTick); if (__instance.shouldPrint) diff --git a/InputFixer/InputFixerSettings.cs b/InputFixer/InputFixerSettings.cs index 6d1b1e3..f1ea4b2 100644 --- a/InputFixer/InputFixerSettings.cs +++ b/InputFixer/InputFixerSettings.cs @@ -17,7 +17,6 @@ public void Load(ref JSONNode json) enableAsync = node["enableAsync"].AsBool; enableKeyLimit = node["enableKeyLimit"].AsBool; JSONArray array = node["LimitKeys"].AsArray; - } public void Save(ref JSONNode json) diff --git a/NoStopMod.cs b/NoStopMod.cs index 699b47b..b802828 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -5,6 +5,7 @@ using NoStopMod.InputFixer; using NoStopMod.HyperRabbit; using NoStopMod.Helper; +using System; namespace NoStopMod { @@ -20,6 +21,9 @@ class NoStopMod public static EventListener onHideGUIListener = new EventListener("OnHideGUI"); public static EventListener onApplicationQuitListener = new EventListener("OnApplicationQuit"); + private static long currFrameTick; + private static long prevFrameTick; + public static bool Load(UnityModManager.ModEntry modEntry) { modEntry.OnToggle = NoStopMod.OnToggle; @@ -29,6 +33,9 @@ public static bool Load(UnityModManager.ModEntry modEntry) NoStopMod.harmony = new Harmony(modEntry.Info.Id); NoStopMod.mod = modEntry; + NoStopMod.prevFrameTick = DateTime.Now.Ticks; + NoStopMod.currFrameTick = prevFrameTick; + GCManager.Init(); InputFixerManager.Init(); HyperRabbitManager.Init(); @@ -54,7 +61,27 @@ public static bool OnToggle(UnityModManager.ModEntry modEntry, bool enabled) onToggleListener.Invoke(enabled); return true; } - + + public static long CurrFrameTick() + { + return NoStopMod.currFrameTick; + } + + public static long PrevFrameTick() + { + return NoStopMod.prevFrameTick; + } + + [HarmonyPatch(typeof(scrConductor), "Update")] + private static class scrConductor_Update_Patch_Time + { + public static void Prefix(scrConductor __instance) + { + NoStopMod.prevFrameTick = NoStopMod.currFrameTick; + NoStopMod.currFrameTick = DateTime.Now.Ticks; + } + } + [HarmonyPatch(typeof(scrController), "OnApplicationQuit")] private static class scrController_OnApplicationQuit_Patch { From 894c762be485c8dc7b7dc26f7a6f704c64325a7d Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Mon, 21 Jun 2021 12:19:39 +0900 Subject: [PATCH 35/67] Feat: Make new scrConductor that replaces original scrConductor --- InputFixer/InputFixerManager.cs | 25 +- InputFixer/InputFixerPatches.cs | 95 +--- InputFixer/SyncFixer/SyncFixerManager.cs | 21 + InputFixer/SyncFixer/SyncFixerPatches.cs | 169 ++++++ InputFixer/SyncFixer/newScrConductor.cs | 673 +++++++++++++++++++++++ NoStopMod.csproj | 312 ++++++++++- 6 files changed, 1167 insertions(+), 128 deletions(-) create mode 100644 InputFixer/SyncFixer/SyncFixerManager.cs create mode 100644 InputFixer/SyncFixer/SyncFixerPatches.cs create mode 100644 InputFixer/SyncFixer/newScrConductor.cs diff --git a/InputFixer/InputFixerManager.cs b/InputFixer/InputFixerManager.cs index 07cf13f..7a9a4f8 100644 --- a/InputFixer/InputFixerManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -6,6 +6,7 @@ using System.Threading; using UnityEngine; using UnityModManagerNet; +using NoStopMod.InputFixer.SyncFixer; namespace NoStopMod.InputFixer { @@ -17,7 +18,7 @@ class InputFixerManager public static Queue>> keyQueue = new Queue>>(); - public static long offsetTick; + //public static long offsetTick; public static long currPressTick; public static bool jumpToOtherClass = false; @@ -38,6 +39,7 @@ public static void Init() mask = Enumerable.Repeat(false, 1024).ToArray(); HitIgnoreManager.Init(); + SyncFixerManager.Init(); } private static void OnGUI(UnityModManager.ModEntry modEntry) @@ -62,10 +64,9 @@ private static void UpdateEnableAsync(bool value) public static void Start() { Stop(); - adjustOffsetTick(); if (settings.enableAsync) { - thread = new Thread(Run); - thread.Start(); + //thread = new Thread(Run); + //thread.Start(); } } @@ -163,21 +164,7 @@ public static double getSongPosition(scrConductor __instance, long nowTick) return (__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / __instance.song.pitch; } } - - public static void adjustOffsetTick() - { - if (scrConductor.instance != null) - { - long prevOffset = offsetTick; - InputFixerManager.jumpToOtherClass = true; - scrConductor.instance.Start(); - } - } - - public static void adjustOffsetTick(scrConductor __instance, double ___dspTimeSong) - { - offsetTick = NoStopMod.CurrFrameTick() - (long)((__instance.dspTime - ___dspTimeSong) * 10000000); - } + } } diff --git a/InputFixer/InputFixerPatches.cs b/InputFixer/InputFixerPatches.cs index 6bc995e..ecdb326 100644 --- a/InputFixer/InputFixerPatches.cs +++ b/InputFixer/InputFixerPatches.cs @@ -1,6 +1,7 @@ using DG.Tweening; using HarmonyLib; using NoStopMod.InputFixer.HitIgnore; +using NoStopMod.InputFixer.SyncFixer; using System; using System.Collections.Generic; using System.Linq; @@ -10,26 +11,13 @@ namespace NoStopMod.InputFixer { public static class AsyncInputPatches { - - //public static string s(double d, int to = 6) - //{ - // try - // { - // return ("" + d).Substring(0, to); - // } - // catch - // { - // return "" + d; - // } - //} + /* [HarmonyPatch(typeof(scrController), "Awake")] private static class scrController_Awake_Patch { public static void Postfix(scrController __instance) { - InputFixerManager.jumpToOtherClass = true; - __instance.conductor.Start(); InputFixerManager.Start(); } } @@ -37,12 +25,9 @@ public static void Postfix(scrController __instance) [HarmonyPatch(typeof(scrConductor), "Update")] private static class scrConductor_Update_Patch_Time { - public static void Postfix(scrConductor __instance, double ___dspTimeSong) + public static void Postfix(scrConductor __instance) { - if (AudioListener.pause) - { - InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); - } + if (!InputFixerManager.settings.enableAsync) { @@ -65,7 +50,7 @@ public static void Postfix(scrConductor __instance, double ___dspTimeSong) if (++count > 4) break; } - InputFixerManager.currPressTick = tick - InputFixerManager.offsetTick; + InputFixerManager.currPressTick = tick - SyncFixerManager.newScrConductor.offsetTick; controller.keyBufferCount += count; while (controller.keyBufferCount > 0) { @@ -106,7 +91,7 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) if (!GCS.d_stationary) { - long nowTick = NoStopMod.CurrFrameTick() - InputFixerManager.offsetTick; + long nowTick = NoStopMod.CurrFrameTick() - SyncFixerManager.newScrConductor.offsetTick; __instance.angle = InputFixerManager.getAngle(__instance, ___snappedLastAngle, nowTick); if (__instance.shouldPrint) @@ -151,72 +136,8 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) return false; } } + - [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] - private static class scrController_Rewind_Patch - { - public static void Postfix(scrController __instance) - { - InputFixerManager.jumpToOtherClass = true; - __instance.conductor.Start(); - } - } - - [HarmonyPatch(typeof(scrConductor), "Start")] - private static class scrConductor_Start_Patch - { - public static bool Prefix(scrConductor __instance, double ___dspTimeSong) - { - if (InputFixerManager.jumpToOtherClass) - { - InputFixerManager.jumpToOtherClass = false; - InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); - return false; - } - return true; - } - } - - [HarmonyPatch(typeof(scrConductor), "Rewind")] - private static class scrConductor_Rewind_Patch - { - public static void Postfix(scrConductor __instance, double ___dspTimeSong) - { - InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("Rewind"); - } - } - - [HarmonyPatch(typeof(scrConductor), "StartMusicCo")] - private static class scrConductor_StartMusicCo_Patch - { - public static void Prefix(scrConductor __instance, double ___dspTimeSong) - { - InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("StartMusicCo"); - } - } - - [HarmonyPatch(typeof(scrConductor), "ScrubMusicToTile")] - private static class scrConductor_ScrubMusicToTile_Patch - { - public static void Postfix(scrConductor __instance, double ___dspTimeSong) - { - InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); - } - } - - [HarmonyPatch(typeof(scrConductor), "DesyncFix")] - private static class scrConductor_DesyncFix_Patch - { - public static void Postfix(scrConductor __instance, double ___dspTimeSong) - { - InputFixerManager.adjustOffsetTick(__instance, ___dspTimeSong); - //NoStopMod.mod.Logger.Log("DesyncFix"); - } - } - - + */ } } diff --git a/InputFixer/SyncFixer/SyncFixerManager.cs b/InputFixer/SyncFixer/SyncFixerManager.cs new file mode 100644 index 0000000..d3cf7ea --- /dev/null +++ b/InputFixer/SyncFixer/SyncFixerManager.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NoStopMod.InputFixer.SyncFixer +{ + class SyncFixerManager + { + + public static newScrConductor newScrConductor; + + public static void Init() + { + newScrConductor = new newScrConductor(); + //if (newScrConductor.instance != null) newScrConductor.FixOffsetTick(); + } + + } +} diff --git a/InputFixer/SyncFixer/SyncFixerPatches.cs b/InputFixer/SyncFixer/SyncFixerPatches.cs new file mode 100644 index 0000000..81fe52e --- /dev/null +++ b/InputFixer/SyncFixer/SyncFixerPatches.cs @@ -0,0 +1,169 @@ +using ADOFAI; +using HarmonyLib; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace NoStopMod.InputFixer.SyncFixer +{ + class SyncFixerPatches + { + //[HarmonyPatch(typeof(scrConductor), "StartMusicCo")] + //private static class scrConductor_StartMusicCo_Patch + //{ + // public static IEnumerator Transpiler(scrConductor __instance, Action onComplete, Action onSongScheduled = null) + // { + + [HarmonyPatch(typeof(scrConductor), "Awake")] + private static class scrConductor_Awake_Patch + { + public static bool Prefix(scrConductor __instance) + { + SyncFixerManager.newScrConductor.Awake(__instance); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "Start")] + private static class scrConductor_Start_Patch + { + public static bool Prefix(scrConductor __instance) + { + SyncFixerManager.newScrConductor.Start(__instance); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "Rewind")] + private static class scrConductor_Rewind_Patch + { + public static bool Prefix(scrConductor __instance) + { + SyncFixerManager.newScrConductor.Rewind(__instance); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "SetupConductorWithLevelData")] + private static class scrConductor_SetupConductorWithLevelData_Patch + { + public static bool Prefix(scrConductor __instance, LevelData levelData) + { + SyncFixerManager.newScrConductor.SetupConductorWithLevelData(__instance, levelData); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "PlayHitTimes")] + private static class scrConductor_PlayHitTimes_Patch + { + public static bool Prefix(scrConductor __instance) + { + SyncFixerManager.newScrConductor.PlayHitTimes(__instance); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "GetCountdownTime")] + private static class scrConductor_GetCountdownTime_Patch + { + public static bool Prefix(scrConductor __instance, ref double __result, int i) + { + __result = SyncFixerManager.newScrConductor.GetCountdownTime(__instance, i); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "StartMusic")] + private static class scrConductor_StartMusic_Patch + { + public static bool Prefix(scrConductor __instance, Action onComplete = null, Action onSongScheduled = null) + { + SyncFixerManager.newScrConductor.StartMusic(__instance, onComplete, onSongScheduled); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "StartMusicCo")] + private static class scrConductor_StartMusicCo_Patch + { + public static bool Prefix(IEnumerator __result, scrConductor __instance, Action onComplete, Action onSongScheduled = null) + { + __result = SyncFixerManager.newScrConductor.StartMusicCo(__instance, onComplete, onSongScheduled); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "ToggleHasSongStarted")] + private static class scrConductor_ToggleHasSongStarted_Patch + { + public static bool Prefix(IEnumerator __result, scrConductor __instance, double songstarttime) + { + __result = SyncFixerManager.newScrConductor.ToggleHasSongStarted(__instance, songstarttime); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "Update")] + private static class scrConductor_Update_Patch + { + public static bool Prefix(scrConductor __instance) + { + SyncFixerManager.newScrConductor.Update(__instance); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "OnBeat")] + private static class scrConductor_OnBeat_Patch + { + public static bool Prefix(scrConductor __instance) + { + SyncFixerManager.newScrConductor.OnBeat(__instance); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "PlaySfx")] + private static class scrConductor_PlaySfx_Patch + { + public static bool Prefix(scrConductor __instance, int num, float volume = 1f, bool ignoreListenerPause = false) + { + SyncFixerManager.newScrConductor.PlaySfx(__instance, num, volume, ignoreListenerPause); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "ScrubMusicToTile")] + private static class scrConductor_ScrubMusicToTile_Patch + { + public static bool Prefix(scrConductor __instance, int tileID) + { + SyncFixerManager.newScrConductor.ScrubMusicToTile(__instance, tileID); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "DesyncFix")] + private static class scrConductor_DesyncFix_Patch + { + public static bool Prefix(IEnumerator __result, scrConductor __instance) + { + __result = SyncFixerManager.newScrConductor.DesyncFix(__instance); + return false; + } + } + + [HarmonyPatch(typeof(scrConductor), "SaveVisualOffset")] + private static class scrConductor_SaveVisualOffset_Patch + { + public static bool Prefix(scrConductor __instance, double offset) + { + SyncFixerManager.newScrConductor.SaveVisualOffset(offset); + return false; + } + } + + + } +} diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs new file mode 100644 index 0000000..70b736c --- /dev/null +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -0,0 +1,673 @@ +using ADOFAI; +using DG.Tweening; +using HarmonyLib; +using RDTools; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NoStopMod.InputFixer.SyncFixer +{ + class newScrConductor + { + // Note : this class replaces scrController in ADOFAI. + // to fix Desync bug, I replaced AudioSettings.dspTime to DateTime.Now.Ticks + // I hope this mechanism work well. + + + + /* + dspTime update + Start() + Rewind() + Update() + */ + // a + + //int _________________________________; + + + //// replaces dspTime + //public long offsetTick; + + //public long dspTick; + + + + + //public void FixOffsetTick() + //{ + // offsetTick = NoStopMod.CurrFrameTick() - (long) ((instance.dspTime - dspTimeSong) * 10000000); + //} + + + // Original Code + + // Token: 0x04000288 RID: 648 + public List hitSoundsData = new List(); + + // Token: 0x04000289 RID: 649 + public int nextHitSoundToSchedule; + + // Token: 0x0400028A RID: 650 + public int crotchetsPerBar = 8; + + + // Token: 0x0400028D RID: 653 + public double _songposition_minusi; + + // Token: 0x0400028E RID: 654 + public double previousFrameTime; + + // Token: 0x0400028F RID: 655 + public double lastReportedPlayheadPosition; + + + // Token: 0x04000294 RID: 660 + public double nextBeatTime; + + // Token: 0x04000295 RID: 661 + public double nextBarTime; + + + // Token: 0x04000299 RID: 665 + public float buffer = 1f; + + // Token: 0x0400029D RID: 669 + public float[] _spectrum = new float[1024]; + + // Token: 0x0400029F RID: 671 + public AudioSource audiosource; + + // Token: 0x040002A0 RID: 672 + public bool playedHitSounds; + + // Token: 0x040002A1 RID: 673 + public scrConductor.DuckState _duckState; + + // Token: 0x040002A2 RID: 674 + public float songPreduckVolume; + + // Token: 0x040002A3 RID: 675 + public float song2PreduckVolume; + + // Token: 0x040002A6 RID: 678 + public double dspTimeSong; + + // Token: 0x040002A8 RID: 680 + public List _onBeats = new List(); + + public static scrConductor instance + { + get + { + if (newScrConductor._instance == null) + { + newScrConductor._instance = UnityEngine.Object.FindObjectOfType(); + } + return newScrConductor._instance; + } + } + + // Token: 0x040002A9 RID: 681 + private static scrConductor _instance; + + // Token: 0x040002AA RID: 682 + public Coroutine startMusicCoroutine; + + public struct HitSoundsData + { + // Token: 0x06000CE9 RID: 3305 RVA: 0x0005342A File Offset: 0x0005162A + public HitSoundsData(HitSound hitSound, double time, float volume) + { + this.hitSound = hitSound; + this.time = time; + this.volume = volume; + this.played = false; + } + + // Token: 0x04000FCC RID: 4044 + public HitSound hitSound; + + // Token: 0x04000FCD RID: 4045 + public double time; + + // Token: 0x04000FCE RID: 4046 + public float volume; + + // Token: 0x04000FCF RID: 4047 + public bool played; + } + + public void Awake(scrConductor __instance) + { + ADOBase.Startup(); + if (GCS.d_webglConductor) + { + this.buffer = 0.5f; + } + if (Application.platform == RuntimePlatform.WindowsPlayer) + { + this.buffer = 0.5f; + } + if (Application.platform == RuntimePlatform.WindowsEditor) + { + this.buffer = 0.5f; + } + if (Application.platform == RuntimePlatform.OSXPlayer) + { + this.buffer = 0.5f; + } + if (Application.platform == RuntimePlatform.OSXEditor) + { + this.buffer = 0.5f; + } + if (__instance.uiController != null) + { + __instance.txtOffset = __instance.uiController.txtOffset; + } + if (scnEditor.instance == null) + { + scnEditor.instance = __instance.editorComponent; + } + if (scnEditor.instance == null) + { + scnCLS.instance = __instance.CLSComponent; + } + if (CustomLevel.instance == null) + { + CustomLevel.instance = __instance.customLevelComponent; + } + } + + public void Start(scrConductor __instance) + { + __instance.crotchet = (double)(60f / __instance.bpm); + __instance.crotchetAtStart = __instance.crotchet; + AudioSource[] components = __instance.GetComponents(); + __instance.song = components[0]; + if (components.Length > 1) + { + __instance.song2 = components[1]; + } + + this.nextBeatTime = 0.0; + this.nextBarTime = 0.0; + if (__instance.txtOffset != null) + { + __instance.txtOffset.text = ""; + } + this.lastReportedPlayheadPosition = AudioSettings.dspTime; + __instance.dspTime = AudioSettings.dspTime; + this.previousFrameTime = Time.unscaledTime; + if (__instance.song.pitch == 0f && !__instance.isLevelEditor) + { + Debug.LogError("Song pitch is zero set to zero?!"); + } + if (__instance.controller != null) + { + __instance.controller.startVolume = __instance.song.volume; + } + + //FixOffsetTick(); + } + + // Token: 0x060001C5 RID: 453 RVA: 0x0000CC64 File Offset: 0x0000AE64 + public void Rewind(scrConductor __instance) + { + __instance.tick = null; + __instance.tickclip = null; + __instance.isGameWorld = true; + __instance.rescrub = true; + __instance.crotchet = 0.0; + this.nextBeatTime = 0.0; + this.nextBarTime = 0.0; + __instance.beatNumber = 0; + __instance.barNumber = 0; + __instance.hasSongStarted = false; + __instance.getSpectrum = false; + __instance.txtStatus = null; + __instance.txtOffset = null; + this.dspTimeSong = 0.0; + __instance.lastHit = 0.0; + this.lastReportedPlayheadPosition = AudioSettings.dspTime; + __instance.dspTime = AudioSettings.dspTime; + this.previousFrameTime = (double)Time.unscaledTime; + + //FixOffsetTick(); + } + + // Token: 0x060001C6 RID: 454 RVA: 0x0000CD24 File Offset: 0x0000AF24 + public void SetupConductorWithLevelData(scrConductor __instance, LevelData levelData) + { + __instance.bpm = levelData.bpm; + __instance.crotchet = (double)(60f / __instance.bpm); + __instance.crotchetAtStart = __instance.crotchet; + __instance.addoffset = (double)((float)levelData.offset * 0.001f); + __instance.song.volume = (float)levelData.volume * 0.01f; + __instance.hitSoundVolume = (float)levelData.hitsoundVolume * 0.01f; + __instance.hitSound = levelData.hitsound; + __instance.separateCountdownTime = levelData.separateCountdownTime; + float num = (float)levelData.pitch * 0.01f; + if (GCS.standaloneLevelMode) + { + num *= GCS.currentSpeedRun; + } + __instance.song.pitch = num; + } + + // StartMusicCo, DesyncFix + public void PlayHitTimes(scrConductor __instance) + { + if (this.playedHitSounds) + { + AudioManager.Instance.StopAllSounds(); + } + this.playedHitSounds = true; + if (ADOBase.sceneName.Contains("scnCalibration") || __instance.lm == null || !GCS.d_hitsounds) + { + return; + } + if (__instance.controller != null && !__instance.controller.isLevelEditor && !__instance.forceHitSounds) + { + return; + } + HitSound hitSound = __instance.hitSound; + float volume = __instance.hitSoundVolume; + List listFloors = __instance.lm.listFloors; + int num = (GCS.checkpointNum < listFloors.Count && GCS.usingCheckpoints) ? (GCS.checkpointNum + 1) : 1; + double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; + this.hitSoundsData = new List(); + this.nextHitSoundToSchedule = 0; + for (int i = 1; i < listFloors.Count; i++) + { + scrFloor scrFloor = listFloors[i]; + ffxSetHitsound setHitsound = scrFloor.setHitsound; + if (setHitsound != null) + { + hitSound = setHitsound.hitSound; + volume = setHitsound.volume; + } + double num3 = (hitSound == HitSound.Shaker || hitSound == HitSound.ShakerLoud) ? 0.015 : 0.0; + double num4 = num2 + scrFloor.entryTimePitchAdj - num3; + if (i >= num && num4 > __instance.dspTime && !scrFloor.midSpin && hitSound != HitSound.None) + { + HitSoundsData item = new HitSoundsData(hitSound, num4, volume); + this.hitSoundsData.Add(item); + } + } + + if (__instance.playCountdownHihats) + { + if (!__instance.fastTakeoff) + { + __instance.countdownTimes = new double[__instance.countdownTicks]; + for (int j = 0; j < __instance.countdownTicks; j++) + { + double countdownTime = this.GetCountdownTime(__instance, j); + if (countdownTime > __instance.dspTime) + { + __instance.countdownTimes[j] = countdownTime; + AudioManager.Play("sndHat", countdownTime, __instance.hitSoundVolume, 10); + } + } + } + if (__instance.playEndingCymbal) + { + AudioManager.Play("sndCymbalCrash", this.dspTimeSong + __instance.lm.listFloors[__instance.lm.listFloors.Count - 1].entryTimePitchAdj + + __instance.addoffset / __instance.song.pitch, __instance.hitSoundVolume, 128); + } + } + } + + // Token: 0x060001C8 RID: 456 RVA: 0x0000D028 File Offset: 0x0000B228 + public double GetCountdownTime(scrConductor __instance, int i) + { + if (GCS.checkpointNum != 0 && GCS.usingCheckpoints) + { + int index = (GCS.checkpointNum != __instance.lm.listFloors.Count - 1) ? (GCS.checkpointNum + 1) : GCS.checkpointNum; + return this.dspTimeSong + __instance.lm.listFloors[index].entryTimePitchAdj - (double)(__instance.countdownTicks - i) * (__instance.crotchet / (double)__instance.lm.listFloors[GCS.checkpointNum].speed) / (double)__instance.song.pitch + __instance.addoffset / (double)__instance.song.pitch; + } + return this.dspTimeSong + (double)i * __instance.crotchet / (double)__instance.song.pitch + __instance.addoffset / (double)__instance.song.pitch; + } + + // Token: 0x060001C9 RID: 457 RVA: 0x0000D10E File Offset: 0x0000B30E + public void StartMusic(scrConductor __instance, Action onComplete = null, Action onSongScheduled = null) + { + if (this.startMusicCoroutine != null) + { + __instance.StopCoroutine(this.startMusicCoroutine); + } + this.startMusicCoroutine = __instance.StartCoroutine(this.StartMusicCo(__instance, onComplete, onSongScheduled)); + } + + // Token: 0x060001CA RID: 458 RVA: 0x0000D138 File Offset: 0x0000B338 + public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Action onSongScheduled = null) + { + this.dspTimeSong = __instance.dspTime + (double)this.buffer + 0.10000000149011612; + + for (float timer = 0.1f; timer >= 0f; timer -= Time.deltaTime) + { + yield return 0; + } + this.dspTimeSong = __instance.dspTime + (double)this.buffer; + if (__instance.fastTakeoff) + { + this.dspTimeSong -= (double)__instance.countdownTicks * __instance.crotchetAtStart / (double)__instance.song.pitch; + } + + //FixOffsetTick(); + + __instance.song.UnPause(); + + double time = this.dspTimeSong + (__instance.separateCountdownTime ? (__instance.crotchet / (double)__instance.song.pitch * (double)__instance.countdownTicks) : 0.0); + __instance.song.PlayScheduled(time); + if (__instance.song2 != null) + { + __instance.song2.PlayScheduled(time); + } + __instance.StartCoroutine(this.ToggleHasSongStarted(__instance, this.dspTimeSong)); + + if (GCS.checkpointNum == 0) + { + __instance.PlayHitTimes(); + } + yield return 0; + onSongScheduled?.Invoke(); + yield return new WaitForSeconds(4f); + while (__instance.song.isPlaying) + { + yield return null; + } + if (onComplete != null) + { + onComplete(); + } + yield break; + } + + // Token: 0x060001CB RID: 459 RVA: 0x0000D155 File Offset: 0x0000B355 + public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstarttime) + { + NoStopMod.mod.Logger.Log("ToggleHasSongStarted"); + if (GCS.d_webglConductor) + { + __instance.song.volume = 0f; + } + while (scrConductor.instance.dspTime < songstarttime) + { + yield return null; + } + __instance.hasSongStarted = true; + scrDebugHUDMessage.Log("Song started forreal!"); + if (GCS.d_webglConductor) + { + yield return new WaitForSeconds(0.2f); + __instance.song.Pause(); + yield return new WaitForSeconds(0.1f); + __instance.song.UnPause(); + __instance.song.volume = 1f; + } + yield break; + } + + // Token: 0x060001CC RID: 460 RVA: 0x0000D16C File Offset: 0x0000B36C + public void Update(scrConductor __instance) + { + RDInput.Update(); + if (!AudioListener.pause && Application.isFocused && Time.unscaledTime - this.previousFrameTime < 0.10000000149011612) + { + __instance.dspTime += Time.unscaledTime - this.previousFrameTime; + + //NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + ((DateTime.Now.Ticks - offsetTick) / 10000000.0)); + } + + //if (AudioListener.pause) + //{ + // FixOffsetTick(); + //} + + this.previousFrameTime = Time.unscaledTime; + if (AudioSettings.dspTime != this.lastReportedPlayheadPosition) + { + __instance.dspTime = AudioSettings.dspTime; + this.lastReportedPlayheadPosition = AudioSettings.dspTime; + } + if (__instance.hasSongStarted && __instance.isGameWorld && (scrController.States)__instance.controller.GetState() != scrController.States.Fail && (scrController.States)__instance.controller.GetState() != scrController.States.Fail2) + { + while (this.nextHitSoundToSchedule < this.hitSoundsData.Count) + { + HitSoundsData hitSoundsData = this.hitSoundsData[this.nextHitSoundToSchedule]; + if (__instance.dspTime + 5.0 <= hitSoundsData.time) + { + break; + } + AudioManager.Play("snd" + hitSoundsData.hitSound, hitSoundsData.time, hitSoundsData.volume, 128); + this.nextHitSoundToSchedule++; + } + } + __instance.crotchet = (double)(60f / __instance.bpm); + double songposition_minusi = __instance.songposition_minusi; + if (!GCS.d_oldConductor && !GCS.d_webglConductor) + { + __instance.songposition_minusi = (double)((float)(__instance.dspTime - this.dspTimeSong - (double)scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + } + else + { + __instance.songposition_minusi = (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; + } + + __instance.deltaSongPos = __instance.songposition_minusi - songposition_minusi; + __instance.deltaSongPos = Math.Max(__instance.deltaSongPos, 0.0); + if (__instance.songposition_minusi > this.nextBeatTime) + { + __instance.OnBeat(); + this.nextBeatTime += __instance.crotchet; + __instance.beatNumber++; + } + if (__instance.songposition_minusi < this.nextBeatTime - __instance.crotchet) + { + this.nextBeatTime -= __instance.crotchet; + __instance.beatNumber--; + } + if (__instance.songposition_minusi > this.nextBarTime) + { + this.nextBarTime += __instance.crotchet * (double)this.crotchetsPerBar; + __instance.barNumber++; + } + + if (Input.GetKeyDown(KeyCode.G) && Application.isEditor) + { + float time = __instance.song.time; + if (__instance.separateCountdownTime) + { + double num = __instance.crotchetAtStart; + int num2 = __instance.countdownTicks; + } + double songposition_minusi2 = __instance.songposition_minusi; + float calibration_i = scrConductor.calibration_i; + float pitch = __instance.song.pitch; + double num3 = __instance.addoffset; + } + if (GCS.d_calibration) + { + if (!(__instance.editor == null)) + { + if (__instance.editor != null) + { + bool flag = !__instance.controller.paused; + } + } + } + + if (__instance.getSpectrum && !GCS.lofiVersion) + { + AudioSource audioSource = __instance.song; + if (__instance.CLSComponent != null) + { + PreviewSongPlayer previewSongPlayer = __instance.CLSComponent.previewSongPlayer; + if (previewSongPlayer.playing) + { + audioSource = previewSongPlayer.audioSource; + } + } + audioSource.GetSpectrumData(__instance.spectrum, 0, FFTWindow.BlackmanHarris); + } + } + + // Token: 0x060001CD RID: 461 RVA: 0x0000D4CC File Offset: 0x0000B6CC + public void OnBeat(scrConductor __instance) + { + List onBeats = __instance.onBeats; + if (onBeats == null) + { + return; + } + int count = onBeats.Count; + for (int i = 0; i < count; i++) + { + onBeats[i].OnBeat(); + } + if (__instance.controller != null && __instance.controller.gameworld) + { + List listFloors = __instance.controller.lm.listFloors; + int count2 = listFloors.Count; + for (int j = 0; j < count2; j++) + { + listFloors[j].OnBeat(); + } + } + } + + // Token: 0x060001CE RID: 462 RVA: 0x0000D555 File Offset: 0x0000B755 + public void PlaySfx(scrConductor __instance, int num, float volume = 1f, bool ignoreListenerPause = false) + { + if (num == 2) + { + volume = 1.5f; + } + scrSfx.instance.Play(num, ignoreListenerPause, volume); + } + + // Token: 0x060001CF RID: 463 RVA: 0x0000D570 File Offset: 0x0000B770 + public void ScrubMusicToTile(scrConductor __instance, int tileID) + { + NoStopMod.mod.Logger.Log("ScrubMusicToTile"); + AudioListener.pause = true; + AudioManager.Instance.StopAllSounds(); + __instance.song.SetScheduledStartTime(__instance.dspTime); + double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; + __instance.song.time = (float)(__instance.lm.listFloors[tileID].entryTime + __instance.addoffset - num); + this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[tileID].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; + __instance.lastHit = __instance.lm.listFloors[tileID].entryTime; + __instance.StartCoroutine(this.DesyncFix(__instance)); + } + + // Token: 0x060001D0 RID: 464 RVA: 0x0000D64B File Offset: 0x0000B84B + public IEnumerator DesyncFix(scrConductor __instance) + { + NoStopMod.mod.Logger.Log("DesyncFix"); + int num; + for (int framecounty = 2; framecounty > 0; framecounty = num - 1) + { + yield return 0; + num = framecounty; + } + AudioListener.pause = false; + __instance.PlayHitTimes(); + int numberOfAttempts = 0; + int framesToWait = 10; + double maxDifference = 0.005; + for (int i = 0; i < numberOfAttempts; i = num + 1) + { + for (int framecount = framesToWait; framecount > 0; framecount = num - 1) + { + yield return 0; + num = framecount; + } + if (__instance.song.isPlaying || __instance.song.clip == null) + { + yield break; + } + double num2 = (double)__instance.song.time + (__instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0); + double num3 = __instance.songposition_minusi + (double)(scrConductor.calibration_i * __instance.song.pitch) + __instance.addoffset; + if (Math.Abs(num3 - num2) > maxDifference) + { + double num4 = num2 - num3; + Debug.Log("Desync Fix Attempt: found difference " + num4); + Debug.Log("Attempt " + i); + Debug.Log("song time " + num2); + Debug.Log("dsptime " + num3); + this.dspTimeSong -= num4; + __instance.PlayHitTimes(); + } + num = i; + } + yield break; + } + + // Token: 0x060001D7 RID: 471 RVA: 0x0000D89B File Offset: 0x0000BA9B + private int GetOffsetChange(bool fine) + { + if (!fine) + { + return 10; + } + return 1; + } + + // Token: 0x060001DC RID: 476 RVA: 0x0000D91C File Offset: 0x0000BB1C + public static void SaveCurrentPreset() + { + for (int i = 0; i < scrConductor.userPresets.Count; i++) + { + CalibrationPreset calibrationPreset = scrConductor.userPresets[i]; + if (scrConductor.currentPreset.outputType == calibrationPreset.outputType && scrConductor.currentPreset.outputName == calibrationPreset.outputName) + { + RDBaseDll.printem("found preset, modifying."); + calibrationPreset.inputOffset = scrConductor.currentPreset.inputOffset; + scrConductor.userPresets[i] = calibrationPreset; + return; + } + } + RDBaseDll.printem("adding preset: " + scrConductor.currentPreset); + scrConductor.userPresets.Add(scrConductor.currentPreset); + } + + + // Token: 0x060001E1 RID: 481 RVA: 0x0000DB61 File Offset: 0x0000BD61 + public void SaveVisualOffset(double offset) + { + Persistence.SetVisualOffset((float)offset); + PlayerPrefs.SetFloat("offset_v", (float)offset); + PlayerPrefs.Save(); + } + + // Token: 0x060001E3 RID: 483 RVA: 0x0000DC98 File Offset: 0x0000BE98 + //public void LoadOnBeats() + //{ + // if (this._onBeats.Count != 0) + // { + // return; + // } + // this._onBeats = new List(); + // GameObject[] array = GameObject.FindGameObjectsWithTag("Beat"); + // for (int i = 0; i < array.Length; i++) + // { + // ADOBase component = array[i].GetComponent(); + // if (component != null && component) + // { + // this._onBeats.Add(component); + // } + // } + //} + + + + + } +} diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 3aeba95..931e0ee 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -35,56 +35,321 @@ false - + + False ..\lib\0Harmony.dll - - ..\lib\Assembly-CSharp.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Assembly-CSharp.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Assembly-CSharp-firstpass.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\DemiLib.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\DOTween.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\DOTweenPro.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\I18N.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\I18N.CJK.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\I18N.MidEast.dll - - ..\lib\Assembly-CSharp-firstpass.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\I18N.Other.dll - - ..\lib\DOTween.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\I18N.Rare.dll - - ..\lib\DOTweenPro.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\I18N.West.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Ionic.Zip.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Mono.Data.Sqlite.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Mono.Posix.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Mono.Security.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Mono.WebBrowser.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Novell.Directory.Ldap.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Ookii.Dialogs.dll False - ..\lib\RD\RDTools.dll + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\RDTools.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\sharedRuntime.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Sirenix.OdinInspector.Attributes.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Sirenix.OdinInspector.CompatibilityLayer.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Sirenix.Serialization.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Sirenix.Serialization.Config.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Sirenix.Utilities.dll + + + + + + + + + + + + + + + + + - - - - ..\lib\UnityEngine.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Unity.MemoryProfiler.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Unity.TextMeshPro.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\Unity.Timeline.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.AccessibilityModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.AIModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.AndroidJNIModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.AnimationModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ARModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.AssetBundleModule.dll False - ..\lib\UnityEngine.AudioModule.dll + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.AudioModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ClothModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ClusterInputModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ClusterRendererModule.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.CoreModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.CrashReportingModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.DirectorModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.DSPGraphModule.dll - - ..\lib\UnityEngine.CoreModule.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.GameCenterModule.dll - - ..\lib\UnityEngine.IMGUIModule.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.GridModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.HotReloadModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ImageConversionModule.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.IMGUIModule.dll False - ..\lib\UnityEngine.InputLegacyModule.dll + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.InputLegacyModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.InputModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.JSONSerializeModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.LocalizationModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ParticleSystemModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.PerformanceReportingModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.Physics2DModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.PhysicsModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ProfilerModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.ScreenCaptureModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.SharedInternalsModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.SpriteMaskModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.SpriteShapeModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.StreamingModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.SubstanceModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.SubsystemsModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.TerrainModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.TerrainPhysicsModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.TextCoreModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.TextRenderingModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.TilemapModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.TLSModule.dll + + + False + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UI.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UIElementsModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UIModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UmbraModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UNETModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityAnalyticsModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityConnectModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityTestProtocolModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityWebRequestAssetBundleModule.dll - - ..\lib\UnityEngine.UI.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityWebRequestAudioModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityWebRequestModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityWebRequestTextureModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.UnityWebRequestWWWModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.VehiclesModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.VFXModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.VideoModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.VRModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.WindModule.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\UnityEngine.XRModule.dll ..\lib\UnityModManager.dll + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\urecordRuntime.dll + + + ..\..\..\..\Desktop\ADOFAI R75 20210619\dll\XTUtilities.dll + @@ -102,10 +367,13 @@ + + + From c4807dfb41a63ddabbade1c7c0c029b9b304e507 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Mon, 21 Jun 2021 15:56:54 +0900 Subject: [PATCH 36/67] Fix: Fix desync issue. --- InputFixer/InputFixerManager.cs | 7 +- InputFixer/InputFixerPatches.cs | 5 +- InputFixer/SyncFixer/SyncFixerManager.cs | 2 +- InputFixer/SyncFixer/newScrConductor.cs | 90 +++++++++++++++--------- 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/InputFixer/InputFixerManager.cs b/InputFixer/InputFixerManager.cs index 7a9a4f8..e487ccb 100644 --- a/InputFixer/InputFixerManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -65,8 +65,8 @@ public static void Start() { Stop(); if (settings.enableAsync) { - //thread = new Thread(Run); - //thread.Start(); + thread = new Thread(Run); + thread.Start(); } } @@ -157,7 +157,7 @@ public static double getSongPosition(scrConductor __instance, long nowTick) { if (!GCS.d_oldConductor && !GCS.d_webglConductor) { - return ((nowTick / 10000000.0 - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + return ((nowTick / 10000000.0 - SyncFixerManager.newScrConductor.dspTimeSong - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; } else { @@ -165,6 +165,5 @@ public static double getSongPosition(scrConductor __instance, long nowTick) } } - } } diff --git a/InputFixer/InputFixerPatches.cs b/InputFixer/InputFixerPatches.cs index ecdb326..c0e33a5 100644 --- a/InputFixer/InputFixerPatches.cs +++ b/InputFixer/InputFixerPatches.cs @@ -12,7 +12,6 @@ namespace NoStopMod.InputFixer public static class AsyncInputPatches { - /* [HarmonyPatch(typeof(scrController), "Awake")] private static class scrController_Awake_Patch { @@ -28,7 +27,6 @@ private static class scrConductor_Update_Patch_Time public static void Postfix(scrConductor __instance) { - if (!InputFixerManager.settings.enableAsync) { InputFixerManager.UpdateKeyQueue(NoStopMod.CurrFrameTick()); @@ -137,7 +135,6 @@ public static bool Prefix(scrPlanet __instance, ref double ___snappedLastAngle) } } - - */ + } } diff --git a/InputFixer/SyncFixer/SyncFixerManager.cs b/InputFixer/SyncFixer/SyncFixerManager.cs index d3cf7ea..06a8ea6 100644 --- a/InputFixer/SyncFixer/SyncFixerManager.cs +++ b/InputFixer/SyncFixer/SyncFixerManager.cs @@ -14,7 +14,7 @@ class SyncFixerManager public static void Init() { newScrConductor = new newScrConductor(); - //if (newScrConductor.instance != null) newScrConductor.FixOffsetTick(); + if (newScrConductor.instance != null) newScrConductor.FixOffsetTick(); } } diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 70b736c..ad71f9b 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -31,22 +31,42 @@ dspTime update //int _________________________________; - //// replaces dspTime - //public long offsetTick; + // new code + public long offsetTick; - //public long dspTick; + public long dspTick; + public void FixOffsetTick() + { + offsetTick = NoStopMod.CurrFrameTick() - (long)(instance.dspTime * 10000000); + } - //public void FixOffsetTick() + // from scrController + //public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDontStartMusicFourTilesBefore = false) //{ - // offsetTick = NoStopMod.CurrFrameTick() - (long) ((instance.dspTime - dspTimeSong) * 10000000); + // int result = floorNum; + // if (GCS.usingCheckpoints && !forceDontStartMusicFourTilesBefore) + // { + // List floorList = conductor.lm.listFloors; + // // (60f / this.bpm) * speed; + // double startSpeed = conductor.crotchetAtStart / (double)floorList[floorNum].speed; + // for (int i = floorNum - 1; i >= 1; i--) + // { + // if (floorList[i].entryTime <= floorList[floorNum].entryTime - (double) conductor.countdownTicks * num) + // { + // result = i; + // break; + // } + // } + // } + // return result; //} - + // Original Code - + // Token: 0x04000288 RID: 648 public List hitSoundsData = new List(); @@ -58,7 +78,7 @@ dspTime update // Token: 0x0400028D RID: 653 - public double _songposition_minusi; + //public double _songposition_minusi; // Token: 0x0400028E RID: 654 public double previousFrameTime; @@ -203,6 +223,7 @@ public void Start(scrConductor __instance) } this.lastReportedPlayheadPosition = AudioSettings.dspTime; __instance.dspTime = AudioSettings.dspTime; + FixOffsetTick(); this.previousFrameTime = Time.unscaledTime; if (__instance.song.pitch == 0f && !__instance.isLevelEditor) { @@ -213,7 +234,6 @@ public void Start(scrConductor __instance) __instance.controller.startVolume = __instance.song.volume; } - //FixOffsetTick(); } // Token: 0x060001C5 RID: 453 RVA: 0x0000CC64 File Offset: 0x0000AE64 @@ -236,9 +256,9 @@ public void Rewind(scrConductor __instance) __instance.lastHit = 0.0; this.lastReportedPlayheadPosition = AudioSettings.dspTime; __instance.dspTime = AudioSettings.dspTime; + FixOffsetTick(); this.previousFrameTime = (double)Time.unscaledTime; - //FixOffsetTick(); } // Token: 0x060001C6 RID: 454 RVA: 0x0000CD24 File Offset: 0x0000AF24 @@ -419,23 +439,30 @@ public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstar public void Update(scrConductor __instance) { RDInput.Update(); - if (!AudioListener.pause && Application.isFocused && Time.unscaledTime - this.previousFrameTime < 0.10000000149011612) + //if (!AudioListener.pause && Application.isFocused && Time.unscaledTime - this.previousFrameTime < 0.10000000149011612) + //{ + // __instance.dspTime += Time.unscaledTime - this.previousFrameTime; + // dspTick = NoStopMod.CurrFrameTick() - offsetTick; + // NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + (dspTick / 10000000.0)); + //} + + if (AudioListener.pause) + { + offsetTick += NoStopMod.CurrFrameTick() - NoStopMod.PrevFrameTick(); + } + else { __instance.dspTime += Time.unscaledTime - this.previousFrameTime; - - //NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + ((DateTime.Now.Ticks - offsetTick) / 10000000.0)); + dspTick = NoStopMod.CurrFrameTick() - offsetTick; + //NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + (dspTick / 10000000.0) + "diff(" + (__instance.dspTime - (dspTick / 10000000.0)) + ")"); } - - //if (AudioListener.pause) - //{ - // FixOffsetTick(); - //} this.previousFrameTime = Time.unscaledTime; if (AudioSettings.dspTime != this.lastReportedPlayheadPosition) { __instance.dspTime = AudioSettings.dspTime; this.lastReportedPlayheadPosition = AudioSettings.dspTime; + FixOffsetTick(); } if (__instance.hasSongStarted && __instance.isGameWorld && (scrController.States)__instance.controller.GetState() != scrController.States.Fail && (scrController.States)__instance.controller.GetState() != scrController.States.Fail2) { @@ -493,16 +520,16 @@ public void Update(scrConductor __instance) float pitch = __instance.song.pitch; double num3 = __instance.addoffset; } - if (GCS.d_calibration) - { - if (!(__instance.editor == null)) - { - if (__instance.editor != null) - { - bool flag = !__instance.controller.paused; - } - } - } + //if (GCS.d_calibration) + //{ + // if (!(__instance.editor == null)) + // { + // if (__instance.editor != null) + // { + // bool flag = !__instance.controller.paused; + // } + // } + //} if (__instance.getSpectrum && !GCS.lofiVersion) { @@ -518,8 +545,7 @@ public void Update(scrConductor __instance) audioSource.GetSpectrumData(__instance.spectrum, 0, FFTWindow.BlackmanHarris); } } - - // Token: 0x060001CD RID: 461 RVA: 0x0000D4CC File Offset: 0x0000B6CC + public void OnBeat(scrConductor __instance) { List onBeats = __instance.onBeats; @@ -556,7 +582,7 @@ public void PlaySfx(scrConductor __instance, int num, float volume = 1f, bool ig // Token: 0x060001CF RID: 463 RVA: 0x0000D570 File Offset: 0x0000B770 public void ScrubMusicToTile(scrConductor __instance, int tileID) { - NoStopMod.mod.Logger.Log("ScrubMusicToTile"); + //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); AudioListener.pause = true; AudioManager.Instance.StopAllSounds(); __instance.song.SetScheduledStartTime(__instance.dspTime); @@ -570,7 +596,7 @@ public void ScrubMusicToTile(scrConductor __instance, int tileID) // Token: 0x060001D0 RID: 464 RVA: 0x0000D64B File Offset: 0x0000B84B public IEnumerator DesyncFix(scrConductor __instance) { - NoStopMod.mod.Logger.Log("DesyncFix"); + //NoStopMod.mod.Logger.Log("DesyncFix"); int num; for (int framecounty = 2; framecounty > 0; framecounty = num - 1) { From e5c817677853d66a6b39796dc9c8700d7296223c Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Mon, 21 Jun 2021 15:57:58 +0900 Subject: [PATCH 37/67] Doc: Update version --- Info.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Info.json b/Info.json index 49e3030..1009b84 100644 --- a/Info.json +++ b/Info.json @@ -2,7 +2,7 @@ "Id": "NoStopMod", "DisplayName": "NoStopMod", "Author": "Luxus", - "Version": "1.1.0", + "Version": "1.2.1", "ManagerVersion": "0.23.4.0", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load" From cfed53244325728e9728fc9f88ec19216c2a0bf0 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Mon, 21 Jun 2021 19:24:23 +0900 Subject: [PATCH 38/67] Feat: ADOFAI Desync bug fix (probably?) --- ...hes.cs => SyncFixerPatchesScrConductor.cs} | 2 +- .../SyncFixerPatchesScrController.cs | 86 +++++++++ InputFixer/SyncFixer/newScrConductor.cs | 180 ++++++++++-------- NoStopMod.csproj | 3 +- 4 files changed, 185 insertions(+), 86 deletions(-) rename InputFixer/SyncFixer/{SyncFixerPatches.cs => SyncFixerPatchesScrConductor.cs} (99%) create mode 100644 InputFixer/SyncFixer/SyncFixerPatchesScrController.cs diff --git a/InputFixer/SyncFixer/SyncFixerPatches.cs b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs similarity index 99% rename from InputFixer/SyncFixer/SyncFixerPatches.cs rename to InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs index 81fe52e..a51e1ea 100644 --- a/InputFixer/SyncFixer/SyncFixerPatches.cs +++ b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs @@ -6,7 +6,7 @@ namespace NoStopMod.InputFixer.SyncFixer { - class SyncFixerPatches + class SyncFixerPatchesScrConductor { //[HarmonyPatch(typeof(scrConductor), "StartMusicCo")] //private static class scrConductor_StartMusicCo_Patch diff --git a/InputFixer/SyncFixer/SyncFixerPatchesScrController.cs b/InputFixer/SyncFixer/SyncFixerPatchesScrController.cs new file mode 100644 index 0000000..ee6842a --- /dev/null +++ b/InputFixer/SyncFixer/SyncFixerPatchesScrController.cs @@ -0,0 +1,86 @@ +using DG.Tweening; +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NoStopMod.InputFixer.SyncFixer +{ + class SyncFixerPatchesScrController + { + + [HarmonyPatch(typeof(scrController), "OnMusicScheduled")] + private static class scrController_OnMusicScheduled_Patch + { + public static bool Prefix(scrController __instance) + { + if (GCS.checkpointNum != 0) + { + //__instance.conductor.hasSongStarted = true; + __instance.Scrub(GCS.checkpointNum, RDC.auto && __instance.isLevelEditor); + __instance.ChangeState(scrController.States.Checkpoint); + } + else if (!GCS.d_oldConductor) + { + __instance.conductor.song.time = 0f; + scrController.States states = (__instance.gameworld && !__instance.forceNoCountdown) ? scrController.States.Countdown : scrController.States.PlayerControl; + __instance.printe("changing to state: " + states); + __instance.ChangeState(states); + } + __instance.uiController.MinimizeDifficultyContainer(); + if (GCS.checkpointNum != 0) + { + scrDebugHUDMessage.Log("OnMusicStart"); + if (__instance.isLevelEditor) + { + scrUIController.instance.FadeFromBlack(1f); + } + } + if (!__instance.gameworld) + { + scrUIController.instance.FadeFromBlack(0.3f); + } + float duration = Mathf.Min(50f / (__instance.conductor.bpm * __instance.conductor.song.pitch), 0.5f); + DOTween.To(() => __instance.chosenplanet.cosmeticRadius, delegate (float x) + { + __instance.chosenplanet.cosmeticRadius = x; + }, __instance.startRadius, duration); + + return false; + } + } + + + [HarmonyPatch(typeof(scrController), "Scrub")] + private static class scrController_Scrub_Patch + { + public static bool Prefix(scrController __instance, int floorNum, bool forceDontStartMusicFourTilesBefore = false) + { + if (floorNum > scrLevelMaker.instance.listFloors.Count - 1 || floorNum < 0) + { + scrDebugHUDMessage.Log("Past the limit"); + return false; + } + int num = __instance.FindScrubStart(floorNum, forceDontStartMusicFourTilesBefore); + int windbackNum = (num == floorNum) ? -1 : num; + __instance.chosenplanet.ScrubToFloorNumber(floorNum, windbackNum, __instance.isLevelEditor || RDC.debug); + if (RDC.debug) + { + __instance.camy.ViewObjectInstant(__instance.chosenplanet.transform, false); + } + //base.conductor.ScrubMusicToTile(num); + if (__instance.isLevelEditor) + { + GameObject.Find("Vfx") + ?.GetComponent() + ?.ScrubToTime((float) __instance.lm.listFloors[num].entryTime); + } + return false; + } + } + + } +} diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index ad71f9b..aa98150 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -44,25 +44,24 @@ public void FixOffsetTick() // from scrController - //public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDontStartMusicFourTilesBefore = false) - //{ - // int result = floorNum; - // if (GCS.usingCheckpoints && !forceDontStartMusicFourTilesBefore) - // { - // List floorList = conductor.lm.listFloors; - // // (60f / this.bpm) * speed; - // double startSpeed = conductor.crotchetAtStart / (double)floorList[floorNum].speed; - // for (int i = floorNum - 1; i >= 1; i--) - // { - // if (floorList[i].entryTime <= floorList[floorNum].entryTime - (double) conductor.countdownTicks * num) - // { - // result = i; - // break; - // } - // } - // } - // return result; - //} + public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDontStartMusicFourTilesBefore = false) + { + int result = floorNum; + if (GCS.usingCheckpoints && !forceDontStartMusicFourTilesBefore) + { + List floorList = conductor.lm.listFloors; + double startSpeed = conductor.crotchetAtStart / (double)floorList[floorNum].speed; + for (int i = floorNum - 1; i >= 1; i--) + { + if (floorList[i].entryTime <= floorList[floorNum].entryTime - (double)conductor.countdownTicks * startSpeed) + { + result = i; + break; + } + } + } + return result; + } // Original Code @@ -288,24 +287,24 @@ public void PlayHitTimes(scrConductor __instance) AudioManager.Instance.StopAllSounds(); } this.playedHitSounds = true; - if (ADOBase.sceneName.Contains("scnCalibration") || __instance.lm == null || !GCS.d_hitsounds) - { - return; - } - if (__instance.controller != null && !__instance.controller.isLevelEditor && !__instance.forceHitSounds) + if (ADOBase.sceneName.Contains("scnCalibration") || + __instance.lm == null || + !GCS.d_hitsounds || + (__instance.controller != null && !__instance.controller.isLevelEditor && !__instance.forceHitSounds)) { return; } HitSound hitSound = __instance.hitSound; float volume = __instance.hitSoundVolume; - List listFloors = __instance.lm.listFloors; - int num = (GCS.checkpointNum < listFloors.Count && GCS.usingCheckpoints) ? (GCS.checkpointNum + 1) : 1; + List floorList = __instance.lm.listFloors; + int num = (GCS.checkpointNum < floorList.Count && GCS.usingCheckpoints) ? (GCS.checkpointNum + 1) : 1; double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; + this.hitSoundsData = new List(); this.nextHitSoundToSchedule = 0; - for (int i = 1; i < listFloors.Count; i++) + for (int i = 1; i < floorList.Count; i++) { - scrFloor scrFloor = listFloors[i]; + scrFloor scrFloor = floorList[i]; ffxSetHitsound setHitsound = scrFloor.setHitsound; if (setHitsound != null) { @@ -313,10 +312,10 @@ public void PlayHitTimes(scrConductor __instance) volume = setHitsound.volume; } double num3 = (hitSound == HitSound.Shaker || hitSound == HitSound.ShakerLoud) ? 0.015 : 0.0; - double num4 = num2 + scrFloor.entryTimePitchAdj - num3; - if (i >= num && num4 > __instance.dspTime && !scrFloor.midSpin && hitSound != HitSound.None) + double time = num2 + scrFloor.entryTimePitchAdj - num3; + if (i >= num && time > __instance.dspTime && !scrFloor.midSpin && hitSound != HitSound.None) { - HitSoundsData item = new HitSoundsData(hitSound, num4, volume); + HitSoundsData item = new HitSoundsData(hitSound, time, volume); this.hitSoundsData.Add(item); } } @@ -362,6 +361,7 @@ public void StartMusic(scrConductor __instance, Action onComplete = null, Action { __instance.StopCoroutine(this.startMusicCoroutine); } + AudioManager.Instance.StopAllSounds(); this.startMusicCoroutine = __instance.StartCoroutine(this.StartMusicCo(__instance, onComplete, onSongScheduled)); } @@ -372,7 +372,7 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti for (float timer = 0.1f; timer >= 0f; timer -= Time.deltaTime) { - yield return 0; + yield return null; } this.dspTimeSong = __instance.dspTime + (double)this.buffer; if (__instance.fastTakeoff) @@ -391,22 +391,33 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti __instance.song2.PlayScheduled(time); } __instance.StartCoroutine(this.ToggleHasSongStarted(__instance, this.dspTimeSong)); - - if (GCS.checkpointNum == 0) + + if (GCS.checkpointNum != 0) { - __instance.PlayHitTimes(); + yield return null; + + int startTile = FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor); + + AudioListener.pause = true; + __instance.song.SetScheduledStartTime(__instance.dspTime); + double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; + __instance.song.time = (float)(__instance.lm.listFloors[startTile].entryTime + __instance.addoffset - num); + this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[startTile].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; + __instance.lastHit = __instance.lm.listFloors[startTile].entryTime; + AudioListener.pause = false; + } - yield return 0; + onSongScheduled?.Invoke(); + + this.PlayHitTimes(__instance); yield return new WaitForSeconds(4f); while (__instance.song.isPlaying) { yield return null; } - if (onComplete != null) - { - onComplete(); - } + onComplete?.Invoke(); + yield break; } @@ -583,56 +594,57 @@ public void PlaySfx(scrConductor __instance, int num, float volume = 1f, bool ig public void ScrubMusicToTile(scrConductor __instance, int tileID) { //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); - AudioListener.pause = true; - AudioManager.Instance.StopAllSounds(); - __instance.song.SetScheduledStartTime(__instance.dspTime); - double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; - __instance.song.time = (float)(__instance.lm.listFloors[tileID].entryTime + __instance.addoffset - num); - this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[tileID].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; - __instance.lastHit = __instance.lm.listFloors[tileID].entryTime; - __instance.StartCoroutine(this.DesyncFix(__instance)); + //AudioListener.pause = true; + //AudioManager.Instance.StopAllSounds(); + //__instance.song.SetScheduledStartTime(__instance.dspTime); + //double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; + //__instance.song.time = (float)(__instance.lm.listFloors[tileID].entryTime + __instance.addoffset - num); + //this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[tileID].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; + //__instance.lastHit = __instance.lm.listFloors[tileID].entryTime; + //__instance.StartCoroutine(this.DesyncFix(__instance)); } // Token: 0x060001D0 RID: 464 RVA: 0x0000D64B File Offset: 0x0000B84B public IEnumerator DesyncFix(scrConductor __instance) { //NoStopMod.mod.Logger.Log("DesyncFix"); - int num; - for (int framecounty = 2; framecounty > 0; framecounty = num - 1) - { - yield return 0; - num = framecounty; - } - AudioListener.pause = false; - __instance.PlayHitTimes(); - int numberOfAttempts = 0; - int framesToWait = 10; - double maxDifference = 0.005; - for (int i = 0; i < numberOfAttempts; i = num + 1) - { - for (int framecount = framesToWait; framecount > 0; framecount = num - 1) - { - yield return 0; - num = framecount; - } - if (__instance.song.isPlaying || __instance.song.clip == null) - { - yield break; - } - double num2 = (double)__instance.song.time + (__instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0); - double num3 = __instance.songposition_minusi + (double)(scrConductor.calibration_i * __instance.song.pitch) + __instance.addoffset; - if (Math.Abs(num3 - num2) > maxDifference) - { - double num4 = num2 - num3; - Debug.Log("Desync Fix Attempt: found difference " + num4); - Debug.Log("Attempt " + i); - Debug.Log("song time " + num2); - Debug.Log("dsptime " + num3); - this.dspTimeSong -= num4; - __instance.PlayHitTimes(); - } - num = i; - } + //int num; + //for (int framecounty = 2; framecounty > 0; framecounty = num - 1) + //{ + // yield return 0; + // num = framecounty; + //} + //AudioListener.pause = false; + //__instance.PlayHitTimes(); + + //int numberOfAttempts = 0; + //int framesToWait = 10; + //double maxDifference = 0.005; + //for (int i = 0; i < numberOfAttempts; i = num + 1) + //{ + // for (int framecount = framesToWait; framecount > 0; framecount = num - 1) + // { + // yield return 0; + // num = framecount; + // } + // if (__instance.song.isPlaying || __instance.song.clip == null) + // { + // yield break; + // } + // double num2 = (double)__instance.song.time + (__instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0); + // double num3 = __instance.songposition_minusi + (double)(scrConductor.calibration_i * __instance.song.pitch) + __instance.addoffset; + // if (Math.Abs(num3 - num2) > maxDifference) + // { + // double num4 = num2 - num3; + // Debug.Log("Desync Fix Attempt: found difference " + num4); + // Debug.Log("Attempt " + i); + // Debug.Log("song time " + num2); + // Debug.Log("dsptime " + num3); + // this.dspTimeSong -= num4; + // __instance.PlayHitTimes(); + // } + // num = i; + //} yield break; } diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 931e0ee..79edc58 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -367,7 +367,8 @@ - + + From 5ef24aea943bf325fb174042a66ece6a82d708c2 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Tue, 22 Jun 2021 09:32:33 +0900 Subject: [PATCH 39/67] Fix: Try to fix desync 2 --- InputFixer/SyncFixer/newScrConductor.cs | 66 +++++++++++++++---------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index aa98150..4701977 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -36,7 +36,7 @@ dspTime update public long dspTick; - + public void FixOffsetTick() { offsetTick = NoStopMod.CurrFrameTick() - (long)(instance.dspTime * 10000000); @@ -202,7 +202,7 @@ public void Awake(scrConductor __instance) CustomLevel.instance = __instance.customLevelComponent; } } - + public void Start(scrConductor __instance) { __instance.crotchet = (double)(60f / __instance.bpm); @@ -287,9 +287,9 @@ public void PlayHitTimes(scrConductor __instance) AudioManager.Instance.StopAllSounds(); } this.playedHitSounds = true; - if (ADOBase.sceneName.Contains("scnCalibration") || - __instance.lm == null || - !GCS.d_hitsounds || + if (ADOBase.sceneName.Contains("scnCalibration") || + __instance.lm == null || + !GCS.d_hitsounds || (__instance.controller != null && !__instance.controller.isLevelEditor && !__instance.forceHitSounds)) { return; @@ -337,7 +337,7 @@ public void PlayHitTimes(scrConductor __instance) } if (__instance.playEndingCymbal) { - AudioManager.Play("sndCymbalCrash", this.dspTimeSong + __instance.lm.listFloors[__instance.lm.listFloors.Count - 1].entryTimePitchAdj + + AudioManager.Play("sndCymbalCrash", this.dspTimeSong + __instance.lm.listFloors[__instance.lm.listFloors.Count - 1].entryTimePitchAdj + __instance.addoffset / __instance.song.pitch, __instance.hitSoundVolume, 128); } } @@ -361,13 +361,15 @@ public void StartMusic(scrConductor __instance, Action onComplete = null, Action { __instance.StopCoroutine(this.startMusicCoroutine); } - AudioManager.Instance.StopAllSounds(); + //AudioManager.Instance.StopAllSounds(); this.startMusicCoroutine = __instance.StartCoroutine(this.StartMusicCo(__instance, onComplete, onSongScheduled)); } // Token: 0x060001CA RID: 458 RVA: 0x0000D138 File Offset: 0x0000B338 public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Action onSongScheduled = null) { + __instance.dspTime = AudioSettings.dspTime; + FixOffsetTick(); this.dspTimeSong = __instance.dspTime + (double)this.buffer + 0.10000000149011612; for (float timer = 0.1f; timer >= 0f; timer -= Time.deltaTime) @@ -381,43 +383,48 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti } //FixOffsetTick(); + //yield return null; - __instance.song.UnPause(); + //__instance.song.UnPause(); double time = this.dspTimeSong + (__instance.separateCountdownTime ? (__instance.crotchet / (double)__instance.song.pitch * (double)__instance.countdownTicks) : 0.0); __instance.song.PlayScheduled(time); - if (__instance.song2 != null) - { - __instance.song2.PlayScheduled(time); - } + __instance.song2?.PlayScheduled(time); __instance.StartCoroutine(this.ToggleHasSongStarted(__instance, this.dspTimeSong)); - + if (GCS.checkpointNum != 0) { - yield return null; - + AudioListener.pause = true; int startTile = FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor); - AudioListener.pause = true; + yield return null; __instance.song.SetScheduledStartTime(__instance.dspTime); + //__instance.song.PlayScheduled(__instance.dspTime); double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; __instance.song.time = (float)(__instance.lm.listFloors[startTile].entryTime + __instance.addoffset - num); this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[startTile].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; __instance.lastHit = __instance.lm.listFloors[startTile].entryTime; - AudioListener.pause = false; - + } - onSongScheduled?.Invoke(); + //this.ToggleHasSongStarted(__instance, this.dspTimeSong); + yield return null; + yield return null; this.PlayHitTimes(__instance); + __instance.conductor.hasSongStarted = true; + AudioListener.pause = false; + + + onSongScheduled?.Invoke(); + yield return new WaitForSeconds(4f); while (__instance.song.isPlaying) { yield return null; } onComplete?.Invoke(); - + yield break; } @@ -475,6 +482,7 @@ public void Update(scrConductor __instance) this.lastReportedPlayheadPosition = AudioSettings.dspTime; FixOffsetTick(); } + if (__instance.hasSongStarted && __instance.isGameWorld && (scrController.States)__instance.controller.GetState() != scrController.States.Fail && (scrController.States)__instance.controller.GetState() != scrController.States.Fail2) { while (this.nextHitSoundToSchedule < this.hitSoundsData.Count) @@ -556,7 +564,7 @@ public void Update(scrConductor __instance) audioSource.GetSpectrumData(__instance.spectrum, 0, FFTWindow.BlackmanHarris); } } - + public void OnBeat(scrConductor __instance) { List onBeats = __instance.onBeats; @@ -590,7 +598,7 @@ public void PlaySfx(scrConductor __instance, int num, float volume = 1f, bool ig scrSfx.instance.Play(num, ignoreListenerPause, volume); } - // Token: 0x060001CF RID: 463 RVA: 0x0000D570 File Offset: 0x0000B770 + // Moved into startMusicCo public void ScrubMusicToTile(scrConductor __instance, int tileID) { //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); @@ -647,7 +655,7 @@ public IEnumerator DesyncFix(scrConductor __instance) //} yield break; } - + // Token: 0x060001D7 RID: 471 RVA: 0x0000D89B File Offset: 0x0000BA9B private int GetOffsetChange(bool fine) { @@ -657,7 +665,7 @@ private int GetOffsetChange(bool fine) } return 1; } - + // Token: 0x060001DC RID: 476 RVA: 0x0000D91C File Offset: 0x0000BB1C public static void SaveCurrentPreset() { @@ -675,7 +683,7 @@ public static void SaveCurrentPreset() RDBaseDll.printem("adding preset: " + scrConductor.currentPreset); scrConductor.userPresets.Add(scrConductor.currentPreset); } - + // Token: 0x060001E1 RID: 481 RVA: 0x0000DB61 File Offset: 0x0000BD61 public void SaveVisualOffset(double offset) @@ -684,7 +692,7 @@ public void SaveVisualOffset(double offset) PlayerPrefs.SetFloat("offset_v", (float)offset); PlayerPrefs.Save(); } - + // Token: 0x060001E3 RID: 483 RVA: 0x0000DC98 File Offset: 0x0000BE98 //public void LoadOnBeats() //{ @@ -705,7 +713,11 @@ public void SaveVisualOffset(double offset) //} - + } } + + + + From 99b543eadee4ee02b6c5dee4fb5feb3b7a62e541 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Tue, 22 Jun 2021 12:19:31 +0900 Subject: [PATCH 40/67] Fix: Fix desync bug (3rd edit) --- InputFixer/SyncFixer/newScrConductor.cs | 82 +++++++++++++++---------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 4701977..89a7da6 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -10,8 +10,12 @@ using System.Threading.Tasks; using UnityEngine; + + namespace NoStopMod.InputFixer.SyncFixer { + + class newScrConductor { // Note : this class replaces scrController in ADOFAI. @@ -40,6 +44,9 @@ dspTime update public void FixOffsetTick() { offsetTick = NoStopMod.CurrFrameTick() - (long)(instance.dspTime * 10000000); +#if DEBUG + NoStopMod.mod.Logger.Log("FixOffsetTick"); +#endif } @@ -222,6 +229,9 @@ public void Start(scrConductor __instance) } this.lastReportedPlayheadPosition = AudioSettings.dspTime; __instance.dspTime = AudioSettings.dspTime; +#if DEBUG + NoStopMod.mod.Logger.Log("CallFrom Start"); +#endif FixOffsetTick(); this.previousFrameTime = Time.unscaledTime; if (__instance.song.pitch == 0f && !__instance.isLevelEditor) @@ -255,6 +265,9 @@ public void Rewind(scrConductor __instance) __instance.lastHit = 0.0; this.lastReportedPlayheadPosition = AudioSettings.dspTime; __instance.dspTime = AudioSettings.dspTime; +#if DEBUG + NoStopMod.mod.Logger.Log("callFrom Rewind"); +#endif FixOffsetTick(); this.previousFrameTime = (double)Time.unscaledTime; @@ -369,6 +382,9 @@ public void StartMusic(scrConductor __instance, Action onComplete = null, Action public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Action onSongScheduled = null) { __instance.dspTime = AudioSettings.dspTime; +#if DEBUG + NoStopMod.mod.Logger.Log("call From StartMusicCo First"); +#endif FixOffsetTick(); this.dspTimeSong = __instance.dspTime + (double)this.buffer + 0.10000000149011612; @@ -390,33 +406,34 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti double time = this.dspTimeSong + (__instance.separateCountdownTime ? (__instance.crotchet / (double)__instance.song.pitch * (double)__instance.countdownTicks) : 0.0); __instance.song.PlayScheduled(time); __instance.song2?.PlayScheduled(time); - __instance.StartCoroutine(this.ToggleHasSongStarted(__instance, this.dspTimeSong)); + //__instance.StartCoroutine(this.ToggleHasSongStarted(__instance, this.dspTimeSong)); if (GCS.checkpointNum != 0) { - AudioListener.pause = true; int startTile = FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor); - + + AudioListener.pause = true; yield return null; + __instance.song.SetScheduledStartTime(__instance.dspTime); - //__instance.song.PlayScheduled(__instance.dspTime); double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; __instance.song.time = (float)(__instance.lm.listFloors[startTile].entryTime + __instance.addoffset - num); this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[startTile].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; __instance.lastHit = __instance.lm.listFloors[startTile].entryTime; + AudioListener.pause = false; } - //this.ToggleHasSongStarted(__instance, this.dspTimeSong); - yield return null; - yield return null; - + __instance.hasSongStarted = true; this.PlayHitTimes(__instance); - __instance.conductor.hasSongStarted = true; - AudioListener.pause = false; - onSongScheduled?.Invoke(); +#if DEBUG + NoStopMod.mod.Logger.Log("call From StartMusicCo Second"); +#endif + FixOffsetTick(); + yield return null; + FixOffsetTick(); yield return new WaitForSeconds(4f); while (__instance.song.isPlaying) @@ -431,25 +448,25 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti // Token: 0x060001CB RID: 459 RVA: 0x0000D155 File Offset: 0x0000B355 public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstarttime) { - NoStopMod.mod.Logger.Log("ToggleHasSongStarted"); - if (GCS.d_webglConductor) - { - __instance.song.volume = 0f; - } - while (scrConductor.instance.dspTime < songstarttime) - { - yield return null; - } - __instance.hasSongStarted = true; - scrDebugHUDMessage.Log("Song started forreal!"); - if (GCS.d_webglConductor) - { - yield return new WaitForSeconds(0.2f); - __instance.song.Pause(); - yield return new WaitForSeconds(0.1f); - __instance.song.UnPause(); - __instance.song.volume = 1f; - } + //NoStopMod.mod.Logger.Log("ToggleHasSongStarted"); + //if (GCS.d_webglConductor) + //{ + // __instance.song.volume = 0f; + //} + //while (scrConductor.instance.dspTime < songstarttime) + //{ + // yield return null; + //} + //__instance.hasSongStarted = true; + //scrDebugHUDMessage.Log("Song started forreal!"); + //if (GCS.d_webglConductor) + //{ + // yield return new WaitForSeconds(0.2f); + // __instance.song.Pause(); + // yield return new WaitForSeconds(0.1f); + // __instance.song.UnPause(); + // __instance.song.volume = 1f; + //} yield break; } @@ -472,7 +489,9 @@ public void Update(scrConductor __instance) { __instance.dspTime += Time.unscaledTime - this.previousFrameTime; dspTick = NoStopMod.CurrFrameTick() - offsetTick; - //NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + (dspTick / 10000000.0) + "diff(" + (__instance.dspTime - (dspTick / 10000000.0)) + ")"); +#if DEBUG + NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + (dspTick / 10000000.0) + "diff(" + (__instance.dspTime - (dspTick / 10000000.0)) + ")"); +#endif } this.previousFrameTime = Time.unscaledTime; @@ -480,7 +499,6 @@ public void Update(scrConductor __instance) { __instance.dspTime = AudioSettings.dspTime; this.lastReportedPlayheadPosition = AudioSettings.dspTime; - FixOffsetTick(); } if (__instance.hasSongStarted && __instance.isGameWorld && (scrController.States)__instance.controller.GetState() != scrController.States.Fail && (scrController.States)__instance.controller.GetState() != scrController.States.Fail2) From 04d12253c448782c0beec2ddc29e84c8ccb3239c Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 23 Jun 2021 08:47:53 +0900 Subject: [PATCH 41/67] Refactor: Move hitsound start timing calculation to StartMusicCo --- .../SyncFixer/SyncFixerPatchesScrConductor.cs | 18 +++++------ InputFixer/SyncFixer/newScrConductor.cs | 32 ++++++++++++++----- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs index a51e1ea..75aa6f4 100644 --- a/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs +++ b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs @@ -54,15 +54,15 @@ public static bool Prefix(scrConductor __instance, LevelData levelData) } } - [HarmonyPatch(typeof(scrConductor), "PlayHitTimes")] - private static class scrConductor_PlayHitTimes_Patch - { - public static bool Prefix(scrConductor __instance) - { - SyncFixerManager.newScrConductor.PlayHitTimes(__instance); - return false; - } - } + //[HarmonyPatch(typeof(scrConductor), "PlayHitTimes")] + //private static class scrConductor_PlayHitTimes_Patch + //{ + // public static bool Prefix(scrConductor __instance) + // { + // SyncFixerManager.newScrConductor.PlayHitTimes(__instance); + // return false; + // } + //} [HarmonyPatch(typeof(scrConductor), "GetCountdownTime")] private static class scrConductor_GetCountdownTime_Patch diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 89a7da6..cf92a5b 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -293,7 +293,7 @@ public void SetupConductorWithLevelData(scrConductor __instance, LevelData level } // StartMusicCo, DesyncFix - public void PlayHitTimes(scrConductor __instance) + public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) { if (this.playedHitSounds) { @@ -311,7 +311,7 @@ public void PlayHitTimes(scrConductor __instance) float volume = __instance.hitSoundVolume; List floorList = __instance.lm.listFloors; int num = (GCS.checkpointNum < floorList.Count && GCS.usingCheckpoints) ? (GCS.checkpointNum + 1) : 1; - double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; + //double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; this.hitSoundsData = new List(); this.nextHitSoundToSchedule = 0; @@ -324,8 +324,8 @@ public void PlayHitTimes(scrConductor __instance) hitSound = setHitsound.hitSound; volume = setHitsound.volume; } - double num3 = (hitSound == HitSound.Shaker || hitSound == HitSound.ShakerLoud) ? 0.015 : 0.0; - double time = num2 + scrFloor.entryTimePitchAdj - num3; + double hitsoundOffset = (hitSound == HitSound.Shaker || hitSound == HitSound.ShakerLoud) ? 0.015 : 0.0; + double time = hitsoundPlayFrom + scrFloor.entryTimePitchAdj - hitsoundOffset; if (i >= num && time > __instance.dspTime && !scrFloor.midSpin && hitSound != HitSound.None) { HitSoundsData item = new HitSoundsData(hitSound, time, volume); @@ -392,6 +392,13 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti { yield return null; } + + __instance.dspTime = AudioSettings.dspTime; +#if DEBUG + NoStopMod.mod.Logger.Log("call From StartMusicCo Second"); +#endif + FixOffsetTick(); + this.dspTimeSong = __instance.dspTime + (double)this.buffer; if (__instance.fastTakeoff) { @@ -408,6 +415,7 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti __instance.song2?.PlayScheduled(time); //__instance.StartCoroutine(this.ToggleHasSongStarted(__instance, this.dspTimeSong)); + double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; if (GCS.checkpointNum != 0) { int startTile = FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor); @@ -418,18 +426,26 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti __instance.song.SetScheduledStartTime(__instance.dspTime); double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; __instance.song.time = (float)(__instance.lm.listFloors[startTile].entryTime + __instance.addoffset - num); - this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[startTile].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; + + hitSoundPlayFrom = __instance.dspTime - __instance.lm.listFloors[startTile].entryTimePitchAdj; + this.dspTimeSong = hitSoundPlayFrom - __instance.addoffset / (double)__instance.song.pitch; __instance.lastHit = __instance.lm.listFloors[startTile].entryTime; - AudioListener.pause = false; } + //double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; + this.PlayHitTimes(__instance, hitSoundPlayFrom); + AudioListener.pause = false; + __instance.hasSongStarted = true; - this.PlayHitTimes(__instance); + + // problem: hitsound plays very little later. + // how to solve?.... + onSongScheduled?.Invoke(); #if DEBUG - NoStopMod.mod.Logger.Log("call From StartMusicCo Second"); + NoStopMod.mod.Logger.Log("call From StartMusicCo Third"); #endif FixOffsetTick(); yield return null; From 9c8fec9185890b35d721555eb54ef8d19c0d1aa4 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 23 Jun 2021 09:34:38 +0900 Subject: [PATCH 42/67] Refactor: Remove duplicated countdownTime calculation --- InputFixer/SyncFixer/newScrConductor.cs | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index cf92a5b..04b3722 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -405,40 +405,33 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti this.dspTimeSong -= (double)__instance.countdownTicks * __instance.crotchetAtStart / (double)__instance.song.pitch; } - //FixOffsetTick(); - //yield return null; - - //__instance.song.UnPause(); - - double time = this.dspTimeSong + (__instance.separateCountdownTime ? (__instance.crotchet / (double)__instance.song.pitch * (double)__instance.countdownTicks) : 0.0); + double countdownTime = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; + double time = this.dspTimeSong + countdownTime / __instance.song.pitch; __instance.song.PlayScheduled(time); __instance.song2?.PlayScheduled(time); - //__instance.StartCoroutine(this.ToggleHasSongStarted(__instance, this.dspTimeSong)); double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; if (GCS.checkpointNum != 0) { int startTile = FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor); - + AudioListener.pause = true; yield return null; - + __instance.song.SetScheduledStartTime(__instance.dspTime); - double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; - __instance.song.time = (float)(__instance.lm.listFloors[startTile].entryTime + __instance.addoffset - num); - + __instance.song.time = (float)(__instance.lm.listFloors[startTile].entryTime + __instance.addoffset - countdownTime); + hitSoundPlayFrom = __instance.dspTime - __instance.lm.listFloors[startTile].entryTimePitchAdj; this.dspTimeSong = hitSoundPlayFrom - __instance.addoffset / (double)__instance.song.pitch; __instance.lastHit = __instance.lm.listFloors[startTile].entryTime; } - - //double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; + this.PlayHitTimes(__instance, hitSoundPlayFrom); AudioListener.pause = false; __instance.hasSongStarted = true; - + // problem: hitsound plays very little later. // how to solve?.... From ee32a66ca37e576dd6fcaf8160db91233cde3f14 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 23 Jun 2021 11:26:21 +0900 Subject: [PATCH 43/67] Refactor: Simplify StartMusicCo --- InputFixer/SyncFixer/newScrConductor.cs | 44 +++++++++++-------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 04b3722..24a7a56 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -386,7 +386,7 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti NoStopMod.mod.Logger.Log("call From StartMusicCo First"); #endif FixOffsetTick(); - this.dspTimeSong = __instance.dspTime + (double)this.buffer + 0.10000000149011612; + this.dspTimeSong = __instance.dspTime + (double)this.buffer + 0.1f; for (float timer = 0.1f; timer >= 0f; timer -= Time.deltaTime) { @@ -399,41 +399,37 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti #endif FixOffsetTick(); - this.dspTimeSong = __instance.dspTime + (double)this.buffer; + this.dspTimeSong = __instance.dspTime + (double) this.buffer; if (__instance.fastTakeoff) { - this.dspTimeSong -= (double)__instance.countdownTicks * __instance.crotchetAtStart / (double)__instance.song.pitch; + this.dspTimeSong -= (double)__instance.crotchetAtStart * __instance.countdownTicks / __instance.song.pitch; } - double countdownTime = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; + double countdownTime = __instance.separateCountdownTime ? (__instance.crotchetAtStart * __instance.countdownTicks) : 0.0; + + if (GCS.checkpointNum != 0) + { + this.dspTimeSong = __instance.dspTime - countdownTime / __instance.song.pitch + this.buffer; + } double time = this.dspTimeSong + countdownTime / __instance.song.pitch; + __instance.song.PlayScheduled(time); __instance.song2?.PlayScheduled(time); - - double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; + if (GCS.checkpointNum != 0) { - int startTile = FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor); - - AudioListener.pause = true; - yield return null; - - __instance.song.SetScheduledStartTime(__instance.dspTime); - __instance.song.time = (float)(__instance.lm.listFloors[startTile].entryTime + __instance.addoffset - countdownTime); - - hitSoundPlayFrom = __instance.dspTime - __instance.lm.listFloors[startTile].entryTimePitchAdj; - this.dspTimeSong = hitSoundPlayFrom - __instance.addoffset / (double)__instance.song.pitch; - __instance.lastHit = __instance.lm.listFloors[startTile].entryTime; - + double entryTime = __instance.lm.listFloors[FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor)].entryTime; + + double destTime = entryTime + __instance.addoffset - countdownTime; + this.dspTimeSong -= destTime / __instance.song.pitch; + __instance.song.time = (float) destTime; + + __instance.lastHit = entryTime; } - - this.PlayHitTimes(__instance, hitSoundPlayFrom); - AudioListener.pause = false; + double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / __instance.song.pitch; + this.PlayHitTimes(__instance, hitSoundPlayFrom); __instance.hasSongStarted = true; - - // problem: hitsound plays very little later. - // how to solve?.... onSongScheduled?.Invoke(); From f65013f24c9a73eb036d58cf9851565a33959f81 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Wed, 23 Jun 2021 12:13:13 +0900 Subject: [PATCH 44/67] Fix: Fix sound bug --- InputFixer/InputFixerManager.cs | 14 ++------- InputFixer/SyncFixer/newScrConductor.cs | 38 ++++++++++++++++--------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/InputFixer/InputFixerManager.cs b/InputFixer/InputFixerManager.cs index e487ccb..962aa6a 100644 --- a/InputFixer/InputFixerManager.cs +++ b/InputFixer/InputFixerManager.cs @@ -149,21 +149,11 @@ private static List getPressedKeys() public static double getAngle(scrPlanet __instance, double ___snappedLastAngle, long nowTick) { - return ___snappedLastAngle + (getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet + return ___snappedLastAngle + (SyncFixerManager.newScrConductor.getSongPosition(__instance.conductor, nowTick) - __instance.conductor.lastHit) / __instance.conductor.crotchet * 3.141592653598793238 * __instance.controller.speed * (double)(__instance.controller.isCW ? 1 : -1); } - public static double getSongPosition(scrConductor __instance, long nowTick) - { - if (!GCS.d_oldConductor && !GCS.d_webglConductor) - { - return ((nowTick / 10000000.0 - SyncFixerManager.newScrConductor.dspTimeSong - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; - } - else - { - return (__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / __instance.song.pitch; - } - } + } } diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 24a7a56..c8fbc7a 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -32,9 +32,6 @@ dspTime update */ // a - //int _________________________________; - - // new code public long offsetTick; @@ -49,6 +46,17 @@ public void FixOffsetTick() #endif } + public double getSongPosition(scrConductor __instance, long nowTick) + { + if (!GCS.d_oldConductor && !GCS.d_webglConductor) + { + return ((nowTick / 10000000.0 - this.dspTimeSong - scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + } + else + { + return (__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / __instance.song.pitch; + } + } // from scrController public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDontStartMusicFourTilesBefore = false) @@ -412,7 +420,8 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti this.dspTimeSong = __instance.dspTime - countdownTime / __instance.song.pitch + this.buffer; } double time = this.dspTimeSong + countdownTime / __instance.song.pitch; - + + __instance.song.UnPause(); __instance.song.PlayScheduled(time); __instance.song2?.PlayScheduled(time); @@ -520,17 +529,18 @@ public void Update(scrConductor __instance) } } __instance.crotchet = (double)(60f / __instance.bpm); - double songposition_minusi = __instance.songposition_minusi; - if (!GCS.d_oldConductor && !GCS.d_webglConductor) - { - __instance.songposition_minusi = (double)((float)(__instance.dspTime - this.dspTimeSong - (double)scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; - } - else - { - __instance.songposition_minusi = (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; - } + double prevSongposition_minusi = __instance.songposition_minusi; + __instance.songposition_minusi = getSongPosition(__instance, dspTick); + //if (!GCS.d_oldConductor && !GCS.d_webglConductor) + //{ + // __instance.songposition_minusi = (double)((float)(__instance.dspTime - this.dspTimeSong - (double)scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; + //} + //else + //{ + // __instance.songposition_minusi = (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; + //} - __instance.deltaSongPos = __instance.songposition_minusi - songposition_minusi; + __instance.deltaSongPos = __instance.songposition_minusi - prevSongposition_minusi; __instance.deltaSongPos = Math.Max(__instance.deltaSongPos, 0.0); if (__instance.songposition_minusi > this.nextBeatTime) { From 947da6a1d982c229ed5d19907ee94a55d9ed6adc Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 10:14:19 +0900 Subject: [PATCH 45/67] Fix: Fix start timing desync. --- InputFixer/SyncFixer/SongAudioSource.cs | 45 +++++++++++++++++++++ InputFixer/SyncFixer/newScrConductor.cs | 53 +++++++++++-------------- NoStopMod.csproj | 1 + 3 files changed, 69 insertions(+), 30 deletions(-) create mode 100644 InputFixer/SyncFixer/SongAudioSource.cs diff --git a/InputFixer/SyncFixer/SongAudioSource.cs b/InputFixer/SyncFixer/SongAudioSource.cs new file mode 100644 index 0000000..34a5898 --- /dev/null +++ b/InputFixer/SyncFixer/SongAudioSource.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NoStopMod.InputFixer.SyncFixer +{ + class SongAudioSource : MonoBehaviour + { + + //public AudioSource m_audioSource; + + //private bool m_playbackUnmutePending; + //private double? m_startTime; + + //public void PlayScheduled(double dspStartTime) + //{ + // m_startTime = dspStartTime; + // m_playbackUnmutePending = true; // weird bug, plays an artifact before scheduled time? + // m_audioSource.PlayScheduled(dspStartTime); + //} + + //void OnAudioFilterRead(float[] data, int channels) + //{ + // if (!m_playbackUnmutePending) + // { + // return; + // } + + // if (AudioSettings.dspTime >= m_startTime) + // { + // m_playbackUnmutePending = false; + // return; + // } + + // for (int i = 0; i < data.Length; i++) + // { + // data[i] = 0f; // mute until start time cos PlaySchedule artifact. + // } + //} + + } +} diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index c8fbc7a..6a14b0d 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -407,7 +407,7 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti #endif FixOffsetTick(); - this.dspTimeSong = __instance.dspTime + (double) this.buffer; + this.dspTimeSong = __instance.dspTime + (double)this.buffer; if (__instance.fastTakeoff) { this.dspTimeSong -= (double)__instance.crotchetAtStart * __instance.countdownTicks / __instance.song.pitch; @@ -415,39 +415,51 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti double countdownTime = __instance.separateCountdownTime ? (__instance.crotchetAtStart * __instance.countdownTicks) : 0.0; - if (GCS.checkpointNum != 0) - { - this.dspTimeSong = __instance.dspTime - countdownTime / __instance.song.pitch + this.buffer; - } + double time = this.dspTimeSong + countdownTime / __instance.song.pitch; __instance.song.UnPause(); __instance.song.PlayScheduled(time); __instance.song2?.PlayScheduled(time); + if (GCS.checkpointNum != 0) { double entryTime = __instance.lm.listFloors[FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor)].entryTime; + yield return null; + AudioListener.pause = true; + this.dspTimeSong = __instance.dspTime - countdownTime / __instance.song.pitch; + __instance.song.SetScheduledStartTime(this.dspTimeSong + countdownTime / __instance.song.pitch); double destTime = entryTime + __instance.addoffset - countdownTime; this.dspTimeSong -= destTime / __instance.song.pitch; - __instance.song.time = (float) destTime; - + __instance.song.time = (float)destTime; + __instance.lastHit = entryTime; } + else + { + yield return null; + + AudioListener.pause = true; + __instance.song.SetScheduledStartTime(time); + __instance.song2?.SetScheduledStartTime(time); + + } double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / __instance.song.pitch; this.PlayHitTimes(__instance, hitSoundPlayFrom); __instance.hasSongStarted = true; - onSongScheduled?.Invoke(); #if DEBUG NoStopMod.mod.Logger.Log("call From StartMusicCo Third"); #endif FixOffsetTick(); + onSongScheduled?.Invoke(); yield return null; FixOffsetTick(); + AudioListener.pause = false; yield return new WaitForSeconds(4f); while (__instance.song.isPlaying) @@ -458,8 +470,7 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti yield break; } - - // Token: 0x060001CB RID: 459 RVA: 0x0000D155 File Offset: 0x0000B355 + public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstarttime) { //NoStopMod.mod.Logger.Log("ToggleHasSongStarted"); @@ -483,8 +494,7 @@ public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstar //} yield break; } - - // Token: 0x060001CC RID: 460 RVA: 0x0000D16C File Offset: 0x0000B36C + public void Update(scrConductor __instance) { RDInput.Update(); @@ -572,16 +582,6 @@ public void Update(scrConductor __instance) float pitch = __instance.song.pitch; double num3 = __instance.addoffset; } - //if (GCS.d_calibration) - //{ - // if (!(__instance.editor == null)) - // { - // if (__instance.editor != null) - // { - // bool flag = !__instance.controller.paused; - // } - // } - //} if (__instance.getSpectrum && !GCS.lofiVersion) { @@ -692,11 +692,7 @@ public IEnumerator DesyncFix(scrConductor __instance) // Token: 0x060001D7 RID: 471 RVA: 0x0000D89B File Offset: 0x0000BA9B private int GetOffsetChange(bool fine) { - if (!fine) - { - return 10; - } - return 1; + return fine ? 1 : 10; } // Token: 0x060001DC RID: 476 RVA: 0x0000D91C File Offset: 0x0000BB1C @@ -751,6 +747,3 @@ public void SaveVisualOffset(double offset) } } - - - diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 79edc58..d21977f 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -367,6 +367,7 @@ + From d01330dad6a2832d12ad4b87ee59866071c8a91f Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 10:50:21 +0900 Subject: [PATCH 46/67] Refactor: Simplify StartMusicCo --- InputFixer/SyncFixer/newScrConductor.cs | 42 +++++++++---------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 6a14b0d..8510c32 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -407,44 +407,32 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti #endif FixOffsetTick(); - this.dspTimeSong = __instance.dspTime + (double)this.buffer; + double countdownTime = __instance.crotchetAtStart * __instance.countdownTicks; + double separatedCountdownTime = __instance.separateCountdownTime ? countdownTime : 0.0; + + this.dspTimeSong = __instance.dspTime + this.buffer; if (__instance.fastTakeoff) { - this.dspTimeSong -= (double)__instance.crotchetAtStart * __instance.countdownTicks / __instance.song.pitch; + this.dspTimeSong -= countdownTime / __instance.song.pitch; } - - double countdownTime = __instance.separateCountdownTime ? (__instance.crotchetAtStart * __instance.countdownTicks) : 0.0; - - double time = this.dspTimeSong + countdownTime / __instance.song.pitch; + double time = this.dspTimeSong + separatedCountdownTime / __instance.song.pitch; __instance.song.UnPause(); __instance.song.PlayScheduled(time); __instance.song2?.PlayScheduled(time); - if (GCS.checkpointNum != 0) { - double entryTime = __instance.lm.listFloors[FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor)].entryTime; - yield return null; AudioListener.pause = true; - this.dspTimeSong = __instance.dspTime - countdownTime / __instance.song.pitch; - __instance.song.SetScheduledStartTime(this.dspTimeSong + countdownTime / __instance.song.pitch); - double destTime = entryTime + __instance.addoffset - countdownTime; - this.dspTimeSong -= destTime / __instance.song.pitch; - __instance.song.time = (float)destTime; + __instance.song.SetScheduledStartTime(__instance.dspTime); + double entryTime = __instance.lm.listFloors[FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor)].entryTime; + __instance.lastHit = entryTime; - } - else - { - yield return null; - - AudioListener.pause = true; - __instance.song.SetScheduledStartTime(time); - __instance.song2?.SetScheduledStartTime(time); - + __instance.song.time = (float) (entryTime + __instance.addoffset - separatedCountdownTime); + this.dspTimeSong = __instance.dspTime - (entryTime + __instance.addoffset) / __instance.song.pitch; } double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / __instance.song.pitch; @@ -452,14 +440,14 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti __instance.hasSongStarted = true; + onSongScheduled?.Invoke(); + + yield return null; + AudioListener.pause = false; #if DEBUG NoStopMod.mod.Logger.Log("call From StartMusicCo Third"); #endif FixOffsetTick(); - onSongScheduled?.Invoke(); - yield return null; - FixOffsetTick(); - AudioListener.pause = false; yield return new WaitForSeconds(4f); while (__instance.song.isPlaying) From bb54d22c8511eba10057459394ce5b5bbdb8b524 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 11:22:21 +0900 Subject: [PATCH 47/67] Feat: Fix Adofai's in editor song bugs --- EditorSongFixer/EditorSongFixerManager.cs | 24 +++++++++++++++ EditorSongFixer/EditorSongFixerPatches.cs | 37 +++++++++++++++++++++++ InputFixer/SyncFixer/SyncFixerManager.cs | 8 +---- NoStopMod.csproj | 2 ++ 4 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 EditorSongFixer/EditorSongFixerManager.cs create mode 100644 EditorSongFixer/EditorSongFixerPatches.cs diff --git a/EditorSongFixer/EditorSongFixerManager.cs b/EditorSongFixer/EditorSongFixerManager.cs new file mode 100644 index 0000000..ce320dd --- /dev/null +++ b/EditorSongFixer/EditorSongFixerManager.cs @@ -0,0 +1,24 @@ +using System.Reflection; + +namespace NoStopMod.EditorSongFixer +{ + class EditorSongFixerManager + { + + private static FieldInfo scnEditorCurrentSongKeyInfo_; + + public static FieldInfo scnEditorCurrentSongKeyInfo + { + get + { + if (scnEditorCurrentSongKeyInfo_ == null) + { + scnEditorCurrentSongKeyInfo_ = CustomLevel.instance?.GetType() + .GetField("currentSongKey", BindingFlags.NonPublic | BindingFlags.Instance); + } + return scnEditorCurrentSongKeyInfo_; + } + } + + } +} diff --git a/EditorSongFixer/EditorSongFixerPatches.cs b/EditorSongFixer/EditorSongFixerPatches.cs new file mode 100644 index 0000000..78fe8c6 --- /dev/null +++ b/EditorSongFixer/EditorSongFixerPatches.cs @@ -0,0 +1,37 @@ +using HarmonyLib; +using NoStopMod.EditorSongFixer; + +namespace NoStopMod.InputFixer.SyncFixer +{ + class SyncFixerPatchesScnEditor + { + + /** + * Author: PatricKR + * + */ + [HarmonyPatch(typeof(scnEditor), "SwitchToEditMode")] + private static class scnEditor_SwitchToEditMode_Patch + { + private static void Prefix(scnEditor __instance) + { + __instance.conductor.song.Stop(); + AudioManager.Instance.StopAllSounds(); + } + } + + /** + * Author: PERIOT + * + */ + [HarmonyPatch(typeof(scnEditor), "OpenLevelCo")] + private static class scnEditor_OpenLevelCo_Patch + { + private static void Prefix(scnEditor __instance) + { + EditorSongFixerManager.scnEditorCurrentSongKeyInfo?.SetValue(CustomLevel.instance, null); + } + } + + } +} diff --git a/InputFixer/SyncFixer/SyncFixerManager.cs b/InputFixer/SyncFixer/SyncFixerManager.cs index 06a8ea6..79602cc 100644 --- a/InputFixer/SyncFixer/SyncFixerManager.cs +++ b/InputFixer/SyncFixer/SyncFixerManager.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NoStopMod.InputFixer.SyncFixer +namespace NoStopMod.InputFixer.SyncFixer { class SyncFixerManager { diff --git a/NoStopMod.csproj b/NoStopMod.csproj index d21977f..17db399 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -352,6 +352,7 @@ + @@ -368,6 +369,7 @@ + From 78c12b8c4fddc31f081db1bd981c6468173d3bf0 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 11:27:21 +0900 Subject: [PATCH 48/67] Doc: Update Version to 1.2.2 --- Info.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Info.json b/Info.json index 1009b84..c938082 100644 --- a/Info.json +++ b/Info.json @@ -2,7 +2,7 @@ "Id": "NoStopMod", "DisplayName": "NoStopMod", "Author": "Luxus", - "Version": "1.2.1", + "Version": "1.2.2", "ManagerVersion": "0.23.4.0", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load" From fab5f9dae356b2f3e3d50759bf540ad7d589a9c8 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 12:16:53 +0900 Subject: [PATCH 49/67] Feat: Support Beta(r74) version --- .../SyncFixer/SyncFixerPatchesScrConductor.cs | 18 ++--- InputFixer/SyncFixer/newScrConductor.cs | 74 ++++++++++--------- 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs index 75aa6f4..1e1cc27 100644 --- a/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs +++ b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs @@ -114,15 +114,15 @@ public static bool Prefix(scrConductor __instance) } } - [HarmonyPatch(typeof(scrConductor), "OnBeat")] - private static class scrConductor_OnBeat_Patch - { - public static bool Prefix(scrConductor __instance) - { - SyncFixerManager.newScrConductor.OnBeat(__instance); - return false; - } - } + //[HarmonyPatch(typeof(scrConductor), "OnBeat")] + //private static class scrConductor_OnBeat_Patch + //{ + // public static bool Prefix(scrConductor __instance) + // { + // SyncFixerManager.newScrConductor.OnBeat(__instance); + // return false; + // } + //} [HarmonyPatch(typeof(scrConductor), "PlaySfx")] private static class scrConductor_PlaySfx_Patch diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 8510c32..acb5e95 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -37,10 +37,12 @@ dspTime update public long dspTick; + public double dspTime; + public void FixOffsetTick() { - offsetTick = NoStopMod.CurrFrameTick() - (long)(instance.dspTime * 10000000); + offsetTick = NoStopMod.CurrFrameTick() - (long)(this.dspTime * 10000000); #if DEBUG NoStopMod.mod.Logger.Log("FixOffsetTick"); #endif @@ -236,7 +238,7 @@ public void Start(scrConductor __instance) __instance.txtOffset.text = ""; } this.lastReportedPlayheadPosition = AudioSettings.dspTime; - __instance.dspTime = AudioSettings.dspTime; + this.dspTime = AudioSettings.dspTime; #if DEBUG NoStopMod.mod.Logger.Log("CallFrom Start"); #endif @@ -272,7 +274,7 @@ public void Rewind(scrConductor __instance) this.dspTimeSong = 0.0; __instance.lastHit = 0.0; this.lastReportedPlayheadPosition = AudioSettings.dspTime; - __instance.dspTime = AudioSettings.dspTime; + this.dspTime = AudioSettings.dspTime; #if DEBUG NoStopMod.mod.Logger.Log("callFrom Rewind"); #endif @@ -334,7 +336,7 @@ public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) } double hitsoundOffset = (hitSound == HitSound.Shaker || hitSound == HitSound.ShakerLoud) ? 0.015 : 0.0; double time = hitsoundPlayFrom + scrFloor.entryTimePitchAdj - hitsoundOffset; - if (i >= num && time > __instance.dspTime && !scrFloor.midSpin && hitSound != HitSound.None) + if (i >= num && time > this.dspTime && !scrFloor.midSpin && hitSound != HitSound.None) { HitSoundsData item = new HitSoundsData(hitSound, time, volume); this.hitSoundsData.Add(item); @@ -349,7 +351,7 @@ public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) for (int j = 0; j < __instance.countdownTicks; j++) { double countdownTime = this.GetCountdownTime(__instance, j); - if (countdownTime > __instance.dspTime) + if (countdownTime > this.dspTime) { __instance.countdownTimes[j] = countdownTime; AudioManager.Play("sndHat", countdownTime, __instance.hitSoundVolume, 10); @@ -389,19 +391,19 @@ public void StartMusic(scrConductor __instance, Action onComplete = null, Action // Token: 0x060001CA RID: 458 RVA: 0x0000D138 File Offset: 0x0000B338 public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Action onSongScheduled = null) { - __instance.dspTime = AudioSettings.dspTime; + this.dspTime = AudioSettings.dspTime; #if DEBUG NoStopMod.mod.Logger.Log("call From StartMusicCo First"); #endif FixOffsetTick(); - this.dspTimeSong = __instance.dspTime + (double)this.buffer + 0.1f; + this.dspTimeSong = this.dspTime + (double)this.buffer + 0.1f; for (float timer = 0.1f; timer >= 0f; timer -= Time.deltaTime) { yield return null; } - __instance.dspTime = AudioSettings.dspTime; + this.dspTime = AudioSettings.dspTime; #if DEBUG NoStopMod.mod.Logger.Log("call From StartMusicCo Second"); #endif @@ -410,7 +412,7 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti double countdownTime = __instance.crotchetAtStart * __instance.countdownTicks; double separatedCountdownTime = __instance.separateCountdownTime ? countdownTime : 0.0; - this.dspTimeSong = __instance.dspTime + this.buffer; + this.dspTimeSong = this.dspTime + this.buffer; if (__instance.fastTakeoff) { this.dspTimeSong -= countdownTime / __instance.song.pitch; @@ -426,13 +428,13 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti { yield return null; AudioListener.pause = true; - __instance.song.SetScheduledStartTime(__instance.dspTime); + __instance.song.SetScheduledStartTime(this.dspTime); double entryTime = __instance.lm.listFloors[FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor)].entryTime; __instance.lastHit = entryTime; __instance.song.time = (float) (entryTime + __instance.addoffset - separatedCountdownTime); - this.dspTimeSong = __instance.dspTime - (entryTime + __instance.addoffset) / __instance.song.pitch; + this.dspTimeSong = this.dspTime - (entryTime + __instance.addoffset) / __instance.song.pitch; } double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / __instance.song.pitch; @@ -499,7 +501,7 @@ public void Update(scrConductor __instance) } else { - __instance.dspTime += Time.unscaledTime - this.previousFrameTime; + this.dspTime += Time.unscaledTime - this.previousFrameTime; dspTick = NoStopMod.CurrFrameTick() - offsetTick; #if DEBUG NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + (dspTick / 10000000.0) + "diff(" + (__instance.dspTime - (dspTick / 10000000.0)) + ")"); @@ -509,7 +511,7 @@ public void Update(scrConductor __instance) this.previousFrameTime = Time.unscaledTime; if (AudioSettings.dspTime != this.lastReportedPlayheadPosition) { - __instance.dspTime = AudioSettings.dspTime; + this.dspTime = AudioSettings.dspTime; this.lastReportedPlayheadPosition = AudioSettings.dspTime; } @@ -518,7 +520,7 @@ public void Update(scrConductor __instance) while (this.nextHitSoundToSchedule < this.hitSoundsData.Count) { HitSoundsData hitSoundsData = this.hitSoundsData[this.nextHitSoundToSchedule]; - if (__instance.dspTime + 5.0 <= hitSoundsData.time) + if (this.dspTime + 5.0 <= hitSoundsData.time) { break; } @@ -586,28 +588,28 @@ public void Update(scrConductor __instance) } } - public void OnBeat(scrConductor __instance) - { - List onBeats = __instance.onBeats; - if (onBeats == null) - { - return; - } - int count = onBeats.Count; - for (int i = 0; i < count; i++) - { - onBeats[i].OnBeat(); - } - if (__instance.controller != null && __instance.controller.gameworld) - { - List listFloors = __instance.controller.lm.listFloors; - int count2 = listFloors.Count; - for (int j = 0; j < count2; j++) - { - listFloors[j].OnBeat(); - } - } - } + //public void OnBeat(scrConductor __instance) + //{ + // List onBeats = __instance.onBeats; + // if (onBeats == null) + // { + // return; + // } + // int count = onBeats.Count; + // for (int i = 0; i < count; i++) + // { + // onBeats[i].OnBeat(); + // } + // if (__instance.controller != null && __instance.controller.gameworld) + // { + // List listFloors = __instance.controller.lm.listFloors; + // int count2 = listFloors.Count; + // for (int j = 0; j < count2; j++) + // { + // listFloors[j].OnBeat(); + // } + // } + //} // Token: 0x060001CE RID: 462 RVA: 0x0000D555 File Offset: 0x0000B755 public void PlaySfx(scrConductor __instance, int num, float volume = 1f, bool ignoreListenerPause = false) From ac970a9f7b78836ff498f7149758cabface1a35e Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 13:04:07 +0900 Subject: [PATCH 50/67] Feat: Make ReflectionField for easy, multiple field names reflection --- Helper/ReflectionField.cs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Helper/ReflectionField.cs diff --git a/Helper/ReflectionField.cs b/Helper/ReflectionField.cs new file mode 100644 index 0000000..aeccda5 --- /dev/null +++ b/Helper/ReflectionField.cs @@ -0,0 +1,32 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace NoStopMod.Helper +{ + class ReflectionField + { + private static FieldInfo fi; + + private string[] fieldNames; + + public ReflectionField(params string[] fieldNames) + { + this.fieldNames = fieldNames; + } + + public FieldInfo getFieldInfo(Type type) + { + if (fi == null) + { + for (int i=0;i < fieldNames.Count();i++) + { + fi = type.GetField(fieldNames[i], BindingFlags.NonPublic | BindingFlags.Instance); + if (fi != null) break; + } + } + return fi; + } + + } +} From df77cec8f0f470b97d9376a04bf118a42e33e188 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 13:58:00 +0900 Subject: [PATCH 51/67] Feat: Support Release(r71) version --- EditorSongFixer/EditorSongFixerManager.cs | 18 ++----- EditorSongFixer/EditorSongFixerPatches.cs | 3 +- Helper/ReflectionField.cs | 22 ++++++-- InputFixer/SyncFixer/SyncFixerManager.cs | 6 ++- .../SyncFixer/SyncFixerPatchesScrConductor.cs | 18 +++---- InputFixer/SyncFixer/newScrConductor.cs | 52 ++++++++++++------- NoStopMod.csproj | 1 + 7 files changed, 71 insertions(+), 49 deletions(-) diff --git a/EditorSongFixer/EditorSongFixerManager.cs b/EditorSongFixer/EditorSongFixerManager.cs index ce320dd..e709de7 100644 --- a/EditorSongFixer/EditorSongFixerManager.cs +++ b/EditorSongFixer/EditorSongFixerManager.cs @@ -1,24 +1,12 @@ -using System.Reflection; +using NoStopMod.Helper; +using System.Reflection; namespace NoStopMod.EditorSongFixer { class EditorSongFixerManager { - private static FieldInfo scnEditorCurrentSongKeyInfo_; - - public static FieldInfo scnEditorCurrentSongKeyInfo - { - get - { - if (scnEditorCurrentSongKeyInfo_ == null) - { - scnEditorCurrentSongKeyInfo_ = CustomLevel.instance?.GetType() - .GetField("currentSongKey", BindingFlags.NonPublic | BindingFlags.Instance); - } - return scnEditorCurrentSongKeyInfo_; - } - } + public static ReflectionField scnEditorCurrentSongKey = new ReflectionField("currentSongKey"); } } diff --git a/EditorSongFixer/EditorSongFixerPatches.cs b/EditorSongFixer/EditorSongFixerPatches.cs index 78fe8c6..eefffc3 100644 --- a/EditorSongFixer/EditorSongFixerPatches.cs +++ b/EditorSongFixer/EditorSongFixerPatches.cs @@ -29,7 +29,8 @@ private static class scnEditor_OpenLevelCo_Patch { private static void Prefix(scnEditor __instance) { - EditorSongFixerManager.scnEditorCurrentSongKeyInfo?.SetValue(CustomLevel.instance, null); + EditorSongFixerManager.scnEditorCurrentSongKey + .SetValue(CustomLevel.instance, null); } } diff --git a/Helper/ReflectionField.cs b/Helper/ReflectionField.cs index aeccda5..12915ab 100644 --- a/Helper/ReflectionField.cs +++ b/Helper/ReflectionField.cs @@ -4,7 +4,7 @@ namespace NoStopMod.Helper { - class ReflectionField + public class ReflectionField { private static FieldInfo fi; @@ -15,18 +15,34 @@ public ReflectionField(params string[] fieldNames) this.fieldNames = fieldNames; } - public FieldInfo getFieldInfo(Type type) + public FieldInfo GetFieldInfo(Type type) { if (fi == null) { for (int i=0;i < fieldNames.Count();i++) { - fi = type.GetField(fieldNames[i], BindingFlags.NonPublic | BindingFlags.Instance); + fi = type.GetField(fieldNames[i], + BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); if (fi != null) break; } + if (fi == null) + { + NoStopMod.mod.Logger.Error("Cannot find fieldInfo : (type=" + type + ", name" + fieldNames + ")"); + } } return fi; } + public void SetValue(object obj, T value) + { + GetFieldInfo(obj.GetType())?.SetValue(obj, value); + } + + public T GetValue(object obj) + { + return (T) GetFieldInfo(obj.GetType())?.GetValue(obj); + } + } } diff --git a/InputFixer/SyncFixer/SyncFixerManager.cs b/InputFixer/SyncFixer/SyncFixerManager.cs index 79602cc..d5fa08f 100644 --- a/InputFixer/SyncFixer/SyncFixerManager.cs +++ b/InputFixer/SyncFixer/SyncFixerManager.cs @@ -8,7 +8,11 @@ class SyncFixerManager public static void Init() { newScrConductor = new newScrConductor(); - if (newScrConductor.instance != null) newScrConductor.FixOffsetTick(); + if (scrConductor.instance != null) + { + newScrConductor.dspTime = newScrConductor.dspTimeField.GetValue(scrConductor.instance); + newScrConductor.FixOffsetTick(); + } } } diff --git a/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs index 1e1cc27..48877ff 100644 --- a/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs +++ b/InputFixer/SyncFixer/SyncFixerPatchesScrConductor.cs @@ -44,15 +44,15 @@ public static bool Prefix(scrConductor __instance) } } - [HarmonyPatch(typeof(scrConductor), "SetupConductorWithLevelData")] - private static class scrConductor_SetupConductorWithLevelData_Patch - { - public static bool Prefix(scrConductor __instance, LevelData levelData) - { - SyncFixerManager.newScrConductor.SetupConductorWithLevelData(__instance, levelData); - return false; - } - } + //[HarmonyPatch(typeof(scrConductor), "SetupConductorWithLevelData")] + //private static class scrConductor_SetupConductorWithLevelData_Patch + //{ + // public static bool Prefix(scrConductor __instance, LevelData levelData) + // { + // SyncFixerManager.newScrConductor.SetupConductorWithLevelData(__instance, levelData); + // return false; + // } + //} //[HarmonyPatch(typeof(scrConductor), "PlayHitTimes")] //private static class scrConductor_PlayHitTimes_Patch diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index acb5e95..04ab032 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -1,6 +1,7 @@ using ADOFAI; using DG.Tweening; using HarmonyLib; +using NoStopMod.Helper; using RDTools; using System; using System.Collections; @@ -22,7 +23,7 @@ class newScrConductor // to fix Desync bug, I replaced AudioSettings.dspTime to DateTime.Now.Ticks // I hope this mechanism work well. - + /* dspTime update @@ -38,7 +39,8 @@ dspTime update public long dspTick; public double dspTime; - + + public static ReflectionField dspTimeField = new ReflectionField("dspTime", "_dspTime"); public void FixOffsetTick() { @@ -81,6 +83,10 @@ public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDon } + + + + // Original Code // Token: 0x04000288 RID: 648 @@ -284,23 +290,23 @@ public void Rewind(scrConductor __instance) } // Token: 0x060001C6 RID: 454 RVA: 0x0000CD24 File Offset: 0x0000AF24 - public void SetupConductorWithLevelData(scrConductor __instance, LevelData levelData) - { - __instance.bpm = levelData.bpm; - __instance.crotchet = (double)(60f / __instance.bpm); - __instance.crotchetAtStart = __instance.crotchet; - __instance.addoffset = (double)((float)levelData.offset * 0.001f); - __instance.song.volume = (float)levelData.volume * 0.01f; - __instance.hitSoundVolume = (float)levelData.hitsoundVolume * 0.01f; - __instance.hitSound = levelData.hitsound; - __instance.separateCountdownTime = levelData.separateCountdownTime; - float num = (float)levelData.pitch * 0.01f; - if (GCS.standaloneLevelMode) - { - num *= GCS.currentSpeedRun; - } - __instance.song.pitch = num; - } + //public void SetupConductorWithLevelData(scrConductor __instance, LevelData levelData) + //{ + // __instance.bpm = levelData.bpm; + // __instance.crotchet = (double)(60f / __instance.bpm); + // __instance.crotchetAtStart = __instance.crotchet; + // __instance.addoffset = (double)((float)levelData.offset * 0.001f); + // __instance.song.volume = (float)levelData.volume * 0.01f; + // __instance.hitSoundVolume = (float)levelData.hitsoundVolume * 0.01f; + // __instance.hitSound = levelData.hitsound; + // __instance.separateCountdownTime = levelData.separateCountdownTime; + // float num = (float)levelData.pitch * 0.01f; + // if (GCS.standaloneLevelMode) + // { + // num *= GCS.currentSpeedRun; + // } + // __instance.song.pitch = num; + //} // StartMusicCo, DesyncFix public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) @@ -328,7 +334,7 @@ public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) for (int i = 1; i < floorList.Count; i++) { scrFloor scrFloor = floorList[i]; - ffxSetHitsound setHitsound = scrFloor.setHitsound; + ffxSetHitsound setHitsound = scrFloor.GetComponent(); if (setHitsound != null) { hitSound = setHitsound.hitSound; @@ -436,9 +442,15 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti __instance.song.time = (float) (entryTime + __instance.addoffset - separatedCountdownTime); this.dspTimeSong = this.dspTime - (entryTime + __instance.addoffset) / __instance.song.pitch; } + //this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / __instance.song.pitch; this.PlayHitTimes(__instance, hitSoundPlayFrom); + + //dspTimeSongField.SetValue(__instance, this.dspTimeSong); + //dspTimeField.SetValue(__instance, this.dspTime); + //__instance.PlayHitTimes(); + __instance.hasSongStarted = true; diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 17db399..53a171f 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -356,6 +356,7 @@ + From dbdf31f668607276e0c15fc141a95b75db52c0bb Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 14:20:08 +0900 Subject: [PATCH 52/67] Fix: Fix hitsound bug. Fixed when play level in editor then play official level, editor level hitsounds plays --- InputFixer/SyncFixer/newScrConductor.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 04ab032..c3811b0 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -22,16 +22,13 @@ class newScrConductor // Note : this class replaces scrController in ADOFAI. // to fix Desync bug, I replaced AudioSettings.dspTime to DateTime.Now.Ticks // I hope this mechanism work well. - - /* dspTime update Start() Rewind() Update() */ - // a // new code public long offsetTick; @@ -311,6 +308,7 @@ public void Rewind(scrConductor __instance) // StartMusicCo, DesyncFix public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) { + this.hitSoundsData = new List(); if (this.playedHitSounds) { AudioManager.Instance.StopAllSounds(); @@ -329,7 +327,6 @@ public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) int num = (GCS.checkpointNum < floorList.Count && GCS.usingCheckpoints) ? (GCS.checkpointNum + 1) : 1; //double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; - this.hitSoundsData = new List(); this.nextHitSoundToSchedule = 0; for (int i = 1; i < floorList.Count; i++) { @@ -443,6 +440,8 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti this.dspTimeSong = this.dspTime - (entryTime + __instance.addoffset) / __instance.song.pitch; } //this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch + + onSongScheduled?.Invoke(); double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / __instance.song.pitch; this.PlayHitTimes(__instance, hitSoundPlayFrom); @@ -454,7 +453,6 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti __instance.hasSongStarted = true; - onSongScheduled?.Invoke(); yield return null; AudioListener.pause = false; From f079369b00671974b67f8f0b8a7c9d7197d3eeae Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 15:20:40 +0900 Subject: [PATCH 53/67] Feat: Support auto update notifier --- Info.json | 2 ++ Repository.json | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 Repository.json diff --git a/Info.json b/Info.json index c938082..6d3d261 100644 --- a/Info.json +++ b/Info.json @@ -6,4 +6,6 @@ "ManagerVersion": "0.23.4.0", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load" + "HomePage": "https://github.com/Luxusio/ADOFAI-NoStopMod", + "Repository": "https://raw.githubusercontent.com/Luxusio/ADOFAI-NoStopMod/master/Repository.json" } diff --git a/Repository.json b/Repository.json new file mode 100644 index 0000000..3748cac --- /dev/null +++ b/Repository.json @@ -0,0 +1,9 @@ +{ + "Releases": [ + { + "Id": "NoStopMod", + "Version": "1.2.2", + "DownloadUrl": "https://github.com/Luxusio/ADOFAI-NoStopMod/releases/download/1.2.2/NoStopMod-1.2.2.zip" + } + ] +} \ No newline at end of file From 2f932060d0f00f695e3bb6f76d1965eadbac7db9 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 24 Jun 2021 15:28:02 +0900 Subject: [PATCH 54/67] Doc: Fix json format error --- Info.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Info.json b/Info.json index 6d3d261..aaad000 100644 --- a/Info.json +++ b/Info.json @@ -5,7 +5,7 @@ "Version": "1.2.2", "ManagerVersion": "0.23.4.0", "AssemblyName": "NoStopMod.dll", - "EntryMethod": "NoStopMod.NoStopMod.Load" + "EntryMethod": "NoStopMod.NoStopMod.Load", "HomePage": "https://github.com/Luxusio/ADOFAI-NoStopMod", "Repository": "https://raw.githubusercontent.com/Luxusio/ADOFAI-NoStopMod/master/Repository.json" } From e800ba6840374c97be25df39bc3a488cf0337d35 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 25 Jun 2021 10:40:41 +0900 Subject: [PATCH 55/67] Feat: Now planet rotation works more native. --- InputFixer/SyncFixer/newScrConductor.cs | 49 +++++++------------------ 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index c3811b0..1acccfe 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -1,18 +1,10 @@ -using ADOFAI; -using DG.Tweening; -using HarmonyLib; -using NoStopMod.Helper; +using NoStopMod.Helper; using RDTools; using System; using System.Collections; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; - - namespace NoStopMod.InputFixer.SyncFixer { @@ -22,7 +14,7 @@ class newScrConductor // Note : this class replaces scrController in ADOFAI. // to fix Desync bug, I replaced AudioSettings.dspTime to DateTime.Now.Ticks // I hope this mechanism work well. - + /* dspTime update Start() @@ -36,7 +28,7 @@ dspTime update public long dspTick; public double dspTime; - + public static ReflectionField dspTimeField = new ReflectionField("dspTime", "_dspTime"); public void FixOffsetTick() @@ -79,11 +71,7 @@ public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDon return result; } - - - - - + // Original Code // Token: 0x04000288 RID: 648 @@ -414,19 +402,19 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti double countdownTime = __instance.crotchetAtStart * __instance.countdownTicks; double separatedCountdownTime = __instance.separateCountdownTime ? countdownTime : 0.0; - + this.dspTimeSong = this.dspTime + this.buffer; if (__instance.fastTakeoff) { this.dspTimeSong -= countdownTime / __instance.song.pitch; } - + double time = this.dspTimeSong + separatedCountdownTime / __instance.song.pitch; __instance.song.UnPause(); __instance.song.PlayScheduled(time); __instance.song2?.PlayScheduled(time); - + if (GCS.checkpointNum != 0) { yield return null; @@ -434,32 +422,20 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti __instance.song.SetScheduledStartTime(this.dspTime); double entryTime = __instance.lm.listFloors[FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor)].entryTime; - + __instance.lastHit = entryTime; - __instance.song.time = (float) (entryTime + __instance.addoffset - separatedCountdownTime); + __instance.song.time = (float)(entryTime + __instance.addoffset - separatedCountdownTime); this.dspTimeSong = this.dspTime - (entryTime + __instance.addoffset) / __instance.song.pitch; } - //this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch - onSongScheduled?.Invoke(); double hitSoundPlayFrom = this.dspTimeSong + __instance.addoffset / __instance.song.pitch; this.PlayHitTimes(__instance, hitSoundPlayFrom); - - //dspTimeSongField.SetValue(__instance, this.dspTimeSong); - //dspTimeField.SetValue(__instance, this.dspTime); - //__instance.PlayHitTimes(); - + __instance.hasSongStarted = true; - - yield return null; AudioListener.pause = false; -#if DEBUG - NoStopMod.mod.Logger.Log("call From StartMusicCo Third"); -#endif - FixOffsetTick(); yield return new WaitForSeconds(4f); while (__instance.song.isPlaying) @@ -470,7 +446,7 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti yield break; } - + public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstarttime) { //NoStopMod.mod.Logger.Log("ToggleHasSongStarted"); @@ -494,7 +470,7 @@ public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstar //} yield break; } - + public void Update(scrConductor __instance) { RDInput.Update(); @@ -523,6 +499,7 @@ public void Update(scrConductor __instance) { this.dspTime = AudioSettings.dspTime; this.lastReportedPlayheadPosition = AudioSettings.dspTime; + FixOffsetTick(); } if (__instance.hasSongStarted && __instance.isGameWorld && (scrController.States)__instance.controller.GetState() != scrController.States.Fail && (scrController.States)__instance.controller.GetState() != scrController.States.Fail2) From 54f77f6b2312a804731b48021105dd2c29193f93 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 25 Jun 2021 10:44:07 +0900 Subject: [PATCH 56/67] Refactor: Remove unnecessary codes. --- InputFixer/SyncFixer/newScrConductor.cs | 195 +++++------------------- 1 file changed, 35 insertions(+), 160 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 1acccfe..701fd69 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -73,59 +73,38 @@ public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDon // Original Code - - // Token: 0x04000288 RID: 648 public List hitSoundsData = new List(); - - // Token: 0x04000289 RID: 649 + public int nextHitSoundToSchedule; - - // Token: 0x0400028A RID: 650 + public int crotchetsPerBar = 8; - - - // Token: 0x0400028D RID: 653 + //public double _songposition_minusi; - - // Token: 0x0400028E RID: 654 + public double previousFrameTime; - - // Token: 0x0400028F RID: 655 + public double lastReportedPlayheadPosition; - - - // Token: 0x04000294 RID: 660 + public double nextBeatTime; - - // Token: 0x04000295 RID: 661 + public double nextBarTime; - - - // Token: 0x04000299 RID: 665 + public float buffer = 1f; - - // Token: 0x0400029D RID: 669 + public float[] _spectrum = new float[1024]; - - // Token: 0x0400029F RID: 671 - public AudioSource audiosource; - - // Token: 0x040002A0 RID: 672 + + //public AudioSource audiosource; + public bool playedHitSounds; - - // Token: 0x040002A1 RID: 673 - public scrConductor.DuckState _duckState; - - // Token: 0x040002A2 RID: 674 - public float songPreduckVolume; - - // Token: 0x040002A3 RID: 675 - public float song2PreduckVolume; - - // Token: 0x040002A6 RID: 678 + + //public scrConductor.DuckState _duckState; + + //public float songPreduckVolume; + + //public float song2PreduckVolume; + public double dspTimeSong; - - // Token: 0x040002A8 RID: 680 + public List _onBeats = new List(); public static scrConductor instance @@ -139,16 +118,13 @@ public static scrConductor instance return newScrConductor._instance; } } - - // Token: 0x040002A9 RID: 681 + private static scrConductor _instance; - - // Token: 0x040002AA RID: 682 + public Coroutine startMusicCoroutine; public struct HitSoundsData { - // Token: 0x06000CE9 RID: 3305 RVA: 0x0005342A File Offset: 0x0005162A public HitSoundsData(HitSound hitSound, double time, float volume) { this.hitSound = hitSound; @@ -156,17 +132,10 @@ public HitSoundsData(HitSound hitSound, double time, float volume) this.volume = volume; this.played = false; } - - // Token: 0x04000FCC RID: 4044 + public HitSound hitSound; - - // Token: 0x04000FCD RID: 4045 public double time; - - // Token: 0x04000FCE RID: 4046 public float volume; - - // Token: 0x04000FCF RID: 4047 public bool played; } @@ -245,8 +214,7 @@ public void Start(scrConductor __instance) } } - - // Token: 0x060001C5 RID: 453 RVA: 0x0000CC64 File Offset: 0x0000AE64 + public void Rewind(scrConductor __instance) { __instance.tick = null; @@ -273,8 +241,7 @@ public void Rewind(scrConductor __instance) this.previousFrameTime = (double)Time.unscaledTime; } - - // Token: 0x060001C6 RID: 454 RVA: 0x0000CD24 File Offset: 0x0000AF24 + //public void SetupConductorWithLevelData(scrConductor __instance, LevelData levelData) //{ // __instance.bpm = levelData.bpm; @@ -313,7 +280,6 @@ public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) float volume = __instance.hitSoundVolume; List floorList = __instance.lm.listFloors; int num = (GCS.checkpointNum < floorList.Count && GCS.usingCheckpoints) ? (GCS.checkpointNum + 1) : 1; - //double num2 = this.dspTimeSong + __instance.addoffset / (double)__instance.song.pitch; this.nextHitSoundToSchedule = 0; for (int i = 1; i < floorList.Count; i++) @@ -356,8 +322,7 @@ public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) } } } - - // Token: 0x060001C8 RID: 456 RVA: 0x0000D028 File Offset: 0x0000B228 + public double GetCountdownTime(scrConductor __instance, int i) { if (GCS.checkpointNum != 0 && GCS.usingCheckpoints) @@ -367,19 +332,16 @@ public double GetCountdownTime(scrConductor __instance, int i) } return this.dspTimeSong + (double)i * __instance.crotchet / (double)__instance.song.pitch + __instance.addoffset / (double)__instance.song.pitch; } - - // Token: 0x060001C9 RID: 457 RVA: 0x0000D10E File Offset: 0x0000B30E + public void StartMusic(scrConductor __instance, Action onComplete = null, Action onSongScheduled = null) { if (this.startMusicCoroutine != null) { __instance.StopCoroutine(this.startMusicCoroutine); } - //AudioManager.Instance.StopAllSounds(); this.startMusicCoroutine = __instance.StartCoroutine(this.StartMusicCo(__instance, onComplete, onSongScheduled)); } - - // Token: 0x060001CA RID: 458 RVA: 0x0000D138 File Offset: 0x0000B338 + public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Action onSongScheduled = null) { this.dspTime = AudioSettings.dspTime; @@ -449,37 +411,12 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti public IEnumerator ToggleHasSongStarted(scrConductor __instance, double songstarttime) { - //NoStopMod.mod.Logger.Log("ToggleHasSongStarted"); - //if (GCS.d_webglConductor) - //{ - // __instance.song.volume = 0f; - //} - //while (scrConductor.instance.dspTime < songstarttime) - //{ - // yield return null; - //} - //__instance.hasSongStarted = true; - //scrDebugHUDMessage.Log("Song started forreal!"); - //if (GCS.d_webglConductor) - //{ - // yield return new WaitForSeconds(0.2f); - // __instance.song.Pause(); - // yield return new WaitForSeconds(0.1f); - // __instance.song.UnPause(); - // __instance.song.volume = 1f; - //} yield break; } public void Update(scrConductor __instance) { RDInput.Update(); - //if (!AudioListener.pause && Application.isFocused && Time.unscaledTime - this.previousFrameTime < 0.10000000149011612) - //{ - // __instance.dspTime += Time.unscaledTime - this.previousFrameTime; - // dspTick = NoStopMod.CurrFrameTick() - offsetTick; - // NoStopMod.mod.Logger.Log("dspTime : " + __instance.dspTime + ", " + (dspTick / 10000000.0)); - //} if (AudioListener.pause) { @@ -518,14 +455,6 @@ public void Update(scrConductor __instance) __instance.crotchet = (double)(60f / __instance.bpm); double prevSongposition_minusi = __instance.songposition_minusi; __instance.songposition_minusi = getSongPosition(__instance, dspTick); - //if (!GCS.d_oldConductor && !GCS.d_webglConductor) - //{ - // __instance.songposition_minusi = (double)((float)(__instance.dspTime - this.dspTimeSong - (double)scrConductor.calibration_i) * __instance.song.pitch) - __instance.addoffset; - //} - //else - //{ - // __instance.songposition_minusi = (double)(__instance.song.time - scrConductor.calibration_i) - __instance.addoffset / (double)__instance.song.pitch; - //} __instance.deltaSongPos = __instance.songposition_minusi - prevSongposition_minusi; __instance.deltaSongPos = Math.Max(__instance.deltaSongPos, 0.0); @@ -597,8 +526,7 @@ public void Update(scrConductor __instance) // } // } //} - - // Token: 0x060001CE RID: 462 RVA: 0x0000D555 File Offset: 0x0000B755 + public void PlaySfx(scrConductor __instance, int num, float volume = 1f, bool ignoreListenerPause = false) { if (num == 2) @@ -607,72 +535,21 @@ public void PlaySfx(scrConductor __instance, int num, float volume = 1f, bool ig } scrSfx.instance.Play(num, ignoreListenerPause, volume); } - - // Moved into startMusicCo + public void ScrubMusicToTile(scrConductor __instance, int tileID) { - //NoStopMod.mod.Logger.Log("ScrubMusicToTile"); - //AudioListener.pause = true; - //AudioManager.Instance.StopAllSounds(); - //__instance.song.SetScheduledStartTime(__instance.dspTime); - //double num = __instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0; - //__instance.song.time = (float)(__instance.lm.listFloors[tileID].entryTime + __instance.addoffset - num); - //this.dspTimeSong = __instance.dspTime - __instance.lm.listFloors[tileID].entryTimePitchAdj - __instance.addoffset / (double)__instance.song.pitch; - //__instance.lastHit = __instance.lm.listFloors[tileID].entryTime; - //__instance.StartCoroutine(this.DesyncFix(__instance)); } - - // Token: 0x060001D0 RID: 464 RVA: 0x0000D64B File Offset: 0x0000B84B + public IEnumerator DesyncFix(scrConductor __instance) { - //NoStopMod.mod.Logger.Log("DesyncFix"); - //int num; - //for (int framecounty = 2; framecounty > 0; framecounty = num - 1) - //{ - // yield return 0; - // num = framecounty; - //} - //AudioListener.pause = false; - //__instance.PlayHitTimes(); - - //int numberOfAttempts = 0; - //int framesToWait = 10; - //double maxDifference = 0.005; - //for (int i = 0; i < numberOfAttempts; i = num + 1) - //{ - // for (int framecount = framesToWait; framecount > 0; framecount = num - 1) - // { - // yield return 0; - // num = framecount; - // } - // if (__instance.song.isPlaying || __instance.song.clip == null) - // { - // yield break; - // } - // double num2 = (double)__instance.song.time + (__instance.separateCountdownTime ? (__instance.crotchetAtStart * (double)__instance.countdownTicks) : 0.0); - // double num3 = __instance.songposition_minusi + (double)(scrConductor.calibration_i * __instance.song.pitch) + __instance.addoffset; - // if (Math.Abs(num3 - num2) > maxDifference) - // { - // double num4 = num2 - num3; - // Debug.Log("Desync Fix Attempt: found difference " + num4); - // Debug.Log("Attempt " + i); - // Debug.Log("song time " + num2); - // Debug.Log("dsptime " + num3); - // this.dspTimeSong -= num4; - // __instance.PlayHitTimes(); - // } - // num = i; - //} yield break; } - - // Token: 0x060001D7 RID: 471 RVA: 0x0000D89B File Offset: 0x0000BA9B + private int GetOffsetChange(bool fine) { return fine ? 1 : 10; } - - // Token: 0x060001DC RID: 476 RVA: 0x0000D91C File Offset: 0x0000BB1C + public static void SaveCurrentPreset() { for (int i = 0; i < scrConductor.userPresets.Count; i++) @@ -690,16 +567,14 @@ public static void SaveCurrentPreset() scrConductor.userPresets.Add(scrConductor.currentPreset); } - - // Token: 0x060001E1 RID: 481 RVA: 0x0000DB61 File Offset: 0x0000BD61 + public void SaveVisualOffset(double offset) { Persistence.SetVisualOffset((float)offset); PlayerPrefs.SetFloat("offset_v", (float)offset); PlayerPrefs.Save(); } - - // Token: 0x060001E3 RID: 483 RVA: 0x0000DC98 File Offset: 0x0000BE98 + //public void LoadOnBeats() //{ // if (this._onBeats.Count != 0) From 3028699c8dbd20c92132dd2189f4c411b1ca744f Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 25 Jun 2021 11:47:00 +0900 Subject: [PATCH 57/67] Refactor: Remove unnecessary function call --- InputFixer/SyncFixer/newScrConductor.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 701fd69..514bfda 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -95,7 +95,7 @@ public int FindSongStartTile(scrConductor conductor, int floorNum, bool forceDon //public AudioSource audiosource; - public bool playedHitSounds; + //public bool playedHitSounds; //public scrConductor.DuckState _duckState; @@ -264,11 +264,11 @@ public void Rewind(scrConductor __instance) public void PlayHitTimes(scrConductor __instance, double hitsoundPlayFrom) { this.hitSoundsData = new List(); - if (this.playedHitSounds) - { - AudioManager.Instance.StopAllSounds(); - } - this.playedHitSounds = true; + //if (this.playedHitSounds) + //{ + // AudioManager.Instance.StopAllSounds(); + //} + //this.playedHitSounds = true; if (ADOBase.sceneName.Contains("scnCalibration") || __instance.lm == null || !GCS.d_hitsounds || From 796e569757388082c890f61ec311893774a73c95 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Sat, 3 Jul 2021 01:49:11 +0900 Subject: [PATCH 58/67] Chore: Remove unnecessary option in InputFixerSettings --- Helper/ReflectionField.cs | 2 +- InputFixer/InputFixerSettings.cs | 6 +++--- Settings.cs | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Helper/ReflectionField.cs b/Helper/ReflectionField.cs index 12915ab..41e75e2 100644 --- a/Helper/ReflectionField.cs +++ b/Helper/ReflectionField.cs @@ -8,7 +8,7 @@ public class ReflectionField { private static FieldInfo fi; - private string[] fieldNames; + private readonly string[] fieldNames; public ReflectionField(params string[] fieldNames) { diff --git a/InputFixer/InputFixerSettings.cs b/InputFixer/InputFixerSettings.cs index f1ea4b2..90236d7 100644 --- a/InputFixer/InputFixerSettings.cs +++ b/InputFixer/InputFixerSettings.cs @@ -8,14 +8,14 @@ namespace NoStopMod.InputFixer class InputFixerSettings : SettingsBase { public bool enableAsync = false; - public bool enableKeyLimit = false; + //public bool enableKeyLimit = false; public void Load(ref JSONNode json) { JSONNode node = json["InputFixer"]; enableAsync = node["enableAsync"].AsBool; - enableKeyLimit = node["enableKeyLimit"].AsBool; + //enableKeyLimit = node["enableKeyLimit"].AsBool; JSONArray array = node["LimitKeys"].AsArray; } @@ -23,7 +23,7 @@ public void Save(ref JSONNode json) { JSONNode node = JSONHelper.CreateEmptyNode(); node["enableAsync"].AsBool = enableAsync; - node["enableKeyLimit"].AsBool = enableKeyLimit; + //node["enableKeyLimit"].AsBool = enableKeyLimit; json["InputFixer"] = node; } diff --git a/Settings.cs b/Settings.cs index 245dab7..0c52bee 100644 --- a/Settings.cs +++ b/Settings.cs @@ -2,12 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; using NoStopMod.Helper; using NoStopMod.Helper.Abstraction; using SimpleJSON; -using UnityEngine; namespace NoStopMod { From 0cf8cd1f1c584a47ac6a1591e9872fee0af70064 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 9 Sep 2021 16:27:21 +0900 Subject: [PATCH 59/67] Refactor(GC): Remove already implemented feature --- GarbageCollection/GCManager.cs | 60 ----------------- GarbageCollection/GCPatches.cs | 117 --------------------------------- NoStopMod.cs | 4 +- 3 files changed, 1 insertion(+), 180 deletions(-) delete mode 100644 GarbageCollection/GCManager.cs delete mode 100644 GarbageCollection/GCPatches.cs diff --git a/GarbageCollection/GCManager.cs b/GarbageCollection/GCManager.cs deleted file mode 100644 index 697d0d3..0000000 --- a/GarbageCollection/GCManager.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using UnityEngine.Scripting; - -namespace NoStopMod.GarbageCollection -{ - public class GCManager - { - - private static bool gcEnabled = true; - - public static void Init() - { - NoStopMod.onToggleListener.Add(OnToggle); - } - - private static void OnToggle(bool enabled) - { - EnableGC(); - } - - public static bool GetDisableAutoSave() - { - return !gcEnabled; - } - - public static void DisableGC() - { - try - { - gcEnabled = false; - //NoStopMod.mod.Logger.Log("disablegc"); - GarbageCollector.GCMode = GarbageCollector.Mode.Disabled; - System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.SustainedLowLatency; - } - catch (NotImplementedException e) - { - NoStopMod.mod.Logger.Log("Exception occur"); - NoStopMod.mod.Logger.Error(e.ToString()); - } - } - - public static void EnableGC() - { - try - { - gcEnabled = true; - //NoStopMod.mod.Logger.Log("enablegc"); - GarbageCollector.GCMode = GarbageCollector.Mode.Enabled; - System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Interactive; - GC.Collect(); - } - catch (NotImplementedException e) - { - NoStopMod.mod.Logger.Log("Exception occur"); - NoStopMod.mod.Logger.Error(e.ToString()); - } - } - - } -} diff --git a/GarbageCollection/GCPatches.cs b/GarbageCollection/GCPatches.cs deleted file mode 100644 index 9b0d91e..0000000 --- a/GarbageCollection/GCPatches.cs +++ /dev/null @@ -1,117 +0,0 @@ -using HarmonyLib; -using NoStopMod.GarbageCollection; - -namespace NoStopMod.Patches -{ - public static class Patches - { - [HarmonyPatch(typeof(CustomLevel), "Play")] - private static class CustomLevel_Play_Patch - { - private static void Prefix(CustomLevel __instance) - { - //NoStopMod.mod.Logger.Log("Play"); - GCManager.DisableGC(); - } - } - - [HarmonyPatch(typeof(scnEditor), "ResetScene")] - private static class scnEditor_ResetScene_Patch - { - private static void Postfix(scnEditor __instance) - { - //NoStopMod.mod.Logger.Log("ResetScene"); - GCManager.EnableGC(); - } - } - - [HarmonyPatch(typeof(scnEditor), "SaveBackup")] - private static class scnEditor_SaveBackup_Patch - { - private static bool Prefix(scnEditor __instance) - { - //NoStopMod.mod.Logger.Log("SaveBackup"); - if (GCManager.GetDisableAutoSave()) - { - //NoStopMod.mod.Logger.Log("Cancel AutoSave"); - return false; - } - - return true; - } - } - - [HarmonyPatch(typeof(scrController), "Awake")] - private static class scrController_Awake_Patch - { - public static void Postfix(scrController __instance) - { - //NoStopMod.mod.Logger.Log("Awake"); - GCManager.EnableGC(); - } - } - - [HarmonyPatch(typeof(scrController), "FailAction")] - private static class scrController_FailAction_Patch - { - private static void Prefix(scrController __instance) - { - GCManager.EnableGC(); - } - } - - [HarmonyPatch(typeof(scrController), "QuitToMainMenu")] - private static class scrController_QuitToMainMenu_Patch - { - private static void Postfix(scrController __instance) - { - //NoStopMod.mod.Logger.Log("StartLoadingScene"); - GCManager.EnableGC(); - } - } - - [HarmonyPatch(typeof(scrController), "ResetCustomLevel")] - private static class scrController_ResetCustomLevel_Patch - { - private static void Postfix(scrController __instance) - { - //NoStopMod.mod.Logger.Log("ResetCustomLevel"); - GCManager.EnableGC(); - } - } - - [HarmonyPatch(typeof(scrController), "Restart")] - private static class scrController_Restart_Patch - { - private static void Prefix(scrController __instance) - { - //NoStopMod.mod.Logger.Log("Restart"); - GCManager.EnableGC(); - } - } - - [HarmonyPatch(typeof(scrController), "StartLoadingScene")] - private static class scrController_StartLoadingScene_Patch - { - private static void Postfix(scrController __instance) - { - //NoStopMod.mod.Logger.Log("StartLoadingScene"); - GCManager.EnableGC(); - } - } - - - [HarmonyPatch(typeof(scrUIController), "WipeToBlack")] - private static class scrUIController_WipeToBlack_Patch - { - private static void Postfix(scrUIController __instance) - { - //NoStopMod.mod.Logger.Log("WipeToBlack"); - GCManager.EnableGC(); - } - } - - } - - -} diff --git a/NoStopMod.cs b/NoStopMod.cs index b802828..2f37907 100644 --- a/NoStopMod.cs +++ b/NoStopMod.cs @@ -1,7 +1,6 @@ using System.Reflection; using HarmonyLib; using UnityModManagerNet; -using NoStopMod.GarbageCollection; using NoStopMod.InputFixer; using NoStopMod.HyperRabbit; using NoStopMod.Helper; @@ -35,8 +34,7 @@ public static bool Load(UnityModManager.ModEntry modEntry) NoStopMod.prevFrameTick = DateTime.Now.Ticks; NoStopMod.currFrameTick = prevFrameTick; - - GCManager.Init(); + InputFixerManager.Init(); HyperRabbitManager.Init(); From c3efd9f195847a8c5e6431b479b4fe259f2163f7 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 9 Sep 2021 16:27:45 +0900 Subject: [PATCH 60/67] Refactor(EditorSongFixer): Remove already implemented feature --- EditorSongFixer/EditorSongFixerManager.cs | 12 ------- EditorSongFixer/EditorSongFixerPatches.cs | 38 ----------------------- 2 files changed, 50 deletions(-) delete mode 100644 EditorSongFixer/EditorSongFixerManager.cs delete mode 100644 EditorSongFixer/EditorSongFixerPatches.cs diff --git a/EditorSongFixer/EditorSongFixerManager.cs b/EditorSongFixer/EditorSongFixerManager.cs deleted file mode 100644 index e709de7..0000000 --- a/EditorSongFixer/EditorSongFixerManager.cs +++ /dev/null @@ -1,12 +0,0 @@ -using NoStopMod.Helper; -using System.Reflection; - -namespace NoStopMod.EditorSongFixer -{ - class EditorSongFixerManager - { - - public static ReflectionField scnEditorCurrentSongKey = new ReflectionField("currentSongKey"); - - } -} diff --git a/EditorSongFixer/EditorSongFixerPatches.cs b/EditorSongFixer/EditorSongFixerPatches.cs deleted file mode 100644 index eefffc3..0000000 --- a/EditorSongFixer/EditorSongFixerPatches.cs +++ /dev/null @@ -1,38 +0,0 @@ -using HarmonyLib; -using NoStopMod.EditorSongFixer; - -namespace NoStopMod.InputFixer.SyncFixer -{ - class SyncFixerPatchesScnEditor - { - - /** - * Author: PatricKR - * - */ - [HarmonyPatch(typeof(scnEditor), "SwitchToEditMode")] - private static class scnEditor_SwitchToEditMode_Patch - { - private static void Prefix(scnEditor __instance) - { - __instance.conductor.song.Stop(); - AudioManager.Instance.StopAllSounds(); - } - } - - /** - * Author: PERIOT - * - */ - [HarmonyPatch(typeof(scnEditor), "OpenLevelCo")] - private static class scnEditor_OpenLevelCo_Patch - { - private static void Prefix(scnEditor __instance) - { - EditorSongFixerManager.scnEditorCurrentSongKey - .SetValue(CustomLevel.instance, null); - } - } - - } -} From c706216921553388117fd0cfbb224b2821461caf Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:27:44 +0900 Subject: [PATCH 61/67] Chore(HyperRabbit): Optimize mechanism --- HyperRabbit/HyperRabbitPatches.cs | 39 +++++++------------------------ 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/HyperRabbit/HyperRabbitPatches.cs b/HyperRabbit/HyperRabbitPatches.cs index d091919..3d36ac0 100644 --- a/HyperRabbit/HyperRabbitPatches.cs +++ b/HyperRabbit/HyperRabbitPatches.cs @@ -4,48 +4,25 @@ namespace NoStopMod.HyperRabbit { class HyperRabbitPatches { - - [HarmonyPatch(typeof(scrPlanet), "SwitchChosen")] - private static class PlanetSwitchChosenPatch - { - public static void Prefix(scrPlanet __instance) - { - if (RDC.auto && scrController.isGameWorld) - { - __instance.angle = __instance.targetExitAngle; - } - } - } [HarmonyPatch(typeof(scrController), "PlayerControl_Update")] private static class scrController_PlayerControl_Update_Patch { public static void Postfix(scrController __instance) { - if (!RDC.auto || !scrController.isGameWorld) - { - return; - } - - __instance.chosenplanet.Update_RefreshAngles(); - while (__instance.chosenplanet.AutoShouldHitNow()) + if (RDC.auto && scrController.isGameWorld) { - __instance.keyBufferCount = 0; - __instance.Hit(); - __instance.chosenplanet.Update_RefreshAngles(); + int num = 1000; + while (num > 0 && __instance.chosenplanet.AutoShouldHitNow()) + { + __instance.keyBufferCount = 0; + __instance.Hit(); + num--; + } } } } - [HarmonyPatch(typeof(scrController), "FailAction")] - private static class ControllerFailActionPatch - { - public static bool Prefix() - { - return !RDC.auto; - } - } - } } From 4f14c943d22d5cb1c35ad7fc2927af01260d909d Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:39:41 +0900 Subject: [PATCH 62/67] Feat(HyperRabbit): Add setting --- HyperRabbit/HyperRabbitManager.cs | 33 ++++++++---------------------- HyperRabbit/HyperRabbitSettings.cs | 26 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 HyperRabbit/HyperRabbitSettings.cs diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitManager.cs index fea34d5..6956601 100644 --- a/HyperRabbit/HyperRabbitManager.cs +++ b/HyperRabbit/HyperRabbitManager.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; +using UnityEngine; using UnityModManagerNet; namespace NoStopMod.HyperRabbit @@ -11,35 +6,23 @@ namespace NoStopMod.HyperRabbit class HyperRabbitManager { - public static bool isEnabled; - - enum Status - { - OFF, - FIXED_OTTO, - HYPER_RABBIT, - } + public static HyperRabbitSettings settings; public static void Init() { - NoStopMod.onToggleListener.Add(OnToggle); - //NoStopMod.onGUIListeners.Add(OnGUI); - } + NoStopMod.onGUIListener.Add(OnGUI); - private static void OnToggle(bool enabled) - { - isEnabled = enabled; + settings = new HyperRabbitSettings(); + Settings.settings.Add(settings); } private static void OnGUI(UnityModManager.ModEntry modEntry) { GUILayout.BeginHorizontal("HyperRabbit"); - GUILayout.TextArea("HyperRabbit Status", 20); - //if (GUILayout.Button(tex)) - //{ + GUILayout.TextArea("Max tile per frame", 20); - //} - //this.isEnabled = GUILayout.Toggle(isEnabled, "HyperRabbit"); + settings.maxTilePerFrame = (int) GUILayout.HorizontalSlider(settings.maxTilePerFrame, 1, 1000); + GUILayout.EndHorizontal(); } diff --git a/HyperRabbit/HyperRabbitSettings.cs b/HyperRabbit/HyperRabbitSettings.cs new file mode 100644 index 0000000..8999156 --- /dev/null +++ b/HyperRabbit/HyperRabbitSettings.cs @@ -0,0 +1,26 @@ +using NoStopMod.Helper; +using NoStopMod.Helper.Abstraction; +using SimpleJSON; + +namespace NoStopMod.HyperRabbit +{ + class HyperRabbitSettings : SettingsBase + { + public int maxTilePerFrame = 5; + + public void Load(ref JSONNode json) + { + JSONNode node = json["HyperRabbit"]; + + maxTilePerFrame = node["maxTilePerFrame"].AsInt; + } + + public void Save(ref JSONNode json) + { + JSONNode node = JSONHelper.CreateEmptyNode(); + node["maxTilePerFrame"].AsInt = maxTilePerFrame; + + json["HyperRabbit"] = node; + } + } +} From 8310748c5e53b47f5701369304f6cbbcea17e995 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:53:29 +0900 Subject: [PATCH 63/67] Fix(HyperRabbit): Fix setting --- HyperRabbit/HyperRabbitManager.cs | 5 +++-- HyperRabbit/HyperRabbitPatches.cs | 2 +- NoStopMod.csproj | 5 +---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/HyperRabbit/HyperRabbitManager.cs b/HyperRabbit/HyperRabbitManager.cs index 6956601..589077a 100644 --- a/HyperRabbit/HyperRabbitManager.cs +++ b/HyperRabbit/HyperRabbitManager.cs @@ -19,9 +19,10 @@ public static void Init() private static void OnGUI(UnityModManager.ModEntry modEntry) { GUILayout.BeginHorizontal("HyperRabbit"); - GUILayout.TextArea("Max tile per frame", 20); - settings.maxTilePerFrame = (int) GUILayout.HorizontalSlider(settings.maxTilePerFrame, 1, 1000); + GUILayout.Label("Max otto tile per frame (5 + " + settings.maxTilePerFrame + ")"); + + settings.maxTilePerFrame = (int) GUILayout.HorizontalSlider(settings.maxTilePerFrame, 0, 100); GUILayout.EndHorizontal(); } diff --git a/HyperRabbit/HyperRabbitPatches.cs b/HyperRabbit/HyperRabbitPatches.cs index 3d36ac0..a77125a 100644 --- a/HyperRabbit/HyperRabbitPatches.cs +++ b/HyperRabbit/HyperRabbitPatches.cs @@ -12,7 +12,7 @@ public static void Postfix(scrController __instance) { if (RDC.auto && scrController.isGameWorld) { - int num = 1000; + int num = HyperRabbitManager.settings.maxTilePerFrame; while (num > 0 && __instance.chosenplanet.AutoShouldHitNow()) { __instance.keyBufferCount = 0; diff --git a/NoStopMod.csproj b/NoStopMod.csproj index 53a171f..a38a20e 100644 --- a/NoStopMod.csproj +++ b/NoStopMod.csproj @@ -352,11 +352,11 @@ - + @@ -365,12 +365,9 @@ - - - From 725c727bfe28757179d8f2d1c448861d3557276a Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Thu, 9 Sep 2021 20:48:16 +0900 Subject: [PATCH 64/67] Chore: Simplify startMusicCo 3 --- InputFixer/SyncFixer/newScrConductor.cs | 39 +++++++++++++++---------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/InputFixer/SyncFixer/newScrConductor.cs b/InputFixer/SyncFixer/newScrConductor.cs index 514bfda..9d4726f 100644 --- a/InputFixer/SyncFixer/newScrConductor.cs +++ b/InputFixer/SyncFixer/newScrConductor.cs @@ -1,10 +1,12 @@ -using NoStopMod.Helper; +using NoStopMod.Helper; using RDTools; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; + + namespace NoStopMod.InputFixer.SyncFixer { @@ -356,32 +358,35 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti yield return null; } - this.dspTime = AudioSettings.dspTime; #if DEBUG NoStopMod.mod.Logger.Log("call From StartMusicCo Second"); #endif + this.dspTime = AudioSettings.dspTime; FixOffsetTick(); + AudioListener.pause = true; + double countdownTime = __instance.crotchetAtStart * __instance.countdownTicks; double separatedCountdownTime = __instance.separateCountdownTime ? countdownTime : 0.0; - this.dspTimeSong = this.dspTime + this.buffer; - if (__instance.fastTakeoff) - { - this.dspTimeSong -= countdownTime / __instance.song.pitch; - } - double time = this.dspTimeSong + separatedCountdownTime / __instance.song.pitch; - __instance.song.UnPause(); - __instance.song.PlayScheduled(time); - __instance.song2?.PlayScheduled(time); + if (GCS.checkpointNum == 0) + { + this.dspTimeSong = this.dspTime + this.buffer; + if (__instance.fastTakeoff) + { + this.dspTimeSong -= countdownTime / __instance.song.pitch; + } + + double time = this.dspTimeSong + separatedCountdownTime / __instance.song.pitch; - if (GCS.checkpointNum != 0) + __instance.song.PlayScheduled(time); + __instance.song2?.PlayScheduled(time); + } + else { - yield return null; - AudioListener.pause = true; - __instance.song.SetScheduledStartTime(this.dspTime); + __instance.song.PlayScheduled(this.dspTime); double entryTime = __instance.lm.listFloors[FindSongStartTile(__instance, GCS.checkpointNum, RDC.auto && __instance.isLevelEditor)].entryTime; @@ -398,6 +403,10 @@ public IEnumerator StartMusicCo(scrConductor __instance, Action onComplete, Acti yield return null; AudioListener.pause = false; +#if DEBUG + NoStopMod.mod.Logger.Log("call From StartMusicCo Third"); +#endif + FixOffsetTick(); yield return new WaitForSeconds(4f); while (__instance.song.isPlaying) From 90f84560645a69b90529ee4faf98f06692cf1b07 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Fri, 10 Sep 2021 20:29:23 +0900 Subject: [PATCH 65/67] Refactor: use more concrete name --- Helper/ReflectionField.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Helper/ReflectionField.cs b/Helper/ReflectionField.cs index 41e75e2..45c9113 100644 --- a/Helper/ReflectionField.cs +++ b/Helper/ReflectionField.cs @@ -6,7 +6,7 @@ namespace NoStopMod.Helper { public class ReflectionField { - private static FieldInfo fi; + private static FieldInfo fieldInfo; private readonly string[] fieldNames; @@ -17,21 +17,21 @@ public ReflectionField(params string[] fieldNames) public FieldInfo GetFieldInfo(Type type) { - if (fi == null) + if (fieldInfo == null) { for (int i=0;i < fieldNames.Count();i++) { - fi = type.GetField(fieldNames[i], + fieldInfo = type.GetField(fieldNames[i], BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); - if (fi != null) break; + if (fieldInfo != null) break; } - if (fi == null) + if (fieldInfo == null) { NoStopMod.mod.Logger.Error("Cannot find fieldInfo : (type=" + type + ", name" + fieldNames + ")"); } } - return fi; + return fieldInfo; } public void SetValue(object obj, T value) From a6c0017a06c70b7bcfd7fb3a60ad99b82e64dc5b Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Mon, 13 Sep 2021 13:18:24 +0900 Subject: [PATCH 66/67] Chore: Change default maxTilePerFrame to 0 --- HyperRabbit/HyperRabbitSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HyperRabbit/HyperRabbitSettings.cs b/HyperRabbit/HyperRabbitSettings.cs index 8999156..f9c7d39 100644 --- a/HyperRabbit/HyperRabbitSettings.cs +++ b/HyperRabbit/HyperRabbitSettings.cs @@ -6,7 +6,7 @@ namespace NoStopMod.HyperRabbit { class HyperRabbitSettings : SettingsBase { - public int maxTilePerFrame = 5; + public int maxTilePerFrame = 0; public void Load(ref JSONNode json) { From 11592285f15921e3d1933c75df1d1b7a0b977e31 Mon Sep 17 00:00:00 2001 From: Luxusio <44326048+Luxusio@users.noreply.github.com> Date: Mon, 13 Sep 2021 13:19:54 +0900 Subject: [PATCH 67/67] Doc: Change version to 1.2.3 --- Info.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Info.json b/Info.json index aaad000..291b88a 100644 --- a/Info.json +++ b/Info.json @@ -2,7 +2,7 @@ "Id": "NoStopMod", "DisplayName": "NoStopMod", "Author": "Luxus", - "Version": "1.2.2", + "Version": "1.2.3", "ManagerVersion": "0.23.4.0", "AssemblyName": "NoStopMod.dll", "EntryMethod": "NoStopMod.NoStopMod.Load",