using System; using System.Collections; 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.Text.RegularExpressions; using FishNet; using HarmonyLib; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using ScheduleOne; using ScheduleOne.DevUtilities; using ScheduleOne.ItemFramework; using ScheduleOne.PlayerScripts; using ScheduleOne.UI; using TMPro; using TextDecorator; using UnityEngine; using UnityEngine.Events; 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: MelonInfo(typeof(global::TextDecorator.TextDecorator), "Text Decorator", "0.6.0", "k073l", null)] [assembly: MelonColor(1, 255, 215, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TextDecorator-Mono")] [assembly: AssemblyConfiguration("Release Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c06a856efeab89e10efdfb8effe0618330b413d2")] [assembly: AssemblyProduct("TextDecorator-Mono")] [assembly: AssemblyTitle("TextDecorator-Mono")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 TextDecorator { public static class BuildInfo { public const string Name = "Text Decorator"; public const string Description = "Adds text formatting options to the text input screen."; public const string Author = "k073l"; public const string Version = "0.6.0"; } [Serializable] public class ColorData { public int R; public int G; public int B; public ColorData(int r, int g, int b) { R = r; G = g; B = b; } public static ColorData FromColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) return new ColorData(Mathf.RoundToInt(color.r * 255f), Mathf.RoundToInt(color.g * 255f), Mathf.RoundToInt(color.b * 255f)); } public Color ToColor() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new Color((float)R / 255f, (float)G / 255f, (float)B / 255f); } } [Serializable] public class FormatButtonData { public string Label; public string TagKey; public ColorData ButtonColorData; [JsonIgnore] public Color ButtonColor => ButtonColorData.ToColor(); public FormatButtonData(string label, string tagKey, Color buttonColor) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) Label = label; TagKey = tagKey; ButtonColorData = ColorData.FromColor(buttonColor); } } [Serializable] public class CustomColorConfig { public List customColors = new List(); } public class TextDecorator : MelonMod { [HarmonyPatch(typeof(TextInputScreen))] public static class TextInputScreenPatch { [CompilerGenerated] private sealed class d__11 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; ((Graphic)warningText).color = Color.yellow; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; ((Graphic)warningText).color = Color.white; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Dictionary formatButtons = new Dictionary(); private static List colorButtons = new List { new FormatButtonData("R", "color=#FF5555", new Color(1f, 0.33f, 0.33f)), new FormatButtonData("G", "color=#55FF55", new Color(0.33f, 1f, 0.33f)), new FormatButtonData("B", "color=#5555FF", new Color(0.33f, 0.33f, 1f)), new FormatButtonData("Y", "color=#FFFF55", new Color(1f, 1f, 0.33f)), new FormatButtonData("P", "color=#FF55FF", new Color(1f, 0.33f, 1f)) }; private static readonly Dictionary formatTags = new Dictionary { { "bold", "b" }, { "italic", "i" }, { "underline", "u" }, { "strikethrough", "s" } }; private static TMP_InputField inputField; private static TextMeshProUGUI warningText; private static readonly string ConfigFilePath = Path.Combine(MelonEnvironment.UserDataDirectory, "TextDecoratorColors.json"); private static void SaveCustomColors() { CustomColorConfig customColorConfig = new CustomColorConfig { customColors = colorButtons.Where((FormatButtonData b) => !IsDefaultColor(b.TagKey)).ToList() }; try { string contents = JsonConvert.SerializeObject((object)customColorConfig, (Formatting)1); File.WriteAllText(ConfigFilePath, contents); } catch (Exception ex) { MelonLogger.Error("Failed to save custom colors: " + ex.Message); } } private static void LoadCustomColors(GameObject buttonPanel) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) if (!File.Exists(ConfigFilePath)) { return; } try { string text = File.ReadAllText(ConfigFilePath); CustomColorConfig customColorConfig = JsonConvert.DeserializeObject(text); foreach (FormatButtonData btn in customColorConfig.customColors) { formatTags[btn.TagKey] = btn.TagKey; if (!colorButtons.Any((FormatButtonData b) => b.TagKey == btn.TagKey)) { colorButtons.Add(btn); CreateColorButton(buttonPanel, btn.Label, btn.TagKey, btn.ButtonColor, isCustom: true); } } } catch (Exception ex) { MelonLogger.Error("Failed to load custom colors: " + ex.Message); } } private static bool IsDefaultColor(string tagKey) { if (1 == 0) { } bool result; switch (tagKey) { case "color=#FF5555": case "color=#55FF55": case "color=#5555FF": case "color=#FFFF55": case "color=#FF55FF": result = true; break; default: result = false; break; } if (1 == 0) { } return result; } [HarmonyPostfix] [HarmonyPatch("Open")] public static void AddFormattingUI(TextInputScreen __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Expected O, but got Unknown //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Expected O, but got Unknown //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Expected O, but got Unknown //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Expected O, but got Unknown //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Expected O, but got Unknown //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Expected O, but got Unknown //IL_05d8: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_0608: Unknown result type (might be due to invalid IL or missing references) //IL_0615: Unknown result type (might be due to invalid IL or missing references) //IL_0622: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Expected O, but got Unknown //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) inputField = __instance.InputField; inputField.characterLimit = 10000; formatButtons.Clear(); GameObject val = new GameObject("FormattingEditorContainer"); val.transform.SetParent(((Component)__instance.Canvas).transform, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0f); val2.anchorMax = new Vector2(0.5f, 0f); val2.pivot = new Vector2(0.5f, 0f); val2.anchoredPosition = new Vector2(0f, 160f); val2.sizeDelta = new Vector2(480f, 110f); VerticalLayoutGroup val3 = val.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val3).spacing = 5f; ((LayoutGroup)val3).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false; GameObject val4 = new GameObject("WarningText"); val4.transform.SetParent(val.transform, false); RectTransform val5 = val4.AddComponent(); val5.sizeDelta = new Vector2(480f, 35f); warningText = val4.AddComponent(); ((TMP_Text)warningText).text = "Warning: Text formatting works only on selections."; ((TMP_Text)warningText).fontSize = 14f; ((Graphic)warningText).color = new Color(1f, 1f, 1f); ((TMP_Text)warningText).alignment = (TextAlignmentOptions)514; ((TMP_Text)warningText).fontStyle = (FontStyles)1; RectTransform component = ((Component)warningText).GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; GameObject buttonPanel = new GameObject("FormattingButtons"); buttonPanel.transform.SetParent(val.transform, false); RectTransform val6 = buttonPanel.AddComponent(); val6.sizeDelta = new Vector2(480f, 50f); Image val7 = buttonPanel.AddComponent(); ((Graphic)val7).color = new Color(0.2f, 0.2f, 0.2f, 0.8f); HorizontalLayoutGroup val8 = buttonPanel.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val8).spacing = 8f; ((LayoutGroup)val8).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)val8).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)val8).childControlHeight = false; ((LayoutGroup)val8).padding = new RectOffset(10, 10, 5, 5); CreateFormatButton(buttonPanel, "B", "bold"); CreateFormatButton(buttonPanel, "I", "italic"); CreateFormatButton(buttonPanel, "U", "underline"); CreateFormatButton(buttonPanel, "S", "strikethrough"); CreateDivider(buttonPanel); foreach (FormatButtonData colorButton in colorButtons) { if (!formatTags.ContainsKey(colorButton.TagKey)) { formatTags[colorButton.TagKey] = colorButton.TagKey; } if (IsDefaultColor(colorButton.TagKey)) { CreateColorButton(buttonPanel, colorButton.Label, colorButton.TagKey, colorButton.ButtonColor); } else { CreateColorButton(buttonPanel, colorButton.Label, colorButton.TagKey, colorButton.ButtonColor, isCustom: true); } } GameObject val9 = new GameObject("CustomColorPanel"); val9.transform.SetParent(val.transform, false); RectTransform val10 = val9.AddComponent(); val10.sizeDelta = new Vector2(480f, 40f); HorizontalLayoutGroup val11 = val9.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val11).spacing = 10f; ((LayoutGroup)val11).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)val11).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)val11).childControlWidth = false; ((LayoutGroup)val11).padding = new RectOffset(10, 10, 5, 5); GameObject val12 = new GameObject("HexInputField"); val12.transform.SetParent(val9.transform, false); RectTransform val13 = val12.AddComponent(); val13.sizeDelta = new Vector2(150f, 35f); TMP_InputField hexInput = val12.AddComponent(); RectTransform val14 = new GameObject("Viewport").AddComponent(); ((Transform)val14).SetParent(((Component)hexInput).transform, false); hexInput.textViewport = val14; TextMeshProUGUI val15 = new GameObject("Text").AddComponent(); ((TMP_Text)val15).transform.SetParent((Transform)(object)val14, false); ((TMP_Text)val15).fontSize = 14f; ((TMP_Text)val15).alignment = (TextAlignmentOptions)4097; hexInput.textComponent = (TMP_Text)(object)val15; hexInput.text = "#FFFFFF"; GameObject val16 = new GameObject("AddColorButton"); val16.transform.SetParent(val9.transform, false); RectTransform val17 = val16.AddComponent(); val17.sizeDelta = new Vector2(100f, 35f); Button val18 = val16.AddComponent