using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Xml.Serialization;
using BaboonAPI.Hooks.Initializer;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TootTallyCore;
using TootTallyCore.Utils.Helpers;
using TootTallyCore.Utils.TootTallyModules;
using TootTallySettings;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("TootTallyTootScoreVisualizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Customize the text popup score after playing a note")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: AssemblyProduct("TootTallyTootScoreVisualizer")]
[assembly: AssemblyTitle("TootTallyTootScoreVisualizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace TootTallyTootScoreVisualizer
{
[BepInPlugin("TootTallyTootScoreVisualizer", "TootTallyTootScoreVisualizer", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin, ITootTallyModule
{
public static class TSVPatches
{
public static int noteParticles_index;
public static float noteScoreAverage;
private static int _lastNoteEffectIndex;
[HarmonyPatch(typeof(GameController), "Start")]
[HarmonyPostfix]
public static void OnLoadControllerLoadGameplayAsyncPostfix(GameController __instance)
{
ResolvePresets();
}
[HarmonyPatch(typeof(GameController), "doScoreText")]
[HarmonyPrefix]
public static void OnGameControllerGetScoreAveragePrefix(GameController __instance)
{
noteScoreAverage = __instance.notescoreaverage;
}
[HarmonyPatch(typeof(GameController), "animateOutNote")]
[HarmonyPrefix]
public static void OnGameControllerAnimateOutNotePrefix(GameController __instance)
{
_lastNoteEffectIndex = __instance.noteparticles_index;
}
[HarmonyPatch(typeof(GameController), "animateOutNote")]
[HarmonyPostfix]
public static void OnGameControllerAnimateOutNotePostfix(GameController __instance, ref noteendeffect[] ___allnoteendeffects)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
if (TSVConfig.configLoaded)
{
Threshold scoreThreshold = TSVConfig.GetScoreThreshold(noteScoreAverage);
noteendeffect noteendeffect = ___allnoteendeffects[_lastNoteEffectIndex];
Text combotext_txt_front = noteendeffect.combotext_txt_front;
Text combotext_txt_shadow = noteendeffect.combotext_txt_shadow;
HorizontalWrapMode horizontalOverflow = (HorizontalWrapMode)1;
combotext_txt_shadow.horizontalOverflow = (HorizontalWrapMode)1;
combotext_txt_front.horizontalOverflow = horizontalOverflow;
Text combotext_txt_front2 = noteendeffect.combotext_txt_front;
Text combotext_txt_shadow2 = noteendeffect.combotext_txt_shadow;
VerticalWrapMode verticalOverflow = (VerticalWrapMode)1;
combotext_txt_shadow2.verticalOverflow = (VerticalWrapMode)1;
combotext_txt_front2.verticalOverflow = verticalOverflow;
noteendeffect.combotext_txt_front.text = scoreThreshold.GetFormattedText(noteScoreAverage, __instance.multiplier);
noteendeffect.combotext_txt_shadow.text = scoreThreshold.GetFormattedTextNoColor(noteScoreAverage, __instance.multiplier);
((Graphic)noteendeffect.combotext_txt_front).color = scoreThreshold.color;
}
}
}
public struct noteendeffect
{
public GameObject noteeffect_obj;
public RectTransform noteeffect_rect;
public GameObject burst_obj;
public Image burst_img;
public CanvasGroup burst_canvasg;
public ParticleSystem burst_particles;
public GameObject drops_obj;
public CanvasGroup drops_canvasg;
public GameObject combotext_obj;
public RectTransform combotext_rect;
public Text combotext_txt_front;
public Text combotext_txt_shadow;
}
public static Plugin Instance;
public const string CONFIGS_FOLDER_NAME = "/TootScoreVisualizer/";
private const string CONFIG_NAME = "TootScoreVisualizer.cfg";
private const string SETTINGS_PAGE_NAME = "TootScoreVisualizer";
public static string currentLoadedConfigName;
private Harmony _harmony;
public static TootTallySettingPage settingPage;
public ConfigEntry<bool> ModuleConfigEnabled { get; set; }
public bool IsConfigInitialized { get; set; }
public string Name
{
get
{
return "TootScoreVisualizer";
}
set
{
Name = value;
}
}
public ConfigEntry<string> TSVName { get; set; }
public static void LogInfo(string msg)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)msg);
}
public static void LogError(string msg)
{
((BaseUnityPlugin)Instance).Logger.LogError((object)msg);
}
private void Awake()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
Instance = this;
_harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
GameInitializationEvent.Register(((BaseUnityPlugin)this).Info, (Action)TryInitialize);
}
}
private void TryInitialize()
{
if (Application.version.CompareTo("1.19A") < 0)
{
LogInfo("Please install Trombone Champ 1.19A version or later.");
return;
}
ModuleConfigEnabled = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Modules", "TootScoreVisualizer", true, "Enables text popup customization when playing notes.");
TootTallyModuleManager.AddModule((ITootTallyModule)(object)this);
Plugin.Instance.AddModuleToSettingPage((ITootTallyModule)(object)this);
}
public void LoadModule()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
string text = Path.Combine(Paths.BepInExRootPath, "config/");
ConfigFile val = new ConfigFile(text + "TootScoreVisualizer.cfg", true);
TSVName = val.Bind<string>("Generic", "TSVName", "Default", "Enter the name of your config here. Do not put the .xml extension.");
val.SettingChanged += Config_SettingChanged;
string text2 = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location), "TootScoreVisualizer");
string text3 = Path.Combine(Paths.BepInExRootPath, "TootScoreVisualizer");
FileHelper.TryMigrateFolder(text2, text3, true);
settingPage = TootTallySettingsManager.AddNewPage("TootScoreVisualizer", "TootScoreVisualizer", 40f, new Color(0.1f, 0.1f, 0.1f, 0.1f));
List<string> fileNames = new List<string>();
if (Directory.Exists(text3))
{
string[] files = Directory.GetFiles(text3);
files.ToList().ForEach(delegate(string d)
{
fileNames.Add(Path.GetFileNameWithoutExtension(d));
});
}
settingPage.AddDropdown("TSVDropdown", TSVName, fileNames.ToArray());
ResolvePresets();
Plugin.TryAddThunderstoreIconToPageButton(((BaseUnityPlugin)Instance).Info.Location, Name, settingPage);
_harmony.PatchAll(typeof(TSVPatches));
LogInfo("Module loaded!");
}
private void Config_SettingChanged(object sender, SettingChangedEventArgs e)
{
ResolvePresets();
}
public void UnloadModule()
{
_harmony.UnpatchSelf();
settingPage.Remove();
LogInfo("Module unloaded!");
}
public static void ResolvePresets()
{
if (currentLoadedConfigName != Instance.TSVName.Value)
{
LogInfo("Config file changed, loading new config");
TSVConfig.LoadConfig(Instance.TSVName.Value);
}
}
}
[XmlRoot("tsv")]
public class SerializableTSVConfig
{
public class ThresholdData
{
[XmlAttribute("value")]
public float threshold;
[XmlAttribute("textsize")]
public int size;
[XmlElement("text")]
public string text;
[XmlElement("color")]
public string color;
}
[XmlAttribute("modversion")]
public string modversion;
[XmlAttribute("decimalprecision")]
public int decimalprecision;
[XmlArray("scorethresholdlist")]
[XmlArrayItem("threshold")]
public List<ThresholdData> scoreThreshold;
[XmlArray("multiplierthresholdlist")]
[XmlArrayItem("threshold")]
public List<ThresholdData> multiplierThreshold;
}
public static class TSVConfig
{
public static List<Threshold> scoreThresholdList;
public static bool configLoaded;
public static string GetHardCodedDefaultConfigString => "<!--\r\n %P = Accuracy score (0 to 100)\r\n %m = Uses the text that matches the threshold as specified in multiplierthresholdlist\r\n %M = In-game value of multiplier (1x to 10x)\r\n threshold = if the value is greater than the given threshold\r\n decimalprecision = number of digits \r\n textsize = the size of the text (defaulted at 20)\r\n -->\r\n <tsv modversion = \"1.0.0\" decimalprecision=\"2\">\r\n\t <scorethresholdlist>\r\n\t\t <threshold value = \"88\" textsize=\"20\" >\r\n <text>%MX</text>\r\n\t\t\t <color>#FFFFFFFF</color>\r\n\t\t </threshold>\r\n\t\t\t\t<threshold value = \"79\" textsize=\"20\">\r\n\t\t\t\t\t<text>OK</text>\r\n\t\t\t\t\t<color>#FFFFFFFF</color>\r\n\t\t\t\t</threshold>\r\n\t\t\t\t<threshold value = \"70\" textsize=\"20\" >\r\n\t\t\t\t\t<text>MEH</text>\r\n\t\t\t\t\t<color>#FFFFFFFF</color>\r\n\t\t\t\t</threshold>\r\n\t\t\t\t<threshold value = \"0\" textsize=\"20\">\r\n\t\t\t\t\t<text>x</text>\r\n\t\t\t\t\t<color>#FF0000FF</color>\r\n\t\t\t\t</threshold>\r\n\t </scorethresholdlist>\r\n\t <multiplierthresholdlist>\r\n\t\t <threshold value = \"0\">\r\n <text></text>\r\n <color>#FFFFFFFF</color>\r\n\t\t </threshold>\r\n </multiplierthresholdlist>\r\n </tsv>";
public static void LoadConfig(string configName)
{
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
configLoaded = false;
string text = configName + ".xml";
string text2 = Path.Combine(Paths.BepInExRootPath + "/TootScoreVisualizer/");
if (!Directory.Exists(text2))
{
Directory.CreateDirectory(text2);
}
if (!File.Exists(text2 + text))
{
Plugin.LogError("TSV config " + text + " not found, using default config");
text = "Default.xml";
Plugin.Instance.TSVName.Value = "Default";
if (!File.Exists(text2 + text))
{
Plugin.LogError("Couldn't find " + text + ". Generating new Default config");
File.WriteAllText(text2 + text, GetHardCodedDefaultConfigString);
}
}
try
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SerializableTSVConfig));
SerializableTSVConfig serializableTSVConfig = (SerializableTSVConfig)xmlSerializer.Deserialize(File.OpenRead(text2 + text));
List<MultiplierThreshold> list = new List<MultiplierThreshold>();
foreach (SerializableTSVConfig.ThresholdData item in serializableTSVConfig.multiplierThreshold)
{
list.Add(new MultiplierThreshold(item.threshold, item.text, item.size, item.color));
}
scoreThresholdList = new List<Threshold>();
Color color = default(Color);
foreach (SerializableTSVConfig.ThresholdData item2 in serializableTSVConfig.scoreThreshold)
{
ColorUtility.TryParseHtmlString(item2.color, ref color);
scoreThresholdList.Add(new Threshold(item2.threshold, item2.text, item2.size, color, serializableTSVConfig.decimalprecision, list));
}
scoreThresholdList.Sort((Threshold x, Threshold y) => (x.value > y.value) ? 1 : 0);
Plugin.currentLoadedConfigName = configName;
Plugin.LogInfo("TSV config " + configName + " has been loaded");
configLoaded = true;
}
catch (Exception ex)
{
Plugin.LogError(ex.Message);
}
}
public static Threshold GetScoreThreshold(float value)
{
for (int i = 0; i < scoreThresholdList.Count; i++)
{
if (value > scoreThresholdList[i].value)
{
return scoreThresholdList[i];
}
}
return scoreThresholdList.Last();
}
}
public class Threshold
{
public float value;
public string text;
public int size;
public Color color;
public int decimalprecision;
public List<MultiplierThreshold> multiplierThresholdList;
public Threshold(float value, string text, int size, Color color, int decimalprecision, List<MultiplierThreshold> multiplierThresholdList)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
this.value = value;
this.text = text;
this.size = size;
this.color = color;
this.decimalprecision = decimalprecision;
this.multiplierThresholdList = multiplierThresholdList;
if (this.size == 0)
{
this.size = 20;
}
}
public string GetFormattedText(float notescoreaverage, int multiplier)
{
string text = this.text.Replace("%P", $"<size={size}>" + notescoreaverage.ToString($"F{decimalprecision}") + "</size>");
text = text.Replace("%m", GetMultiplierThreshold(multiplier).GetFormattedMultiplierText(multiplier));
text = text.Replace("%M", $"<size={size}>" + multiplier + "</size>");
return text.Replace("%n", "\n");
}
public string GetFormattedTextNoColor(float notescoreaverage, int multiplier)
{
string text = this.text.Replace("%P", $"<size={size}>" + notescoreaverage.ToString($"F{decimalprecision}") + "</size>");
text = text.Replace("%m", GetMultiplierThreshold(multiplier).GetFormattedMultiplierTextNoColor(multiplier));
text = text.Replace("%M", $"<size={size}>" + multiplier + "</size>");
return text.Replace("%n", "\n");
}
public MultiplierThreshold GetMultiplierThreshold(float value)
{
for (int i = 0; i < multiplierThresholdList.Count; i++)
{
if (value >= multiplierThresholdList[i].value)
{
return multiplierThresholdList[i];
}
}
return multiplierThresholdList.Last();
}
}
public class MultiplierThreshold
{
public float value;
public string text;
public int size;
public string color;
public MultiplierThreshold(float value, string text, int size, string color)
{
this.value = value;
this.text = text;
this.size = size;
this.color = color;
if (this.size == 0)
{
this.size = 20;
}
}
public string GetFormattedMultiplierText(int multiplier)
{
return $"<size={size}><color={color}>" + text.Replace("%M", multiplier.ToString()) + "</color></size>";
}
public string GetFormattedMultiplierTextNoColor(int multiplier)
{
return $"<size={size}>" + text.Replace("%M", multiplier.ToString()) + "</size>";
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "TootTallyTootScoreVisualizer";
public const string PLUGIN_NAME = "TootTallyTootScoreVisualizer";
public const string PLUGIN_VERSION = "1.0.3";
}
}