diff --git a/HitScoreVisualizer/Config.cs b/HitScoreVisualizer/Config.cs index dc5a632..88c7d83 100644 --- a/HitScoreVisualizer/Config.cs +++ b/HitScoreVisualizer/Config.cs @@ -6,8 +6,11 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using TMPro; using UnityEngine; +using static HitScoreVisualizer.Utils.ReflectionUtil; + namespace HitScoreVisualizer { public class Config @@ -106,13 +109,13 @@ public struct SegmentJudgment private const string DEFAULT_JSON = @"{ ""majorVersion"": 2, ""minorVersion"": 1, - ""patchVersion"": 3, + ""patchVersion"": 5, ""isDefaultConfig"": true, ""displayMode"": ""format"", ""judgments"": [ { ""threshold"": 110, - ""text"": ""Fantastic%n%s%n%B %C %A"", + ""text"": ""%BFantastic%A%n%s"", ""color"": [ 1.0, 1.0, @@ -122,7 +125,7 @@ public struct SegmentJudgment }, { ""threshold"": 101, - ""text"": ""Excellent%n%s%n%B %C %A"", + ""text"": ""%BExcellent%A%n%s"", ""color"": [ 0.0, 1.0, @@ -132,7 +135,7 @@ public struct SegmentJudgment }, { ""threshold"": 90, - ""text"": ""Great%n%s%n%B %C %A"", + ""text"": ""%BGreat%A%n%s"", ""color"": [ 1.0, 0.980392158, @@ -142,7 +145,7 @@ public struct SegmentJudgment }, { ""threshold"": 80, - ""text"": ""Good%n%s%n%B %C %A"", + ""text"": ""%BGood%A%n%s"", ""color"": [ 1.0, 0.6, @@ -153,7 +156,7 @@ public struct SegmentJudgment }, { ""threshold"": 60, - ""text"": ""Decent%n%s%n%B %C %A"", + ""text"": ""%BDecent%A%n%s"", ""color"": [ 1.0, 0.0, @@ -163,7 +166,7 @@ public struct SegmentJudgment ""fade"": true }, { - ""text"": ""Way Off%n%s%n%B %C %A"", + ""text"": ""%BWay Off%A%n%s"", ""color"": [ 0.5, 0.0, @@ -175,44 +178,29 @@ public struct SegmentJudgment ], ""beforeCutAngleJudgments"": [ { - ""threshold"": 70, + ""threshold"": 70, ""text"": ""+"" }, { - ""threshold"": 35, ""text"": "" "" - }, - { - ""threshold"": 0, - ""text"": ""-"" } ], ""accuracyJudgments"": [ { - ""threshold"": 10, + ""threshold"": 10, ""text"": ""+"" }, { - ""threshold"": 5, ""text"": "" "" - }, - { - ""threshold"": 0, - ""text"": ""-"" } ], ""afterCutAngleJudgments"": [ { - ""threshold"": 30, + ""threshold"": 30, ""text"": ""+"" }, { - ""threshold"": 15, ""text"": "" "" - }, - { - ""threshold"": 0, - ""text"": ""-"" } ] }"; @@ -278,9 +266,9 @@ public static void load() loaded.patchVersion = 0; isDirty = true; } - if (loaded.majorVersion == 2 && loaded.minorVersion == 1 && loaded.patchVersion < 3) + if (loaded.majorVersion == 2 && loaded.minorVersion == 1 && loaded.patchVersion < Plugin.patchVersion) { - loaded.patchVersion = 3; + loaded.patchVersion = Plugin.patchVersion; isDirty = true; } if (isDirty) save(); @@ -345,8 +333,16 @@ public static void resetToDefault() instance = DEFAULT_CONFIG; } - public static void judge(FlyingScoreTextEffect text, NoteCutInfo noteCutInfo, SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, ref Color color, int score, int before, int after, int accuracy) + public static void judge(FlyingScoreEffect scoreEffect, NoteCutInfo noteCutInfo, SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, ref Color color, int score, int before, int after, int accuracy) { + // as of 0.13, the TextMeshPro is private; use reflection to grab it out of a private field + TextMeshPro text = scoreEffect.getPrivateField("_text"); + // enable rich text + text.richText = true; + // disable word wrap, make sure full text displays + text.enableWordWrapping = false; + text.overflowMode = TextOverflowModes.Overflow; + Judgment judgment = DEFAULT_JUDGMENT; int index; // save in case we need to fade for (index = 0; index < instance.judgments.Length; index++) @@ -435,6 +431,7 @@ public static void judge(FlyingScoreTextEffect text, NoteCutInfo noteCutInfo, Sa } if (instance.displayMode == "numeric") { + text.text = score.ToString(); return; } if (instance.displayMode == "scoreOnTop") diff --git a/HitScoreVisualizer/Harmony Patches/FlyingScoreEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent.cs b/HitScoreVisualizer/Harmony Patches/FlyingScoreEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent.cs new file mode 100644 index 0000000..266ec89 --- /dev/null +++ b/HitScoreVisualizer/Harmony Patches/FlyingScoreEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent.cs @@ -0,0 +1,23 @@ +using Harmony; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace HitScoreVisualizer.Harmony_Patches +{ + [HarmonyPatch(typeof(FlyingScoreEffect), "HandleSaberAfterCutSwingRatingCounterDidChangeEvent", + new Type[] { typeof(SaberAfterCutSwingRatingCounter), typeof(float) })] + class FlyingScoreEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent + { + static bool Prefix(SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, FlyingScoreEffect __instance, ref Color ____color, NoteCutInfo ____noteCutInfo) + { + ScoreController.ScoreWithoutMultiplier(____noteCutInfo, saberAfterCutSwingRatingCounter, out int before_plus_acc, out int after, out int accuracy); + int total = before_plus_acc + after; + Config.judge(__instance, ____noteCutInfo, saberAfterCutSwingRatingCounter, ref ____color, total, before_plus_acc - accuracy, after, accuracy); + return false; + } + } +} diff --git a/HitScoreVisualizer/Harmony Patches/FlyingScoreTextEffectInitAndPresent.cs b/HitScoreVisualizer/Harmony Patches/FlyingScoreEffectInitAndPresent.cs similarity index 78% rename from HitScoreVisualizer/Harmony Patches/FlyingScoreTextEffectInitAndPresent.cs rename to HitScoreVisualizer/Harmony Patches/FlyingScoreEffectInitAndPresent.cs index a947228..a9709a9 100644 --- a/HitScoreVisualizer/Harmony Patches/FlyingScoreTextEffectInitAndPresent.cs +++ b/HitScoreVisualizer/Harmony Patches/FlyingScoreEffectInitAndPresent.cs @@ -8,16 +8,17 @@ namespace HitScoreVisualizer.Harmony_Patches { - [HarmonyPatch(typeof(FlyingScoreTextEffect), "InitAndPresent", + [HarmonyPatch(typeof(FlyingScoreEffect), "InitAndPresent", new Type[] { typeof(NoteCutInfo), typeof(int), + typeof(float), typeof(Vector3), typeof(Color), typeof(SaberAfterCutSwingRatingCounter)})] - class FlyingScoreTextEffectInitAndPresent + class FlyingScoreEffectInitAndPresent { - static void Postfix(SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, FlyingScoreTextEffect __instance, ref Color ____color, NoteCutInfo noteCutInfo) + static void Postfix(SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, FlyingScoreEffect __instance, ref Color ____color, NoteCutInfo noteCutInfo) { ScoreController.ScoreWithoutMultiplier(noteCutInfo, saberAfterCutSwingRatingCounter, out int before_plus_acc, out int after, out int accuracy); int total = before_plus_acc + after; diff --git a/HitScoreVisualizer/Harmony Patches/FlyingScoreTextEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent.cs b/HitScoreVisualizer/Harmony Patches/FlyingScoreTextEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent.cs deleted file mode 100644 index 2a0bcac..0000000 --- a/HitScoreVisualizer/Harmony Patches/FlyingScoreTextEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Harmony; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace HitScoreVisualizer.Harmony_Patches -{ - [HarmonyPatch(typeof(FlyingScoreTextEffect), "HandleSaberAfterCutSwingRatingCounterDidChangeEvent", - new Type[] { typeof(SaberAfterCutSwingRatingCounter), typeof(float) })] - class FlyingScoreTextEffectHandleSaberAfterCutSwingRatingCounterDidChangeEvent - { - static bool Prefix(SaberAfterCutSwingRatingCounter afterCutRating, FlyingScoreTextEffect __instance, ref Color ____color, NoteCutInfo ____noteCutInfo, int ____multiplier) - { - ScoreController.ScoreWithoutMultiplier(____noteCutInfo, afterCutRating, out int before_plus_acc, out int after, out int accuracy); - int total = before_plus_acc + after; - Config.judge(__instance, ____noteCutInfo, afterCutRating, ref ____color, total, before_plus_acc - accuracy, after, accuracy); - return false; - } - } -} diff --git a/HitScoreVisualizer/HitScoreVisualizer.csproj b/HitScoreVisualizer/HitScoreVisualizer.csproj index 1400c3d..2bbbad9 100644 --- a/HitScoreVisualizer/HitScoreVisualizer.csproj +++ b/HitScoreVisualizer/HitScoreVisualizer.csproj @@ -44,7 +44,8 @@ ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\IllusionPlugin.dll - ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + False + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\Newtonsoft.Json.dll @@ -54,6 +55,9 @@ + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\Unity.TextMeshPro.dll + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\UnityEngine.dll @@ -63,10 +67,11 @@ - - + + + diff --git a/HitScoreVisualizer/Plugin.cs b/HitScoreVisualizer/Plugin.cs index 38d1178..de15dac 100644 --- a/HitScoreVisualizer/Plugin.cs +++ b/HitScoreVisualizer/Plugin.cs @@ -9,11 +9,11 @@ namespace HitScoreVisualizer public class Plugin : IPlugin { public string Name => "HitScoreVisualizer"; - public string Version => "2.1.3"; + public string Version => "2.1.5"; internal const int majorVersion = 2; internal const int minorVersion = 1; - internal const int patchVersion = 3; + internal const int patchVersion = 5; public void OnApplicationStart() { diff --git a/HitScoreVisualizer/Utils/ReflectionUtil.cs b/HitScoreVisualizer/Utils/ReflectionUtil.cs new file mode 100644 index 0000000..76aa06d --- /dev/null +++ b/HitScoreVisualizer/Utils/ReflectionUtil.cs @@ -0,0 +1,66 @@ +using System.Reflection; + +namespace HitScoreVisualizer.Utils +{ + static class ReflectionUtil + { + public static void SetPrivateField(object obj, string fieldName, object value) + { + var prop = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + prop.SetValue(obj, value); + } + + public static T GetPrivateField(object obj, string fieldName) + { + var prop = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + var value = prop.GetValue(obj); + return (T)value; + } + + public static void SetPrivateProperty(object obj, string propertyName, object value) + { + var prop = obj.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + prop.SetValue(obj, value, null); + } + + public static void SetPrivateFieldBase(object obj, string fieldName, object value) + { + var prop = obj.GetType().BaseType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + prop.SetValue(obj, value); + } + + public static T GetPrivateFieldBase(object obj, string fieldName) + { + var prop = obj.GetType().BaseType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + var value = prop.GetValue(obj); + return (T)value; + } + + public static void SetPrivatePropertyBase(object obj, string propertyName, object value) + { + var prop = obj.GetType().BaseType.GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + prop.SetValue(obj, value, null); + } + + public static void InvokePrivateMethod(object obj, string methodName, object[] methodParams) + { + MethodInfo dynMethod = obj.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + dynMethod.Invoke(obj, methodParams); + } + + public static T getPrivateField(this object obj, string fieldName) => + GetPrivateField(obj, fieldName); + public static void setPrivateField(this object obj, string fieldName, object value) => + SetPrivateField(obj, fieldName, value); + public static T getPrivateFieldBase(this object obj, string fieldName) => + GetPrivateFieldBase(obj, fieldName); + public static void setPrivateFieldBase(this object obj, string fieldName, object value) => + SetPrivateFieldBase(obj, fieldName, value); + public static void setPrivateProperty(this object obj, string propertyName, object value) => + setPrivateProperty(obj, propertyName, value); + public static void setPrivatePropertyBase(this object obj, string propertyName, object value) => + setPrivatePropertyBase(obj, propertyName, value); + public static void invokePrivateMethod(this object obj, string methodName, object[] methodParams) => + InvokePrivateMethod(obj, methodName, methodParams); + } +} \ No newline at end of file