Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RunicSigns v1.0.2
RunicSigns.dll
Decompiled 14 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using RunicSigns.Core; using RunicSigns.Input; using RunicSigns.Runtime; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("RunicSigns")] [assembly: AssemblyDescription("Simple synchronized labels and sizing for Valheim signs")] [assembly: AssemblyCompany("Chazman")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("1.0.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 RunicSigns { [BepInPlugin("chazman.RunicSigns", "RunicSigns", "1.0.2")] [BepInIncompatibility("chazman.BetterSigns")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "chazman.RunicSigns"; public const string Version = "1.0.2"; private Harmony _harmony; internal static ManualLogSource Log; private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModalGameplayInput.IsOpen = () => SignEditor.BlockGameplay; _harmony = new Harmony("chazman.RunicSigns"); _harmony.PatchAll(); ((Component)this).gameObject.AddComponent<SignEditor>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RunicSigns 1.0.2 loaded: vanilla signs, synchronized labels and size 0.25–4x."); } private void OnDestroy() { SignEditor.Close(); SignRuntime[] array = Object.FindObjectsByType<SignRuntime>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Object.Destroy((Object)(object)array[i]); } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } ModalGameplayInput.Reset(); } } } namespace RunicSigns.Input { internal static class ModalGameplayInput { internal static Func<bool> IsOpen; [ThreadStatic] private static int _cameraDepth; private static int _lastOpenFrame = -10; internal static bool Blocked { get { Func<bool> isOpen = IsOpen; if (isOpen != null && isOpen()) { _lastOpenFrame = Time.frameCount; return true; } return Time.frameCount <= _lastOpenFrame + 1; } } internal static bool CameraBlocked => _cameraDepth > 0; internal static void Reset() { IsOpen = null; _lastOpenFrame = -10; _cameraDepth = 0; } internal static void EnterCamera(bool blocked) { if (blocked) { _cameraDepth++; } } internal static void ExitCamera(bool blocked) { if (blocked) { _cameraDepth = Math.Max(0, _cameraDepth - 1); } } internal static bool GameplayAction(string name) { if (name != null) { if (!name.StartsWith("Hotbar", StringComparison.Ordinal)) { switch (name) { default: return name == "JoyGuardianPower"; case "JoyHotbarUse": case "Forward": case "Backward": case "Left": case "Right": case "Attack": case "JoyAttack": case "SecondaryAttack": case "JoySecondaryAttack": case "Block": case "JoyBlock": case "Jump": case "JoyJump": case "Crouch": case "JoyCrouch": case "Run": case "JoyRun": case "AutoRun": case "Dodge": case "JoyDodge": case "Use": case "JoyUse": case "Inventory": case "JoyInventory": case "Chat": case "Console": case "GuardianPower": break; } } return true; } return false; } } [HarmonyPatch(typeof(PlayerController), "TakeInput", new Type[] { typeof(bool) })] internal static class ModalControllerInputPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ref bool __result) { if (ModalGameplayInput.Blocked) { __result = false; } } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class ModalPlayerInputPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(Player __instance, ref bool __result) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && ModalGameplayInput.Blocked) { __result = false; } } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class ModalControlsPatch { [HarmonyPrefix] [HarmonyPriority(0)] private static void Prefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool jump, ref bool crouch, ref bool run, ref bool autoRun, ref bool dodge) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ModalGameplayInput.Blocked) { movedir = Vector3.zero; attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = (jump = (crouch = (run = (autoRun = (dodge = false)))))))))); } } } [HarmonyPatch] internal static class ModalCameraScopePatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in typeof(GameCamera).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.DeclaringType == typeof(GameCamera) && (m.Name == "UpdateCamera" || m.Name == "UpdateFreeFly") select m; } [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(out bool __state) { __state = ModalGameplayInput.Blocked; ModalGameplayInput.EnterCamera(__state); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception, bool __state) { ModalGameplayInput.ExitCamera(__state); return __exception; } } [HarmonyPatch] internal static class ModalCameraAxisPatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in typeof(ZInput).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.ReturnType == typeof(float) && (m.Name == "GetMouseScrollWheel" || m.Name.StartsWith("GetJoyLeftStick", StringComparison.Ordinal) || m.Name.StartsWith("GetJoyRightStick", StringComparison.Ordinal) || m.Name == "GetJoyLTrigger" || m.Name == "GetJoyRTrigger") select m; } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ref float __result) { if (ModalGameplayInput.CameraBlocked) { __result = 0f; } } } [HarmonyPatch(typeof(ZInput), "GetMouseDelta")] internal static class ModalCameraLookPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ref Vector2 __result) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (ModalGameplayInput.CameraBlocked) { __result = Vector2.zero; } } } [HarmonyPatch] internal static class ModalNamedActionPatch { private static IEnumerable<MethodBase> TargetMethods() { return ((IEnumerable<string>)new string[3] { "GetButton", "GetButtonDown", "GetButtonUp" }).Select((Func<string, MethodBase>)((string name) => AccessTools.Method(typeof(ZInput), name, new Type[1] { typeof(string) }, (Type[])null))); } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(string name, ref bool __result) { if (ModalGameplayInput.CameraBlocked || (ModalGameplayInput.Blocked && ModalGameplayInput.GameplayAction(name))) { __result = false; } } } [HarmonyPatch] internal static class ModalShortcutKeyPatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in typeof(ZInput).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.ReturnType == typeof(bool) && (m.Name == "GetKey" || m.Name == "GetKeyDown" || m.Name == "GetKeyUp") && m.GetParameters().Length != 0 && m.GetParameters()[0].ParameterType == typeof(KeyCode) select m; } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(KeyCode key, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if ((int)key != 27 && ((int)key < 323 || (int)key > 329) && ModalGameplayInput.Blocked) { __result = false; } } } } namespace RunicSigns.Runtime { internal static class SignAccess { private static readonly FieldInfo Areas = AccessTools.Field(typeof(PrivateArea), "m_allAreas"); private static readonly MethodInfo Permitted = AccessTools.Method(typeof(PrivateArea), "IsPermitted", (Type[])null, (Type[])null); internal static bool Eligible(Sign sign) { if (Object.op_Implicit((Object)(object)sign) && Object.op_Implicit((Object)(object)((Component)sign).GetComponent<Piece>()) && Object.op_Implicit((Object)(object)((Component)sign).GetComponent<ZNetView>()) && ((Component)sign).GetComponent<ZNetView>().IsValid()) { return Utils.GetPrefabName(((Component)sign).gameObject) == "sign"; } return false; } internal static bool Local(Sign sign) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (Eligible(sign) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && !((Character)Player.m_localPlayer).IsDead() && Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)sign).transform.position) <= 5f) { return PrivateArea.CheckAccess(((Component)sign).transform.position, 0f, false, false); } return false; } internal static bool Sender(Sign sign, long sender) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if (sender == ZNet.GetUID()) { return Local(sign); } Player val = ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)delegate(Player p) { if (Object.op_Implicit((Object)(object)p)) { ZNetView component2 = ((Component)p).GetComponent<ZNetView>(); if (component2 == null) { return false; } ZDO zDO = component2.GetZDO(); return ((zDO != null) ? new long?(zDO.GetOwner()) : ((long?)null)) == sender; } return false; }); if (!Object.op_Implicit((Object)(object)val) || ((Character)val).IsDead() || Vector3.Distance(((Component)val).transform.position, ((Component)sign).transform.position) > 5f) { return false; } if (Areas == null || Permitted == null) { return false; } if (!(Areas.GetValue(null) is List<PrivateArea> list)) { return false; } bool flag = false; foreach (PrivateArea item in list) { object obj; if (!Object.op_Implicit((Object)(object)item)) { obj = null; } else { ZNetView component = ((Component)item).GetComponent<ZNetView>(); obj = ((component != null) ? component.GetZDO() : null); } ZDO val2 = (ZDO)obj; if (val2 != null && val2.GetBool(ZDOVars.s_enabled, false) && !(Utils.DistanceXZ(((Component)item).transform.position, ((Component)sign).transform.position) >= item.m_radius)) { flag = true; if (((Component)item).GetComponent<Piece>().GetCreator() == val.GetPlayerID() || (bool)Permitted.Invoke(item, new object[1] { val.GetPlayerID() })) { return true; } } } return !flag; } } internal sealed class SignEditor : MonoBehaviour { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; } private static SignEditor _instance; private GameObject _canvas; private Sign _sign; private SignRuntime _runtime; private SignSettings _draft; private string _expectedStyle; private string _expectedText; private TMP_FontAsset _font; private TMP_InputField _caption; private TMP_InputField _color; private TMP_Text _status; private TMP_Text _preview; private TMP_Text _sizeLabel; private TMP_Text _fontLabel; private TMP_Text _positionLabel; private TMP_Text _colorLabel; private Image _previewBackground; private Button _save; private CanvasGroup _fields; private TMP_Text _backgroundLabel; private TMP_Text _alignmentLabel; private TMP_Text _boldLabel; private bool _oldCursorVisible; private CursorLockMode _oldCursorLock; private bool _closing; private static bool _pollingCancel; private static int _cancelFrame = -10; private static readonly EditorInputState InputState = new EditorInputState(); internal static bool IsOpen { get { if (InputState.IsOpen && Object.op_Implicit((Object)(object)_instance) && ((Behaviour)_instance).isActiveAndEnabled && Object.op_Implicit((Object)(object)_instance._canvas)) { return _instance._canvas.activeInHierarchy; } return false; } } internal static bool BlockGameplay => IsOpen; internal static bool SuppressCancel { get { if (!_pollingCancel) { if (!IsOpen) { return Time.frameCount == _cancelFrame; } return true; } return false; } } private void Awake() { InputState.Reset(); _instance = this; } internal static void Open(Sign sign) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_instance) || !SignAccess.Local(sign)) { return; } Close(); SignEditor instance = _instance; instance._runtime = SignRuntime.Attach(sign); if (!Object.op_Implicit((Object)(object)instance._runtime)) { return; } instance._expectedStyle = instance._runtime.Raw; instance._expectedText = instance._runtime.NativeText; if (!SignSettings.TryDecode(instance._expectedStyle, out instance._draft)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "This sign uses unrecognized settings. Its saved data was preserved.", 0, (Sprite)null, false); return; } instance._sign = sign; instance._font = ((TMP_Text)sign.m_textWidget).font; instance._oldCursorVisible = Cursor.visible; instance._oldCursorLock = Cursor.lockState; try { instance.Build(sign.GetText()); instance.Refresh(); instance._canvas.SetActive(true); InputState.Open(); instance.RenewCursor(); } catch (Exception ex) { Close(); Plugin.Log.LogError((object)("Sign editor could not open; gameplay controls released: " + ex)); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "The sign editor could not open. Your controls have been restored.", 0, (Sprite)null, false); } } } private void Update() { if (!InputState.IsOpen) { return; } try { if (!IsOpen || !Object.op_Implicit((Object)(object)_sign) || !Object.op_Implicit((Object)(object)_runtime) || !SignAccess.Local(_sign)) { Close(); return; } _pollingCancel = true; bool flag; try { flag = ZInput.GetKeyDown((KeyCode)27, false) || ZInput.GetButtonDown("JoyButtonB"); } finally { _pollingCancel = false; } if (flag) { _cancelFrame = Time.frameCount; Close(); } else { _fields.interactable = !_runtime.Saving; ((Selectable)_save).interactable = !_runtime.Saving; RenewCursor(); } } catch (Exception ex) { Close(); Plugin.Log.LogError((object)("Sign editor failed; gameplay controls released: " + ex)); } } private void LateUpdate() { if (IsOpen) { RenewCursor(); } } private void RenewCursor() { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } internal static void KeepCursor() { if (IsOpen) { _instance.RenewCursor(); } } internal static void Close() { //IL_0162: Unknown result type (might be due to invalid IL or missing references) SignEditor instance = _instance; if (!Object.op_Implicit((Object)(object)instance)) { InputState.Reset(); } else { if (instance._closing) { return; } instance._closing = true; bool flag = Object.op_Implicit((Object)(object)instance._canvas); InputState.Close(Time.unscaledTime, 0u); try { uint num = 0u; for (int i = 0; i < EditorInputState.ClosingActions.Length; i++) { ZInput instance2 = ZInput.instance; if (instance2 != null) { ButtonDef buttonDef = instance2.GetButtonDef(EditorInputState.ClosingActions[i]); if (((buttonDef != null) ? new bool?(buttonDef.Held) : ((bool?)null)) == true) { num |= (uint)(1 << i); } } } InputState.Close(Time.unscaledTime, num); if (Object.op_Implicit((Object)(object)instance._runtime)) { instance._runtime.CancelSave(); } if (Object.op_Implicit((Object)(object)instance._caption)) { instance._caption.DeactivateInputField(false); } if (Object.op_Implicit((Object)(object)instance._color)) { instance._color.DeactivateInputField(false); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Sign editor cleanup skipped a failed callback: " + ex.Message)); } finally { GameObject canvas = instance._canvas; instance._canvas = null; instance._sign = null; instance._runtime = null; instance._caption = (instance._color = null); instance._closing = false; if (flag) { Cursor.visible = instance._oldCursorVisible; Cursor.lockState = instance._oldCursorLock; } if (Object.op_Implicit((Object)(object)canvas)) { canvas.SetActive(false); Object.Destroy((Object)(object)canvas); } } } } private void OnDisable() { if ((Object)(object)_instance == (Object)(object)this) { Close(); } } private void OnDestroy() { Close(); InputState.Reset(); if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } internal static bool SuppressClosingAction(string name) { EditorInputState inputState = InputState; ZInput instance = ZInput.instance; int held; if (instance == null) { held = 0; } else { ButtonDef buttonDef = instance.GetButtonDef(name); held = ((((buttonDef != null) ? new bool?(buttonDef.Held) : ((bool?)null)) == true) ? 1 : 0); } return inputState.SuppressClosingAction(name, (byte)held != 0, Time.unscaledTime); } private void Build(string caption) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Expected O, but got Unknown //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Expected O, but got Unknown //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Expected O, but got Unknown //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Expected O, but got Unknown //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Expected O, but got Unknown //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Expected O, but got Unknown //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Expected O, but got Unknown //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Expected O, but got Unknown //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Expected O, but got Unknown //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Expected O, but got Unknown //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Expected O, but got Unknown //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Expected O, but got Unknown //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_062f: Expected O, but got Unknown //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Expected O, but got Unknown //IL_067f: Unknown result type (might be due to invalid IL or missing references) //IL_0689: Expected O, but got Unknown //IL_06ac: Unknown result type (might be due to invalid IL or missing references) //IL_06b6: Expected O, but got Unknown //IL_0704: Unknown result type (might be due to invalid IL or missing references) //IL_07b8: Unknown result type (might be due to invalid IL or missing references) //IL_07c2: Expected O, but got Unknown //IL_07f2: Unknown result type (might be due to invalid IL or missing references) //IL_07f7: Unknown result type (might be due to invalid IL or missing references) //IL_07fd: Expected O, but got Unknown _canvas = new GameObject("RunicSignsEditor", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); _canvas.SetActive(false); Canvas component = _canvas.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 2000; CanvasScaler component2 = _canvas.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1000f, 820f); component2.screenMatchMode = (ScreenMatchMode)1; Image val = Box(_canvas.transform, "Shade", 0f, 0f, 0f, 0f, new Color(0f, 0f, 0f, 0.7f)); ((Graphic)val).rectTransform.anchorMin = Vector2.zero; ((Graphic)val).rectTransform.anchorMax = Vector2.one; RectTransform rectTransform = ((Graphic)val).rectTransform; Vector2 offsetMin = (((Graphic)val).rectTransform.offsetMax = Vector2.zero); rectTransform.offsetMin = offsetMin; RectTransform rectTransform2 = ((Graphic)Box(_canvas.transform, "Panel", 0f, 0f, 800f, 744f, new Color(0.085f, 0.095f, 0.1f, 1f))).rectTransform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); rectTransform2.pivot = val2; offsetMin = (rectTransform2.anchorMax = val2); rectTransform2.anchorMin = offsetMin; Text((Transform)(object)rectTransform2, "Runic Signs", 28f, 18f, 600f, 40f, 28); ((Graphic)Text((Transform)(object)rectTransform2, "A caption. A color. The right size.", 28f, 61f, 744f, 28f, 17)).color = new Color(0.7f, 0.74f, 0.75f); RectTransform val4 = Rect("Fields", (Transform)(object)rectTransform2, 0f, 100f, 800f, 490f); _fields = ((Component)val4).gameObject.AddComponent<CanvasGroup>(); Text((Transform)(object)val4, "Caption", 28f, 0f, 744f, 24f); _caption = Input((Transform)(object)val4, caption, "Write your sign…", 28f, 30f, 744f, 88f, 256, multi: true); ((UnityEvent<string>)(object)_caption.onValueChanged).AddListener((UnityAction<string>)delegate { Refresh(); }); _sizeLabel = Text((Transform)(object)val4, "", 28f, 135f, 250f, 32f); Button((Transform)(object)val4, "−", 288f, 135f, 48f, 34f, (UnityAction)delegate { Adjust(board: true, -0.25f); }); Button((Transform)(object)val4, "+", 344f, 135f, 48f, 34f, (UnityAction)delegate { Adjust(board: true, 0.25f); }); Button((Transform)(object)val4, "1×", 400f, 135f, 62f, 34f, (UnityAction)delegate { _draft.Scale = 1f; Refresh(); }); Text((Transform)(object)val4, "Whole sign · 0.25× to 4×", 484f, 135f, 288f, 32f, 16); _fontLabel = Text((Transform)(object)val4, "", 28f, 181f, 250f, 32f); Button((Transform)(object)val4, "−", 288f, 181f, 48f, 34f, (UnityAction)delegate { Adjust(board: false, -0.1f); }); Button((Transform)(object)val4, "+", 344f, 181f, 48f, 34f, (UnityAction)delegate { Adjust(board: false, 0.1f); }); Button((Transform)(object)val4, "1×", 400f, 181f, 62f, 34f, (UnityAction)delegate { _draft.TextSize = 1f; Refresh(); }); Text((Transform)(object)val4, "Long captions shrink to fit", 484f, 181f, 288f, 32f, 16); _colorLabel = Text((Transform)(object)val4, "Color", 28f, 231f, 260f, 28f); _color = Input((Transform)(object)val4, LabelColors.Names[_draft.Color], "Color name", 288f, 226f, 174f, 36f, 32, multi: false); ((UnityEvent<string>)(object)_color.onEndEdit).AddListener((UnityAction<string>)delegate(string value) { _draft.Color = LabelColors.Resolve(value); _color.SetTextWithoutNotify(LabelColors.Names[_draft.Color]); Refresh(); }); Button((Transform)(object)val4, "‹", 484f, 226f, 44f, 36f, (UnityAction)delegate { CycleColor(-1); }); Button((Transform)(object)val4, "›", 536f, 226f, 44f, 36f, (UnityAction)delegate { CycleColor(1); }); _boldLabel = ((Component)Button((Transform)(object)val4, "", 592f, 226f, 180f, 36f, (UnityAction)delegate { _draft.Bold = !_draft.Bold; Refresh(); })).GetComponentInChildren<TMP_Text>(); _backgroundLabel = ((Component)Button((Transform)(object)val4, "", 28f, 276f, 358f, 38f, (UnityAction)delegate { _draft.Background = (_draft.Background + 1) % 3; Refresh(); })).GetComponentInChildren<TMP_Text>(); _alignmentLabel = ((Component)Button((Transform)(object)val4, "", 402f, 276f, 370f, 38f, (UnityAction)delegate { _draft.Alignment = (_draft.Alignment + 1) % 3; Refresh(); })).GetComponentInChildren<TMP_Text>(); _positionLabel = Text((Transform)(object)val4, "", 28f, 329f, 280f, 32f, 17); Button((Transform)(object)val4, "←", 316f, 329f, 48f, 34f, (UnityAction)delegate { Move(-0.05f, 0f); }); Button((Transform)(object)val4, "→", 372f, 329f, 48f, 34f, (UnityAction)delegate { Move(0.05f, 0f); }); Button((Transform)(object)val4, "↓", 428f, 329f, 48f, 34f, (UnityAction)delegate { Move(0f, -0.05f); }); Button((Transform)(object)val4, "↑", 484f, 329f, 48f, 34f, (UnityAction)delegate { Move(0f, 0.05f); }); Button((Transform)(object)val4, "Center", 548f, 329f, 224f, 34f, (UnityAction)delegate { _draft.Horizontal = (_draft.Vertical = 0f); Refresh(); }); Text((Transform)(object)val4, "Text preview", 28f, 382f, 744f, 24f, 16); _previewBackground = Box((Transform)(object)val4, "Preview", 28f, 412f, 744f, 72f, new Color(0.2f, 0.15f, 0.1f)); _preview = Text(((Component)_previewBackground).transform, "", 12f, 2f, 720f, 68f, 28); _preview.enableAutoSizing = true; _preview.fontSizeMin = 8f; _status = Text((Transform)(object)rectTransform2, "Changes apply when you save. Escape or Cancel discards the draft.", 28f, 604f, 744f, 48f, 16); _status.textWrappingMode = (TextWrappingModes)1; _save = Button((Transform)(object)rectTransform2, "Save sign", 28f, 670f, 358f, 44f, new UnityAction(Save)); object obj = <>O.<0>__Close; if (obj == null) { UnityAction val5 = Close; <>O.<0>__Close = val5; obj = (object)val5; } Button((Transform)(object)rectTransform2, "Cancel", 402f, 670f, 370f, 44f, (UnityAction)obj); } private void Adjust(bool board, float delta) { if (board) { _draft.Scale = Mathf.Clamp(Mathf.Round((_draft.Scale + delta) * 100f) / 100f, 0.25f, 4f); } else { _draft.TextSize = Mathf.Clamp(Mathf.Round((_draft.TextSize + delta) * 100f) / 100f, 0.3f, 3f); } Refresh(); } private void Move(float x, float y) { _draft.Horizontal = Mathf.Clamp(Mathf.Round((_draft.Horizontal + x) * 100f) / 100f, -0.4f, 0.4f); _draft.Vertical = Mathf.Clamp(Mathf.Round((_draft.Vertical + y) * 100f) / 100f, -0.4f, 0.4f); Refresh(); } private void CycleColor(int direction) { _draft.Color = (_draft.Color + direction + LabelColors.Names.Length) % LabelColors.Names.Length; _color.SetTextWithoutNotify(LabelColors.Names[_draft.Color]); Refresh(); } private void Refresh() { //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_preview)) { _sizeLabel.text = $"Sign size {_draft.Scale:0.##}×"; _fontLabel.text = $"Text size {_draft.TextSize:0.##}×"; _colorLabel.text = "Color " + LabelColors.Names[_draft.Color]; _backgroundLabel.text = "Background: " + (new string[3] { "Transparent", "White", "Black" })[_draft.Background]; _alignmentLabel.text = "Align: " + (new string[3] { "Left", "Center", "Right" })[_draft.Alignment]; _boldLabel.text = "Bold: " + (_draft.Bold ? "On" : "Off"); _positionLabel.text = $"Text offset {_draft.Horizontal:0.##}, {_draft.Vertical:0.##}"; _preview.text = (string.IsNullOrEmpty(_caption.text) ? "Your caption" : _caption.text); Color color = default(Color); ColorUtility.TryParseHtmlString(LabelColors.Hex[_draft.Color], ref color); ((Graphic)_preview).color = color; _preview.fontStyle = (FontStyles)(_draft.Bold ? 1 : 0); _preview.fontSizeMax = 28f * _draft.TextSize; _preview.alignment = (TextAlignmentOptions)((_draft.Alignment == 0) ? 513 : ((_draft.Alignment == 2) ? 516 : 514)); ((Graphic)_previewBackground).color = (Color)((_draft.Background == 1) ? Color.white : ((_draft.Background == 2) ? Color.black : new Color(0.2f, 0.15f, 0.1f))); } } private void Save() { if (!Object.op_Implicit((Object)(object)_runtime) || _runtime.Saving) { return; } _draft.Color = LabelColors.Resolve(_color.text); Refresh(); _status.text = "Saving…"; _runtime.BeginSave(_draft, _caption.text.Replace("\r\n", "\n"), _expectedStyle, _expectedText, delegate(bool success, string message) { if (Object.op_Implicit((Object)(object)_canvas) && !_closing) { if (success) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "Sign saved.", 0, (Sprite)null, false); } Close(); } else { _status.text = message; } } }); } private static RectTransform Rect(string name, Transform parent, float x, float y, float width, float height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.pivot = val3; Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; val2.anchoredPosition = new Vector2(x, 0f - y); val2.sizeDelta = new Vector2(width, height); return val2; } private static Image Box(Transform parent, string name, float x, float y, float w, float h, Color color) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)Rect(name, parent, x, y, w, h)).gameObject.AddComponent<Image>(); ((Graphic)obj).color = color; return obj; } private TMP_Text Text(Transform parent, string value, float x, float y, float w, float h, int size = 19) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI obj = ((Component)Rect("Text", parent, x, y, w, h)).gameObject.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = _font; ((TMP_Text)obj).text = value; ((TMP_Text)obj).fontSize = size; ((Graphic)obj).color = new Color(0.94f, 0.89f, 0.77f); ((TMP_Text)obj).richText = false; ((Graphic)obj).raycastTarget = false; ((TMP_Text)obj).alignment = (TextAlignmentOptions)4097; ((TMP_Text)obj).overflowMode = (TextOverflowModes)1; return (TMP_Text)(object)obj; } private Button Button(Transform parent, string caption, float x, float y, float w, float h, UnityAction action) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Image val = Box(parent, caption, x, y, w, h, new Color(0.22f, 0.25f, 0.26f)); Button obj = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)val; ((UnityEvent)obj.onClick).AddListener(action); Text(((Component)val).transform, caption, 6f, 0f, w - 12f, h).alignment = (TextAlignmentOptions)514; return obj; } private TMP_InputField Input(Transform parent, string value, string hint, float x, float y, float w, float h, int limit, bool multi) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) Image val = Box(parent, "Input", x, y, w, h, new Color(0.04f, 0.045f, 0.05f)); TMP_InputField obj = ((Component)val).gameObject.AddComponent<TMP_InputField>(); ((Selectable)obj).targetGraphic = (Graphic)(object)val; obj.richText = false; obj.characterLimit = limit; obj.lineType = (LineType)(multi ? 2 : 0); RectTransform val2 = Rect("Viewport", ((Component)val).transform, 10f, 4f, w - 20f, h - 8f); ((Component)val2).gameObject.AddComponent<RectMask2D>(); TMP_Text val3 = Text((Transform)(object)val2, "", 0f, 0f, w - 20f, h - 8f); val3.textWrappingMode = (TextWrappingModes)1; val3.alignment = (TextAlignmentOptions)(multi ? 257 : 4097); TMP_Text val4 = Text((Transform)(object)val2, hint, 0f, 0f, w - 20f, h - 8f); ((Graphic)val4).color = Color.gray; obj.textViewport = val2; obj.textComponent = val3; obj.placeholder = (Graphic)(object)val4; obj.SetTextWithoutNotify(value); return obj; } } [HarmonyPatch(typeof(ZInput), "GetKeyDown", new Type[] { typeof(KeyCode), typeof(bool) })] internal static class SignEscapeGuard { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(KeyCode key, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)key == 27 && SignEditor.SuppressCancel) { __result = false; } } } [HarmonyPatch(typeof(ZInput), "GetButtonDown", new Type[] { typeof(string) })] internal static class SignControllerCancelGuard { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(string name, ref bool __result) { if (name == "JoyButtonB" && SignEditor.SuppressCancel) { __result = false; } } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] internal static class SignCursorGuard { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix() { SignEditor.KeepCursor(); } } [HarmonyPatch] internal static class SignClosingActionGuard { private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[3] { "GetButton", "GetButtonDown", "GetButtonUp" }; foreach (string text in array) { yield return AccessTools.Method(typeof(ZInput), text, new Type[1] { typeof(string) }, (Type[])null); } } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(string name, ref bool __result) { if (SignEditor.SuppressClosingAction(name)) { __result = false; } } } internal sealed class SignRuntime : MonoBehaviour { internal const string SettingsKey = "RunicSigns.Settings.v1"; private const string LeaseKey = "RunicSigns.SaveLease.v1"; private const string ExpiryKey = "RunicSigns.SaveExpiry.v1"; private const string RequestRpc = "RunicSigns_RequestSave_v1"; private const string ResponseRpc = "RunicSigns_SaveResponse_v1"; private Sign _sign; private ZNetView _view; private Vector3 _baseScale; private Vector2 _baseTextPosition; private float _baseFontSize; private float _baseFontMin; private float _baseFontMax; private bool _baseAutoSize; private bool _baseRichText; private Color _baseColor; private FontStyles _baseStyle; private TextAlignmentOptions _baseAlignment; private Image _background; private string _rendered; private float _next; private string _pendingToken; private string _expectedStyle; private string _expectedText; private string _newStyle; private string _newText; private long _requestedOwner; private float _requestDeadline; private bool _granted; private bool _nativeWrite; private Action<bool, string> _completion; internal bool Saving => _pendingToken != null; internal string Raw => _view.GetZDO().GetString("RunicSigns.Settings.v1", ""); internal string NativeText => _view.GetZDO().GetString(ZDOVars.s_text, _sign.m_defaultText); private double Now => ZNet.instance.GetTimeSeconds(); private bool Busy => EditPolicy.LeaseActive(_view.GetZDO().GetString("RunicSigns.SaveLease.v1", ""), (double)_view.GetZDO().GetLong("RunicSigns.SaveExpiry.v1", 0L) / 1000.0, Now); internal bool AllowNativeWrite { get { if (!_nativeWrite) { return !Busy; } return true; } } internal static SignRuntime Attach(Sign sign) { if (!SignAccess.Eligible(sign)) { return null; } return ((Component)sign).GetComponent<SignRuntime>() ?? ((Component)sign).gameObject.AddComponent<SignRuntime>(); } private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00a9: Unknown result type (might be due to invalid IL or missing references) _sign = ((Component)this).GetComponent<Sign>(); _view = ((Component)this).GetComponent<ZNetView>(); _baseScale = ((Component)this).transform.localScale; TextMeshProUGUI textWidget = _sign.m_textWidget; if (Object.op_Implicit((Object)(object)textWidget)) { _baseFontSize = ((TMP_Text)textWidget).fontSize; _baseFontMin = ((TMP_Text)textWidget).fontSizeMin; _baseFontMax = ((TMP_Text)textWidget).fontSizeMax; _baseAutoSize = ((TMP_Text)textWidget).enableAutoSizing; _baseRichText = ((TMP_Text)textWidget).richText; _baseColor = ((Graphic)textWidget).color; _baseStyle = ((TMP_Text)textWidget).fontStyle; _baseAlignment = ((TMP_Text)textWidget).alignment; _baseTextPosition = ((TMP_Text)textWidget).rectTransform.anchoredPosition; } _view.Register<string, string, string>("RunicSigns_RequestSave_v1", (Action<long, string, string, string>)RequestSave); _view.Register<string, string>("RunicSigns_SaveResponse_v1", (Action<long, string, string>)SaveResponse); Render(); } private void Update() { if (!Object.op_Implicit((Object)(object)_view) || !_view.IsValid()) { CancelSave(); return; } if (Saving) { if (Time.unscaledTime > _requestDeadline) { Finish(success: false, "Save timed out. Your draft is still here; wait a moment and try again."); } else if (_granted && _view.IsOwner() && _view.GetZDO().GetString("RunicSigns.SaveLease.v1", "") == _pendingToken) { Commit(); } } if (Time.unscaledTime >= _next) { _next = Time.unscaledTime + 0.25f; Render(); } } internal void BeginSave(SignSettings settings, string text, string expectedStyle, string expectedText, Action<bool, string> completion) { if (!Saving) { if (!SignAccess.Local(_sign) || !settings.Valid || !SignSettings.ValidText(text)) { completion(arg1: false, "Check sign access and caption (maximum 256 characters)."); return; } _expectedStyle = expectedStyle; _expectedText = expectedText; _newStyle = settings.Encode(); _newText = text; _completion = completion; _pendingToken = Guid.NewGuid().ToString("N"); _requestedOwner = _view.GetZDO().GetOwner(); _granted = false; _requestDeadline = Time.unscaledTime + 8f; _view.InvokeRPC(_requestedOwner, "RunicSigns_RequestSave_v1", new object[3] { _pendingToken, expectedStyle, expectedText }); } } private void RequestSave(long sender, string token, string expectedStyle, string expectedText) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (!_view.IsOwner() || !Guid.TryParseExact(token, "N", out var _) || expectedStyle == null || expectedStyle.Length > 160 || expectedText == null || expectedText.Length > 4096) { return; } string text = EditPolicy.Reject(expectedStyle, Raw, expectedText, NativeText, SignAccess.Sender(_sign, sender), Busy); if (text.Length == 0) { ZDO zDO = _view.GetZDO(); zDO.Set("RunicSigns.SaveLease.v1", token); zDO.Set("RunicSigns.SaveExpiry.v1", (long)((Now + 12.0) * 1000.0)); zDO.SetOwner(sender); if (sender != ZNet.GetUID()) { ZDOMan.instance.ForceSendZDO(sender, zDO.m_uid); } } _view.InvokeRPC(sender, "RunicSigns_SaveResponse_v1", new object[2] { token, text }); } private void SaveResponse(long sender, string token, string error) { if (Saving && !(token != _pendingToken) && sender == _requestedOwner) { if (!string.IsNullOrEmpty(error)) { Finish(success: false, error); } else { _granted = true; } } } private void Commit() { string text = EditPolicy.Reject(_expectedStyle, Raw, _expectedText, NativeText, SignAccess.Local(_sign), !Busy); if (text.Length != 0) { Finish(success: false, text); return; } try { _nativeWrite = true; _sign.SetText(_newText); if (NativeText != _newText) { Finish(success: false, "Valheim rejected the caption. Check ward access."); return; } _view.GetZDO().Set("RunicSigns.Settings.v1", _newStyle); Render(); Finish(Raw == _newStyle, (Raw == _newStyle) ? "Saved." : "Settings could not be verified. Reopen the sign."); } catch (Exception ex) { Plugin.Log.LogError((object)("Sign save failed: " + ex)); Finish(success: false, "Save failed. Reopen the sign to check its current state."); } finally { _nativeWrite = false; } } internal void CancelSave() { if (Saving) { Finish(success: false, "Save cancelled."); } } private void Finish(bool success, string message) { if (Object.op_Implicit((Object)(object)_view) && _view.IsValid() && _view.IsOwner() && _view.GetZDO().GetString("RunicSigns.SaveLease.v1", "") == _pendingToken) { _view.GetZDO().Set("RunicSigns.SaveLease.v1", ""); _view.GetZDO().Set("RunicSigns.SaveExpiry.v1", 0L); } Action<bool, string> completion = _completion; _completion = null; _pendingToken = null; _granted = false; completion?.Invoke(success, message); } internal void Render() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_01e4: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_view) || !_view.IsValid()) { return; } string raw = Raw; if (raw == _rendered) { return; } _rendered = raw; if (!SignSettings.TryDecode(raw, out var settings)) { Restore(); Plugin.Log.LogWarning((object)"Unrecognized RunicSigns data preserved; sign uses its original appearance."); return; } if (raw.Length == 0) { Restore(); return; } ((Component)this).transform.localScale = _baseScale * settings.Scale; TextMeshProUGUI textWidget = _sign.m_textWidget; if (Object.op_Implicit((Object)(object)textWidget)) { ((TMP_Text)textWidget).richText = false; Color color = default(Color); ColorUtility.TryParseHtmlString(LabelColors.Hex[settings.Color], ref color); ((Graphic)textWidget).color = color; ((TMP_Text)textWidget).fontStyle = (FontStyles)((settings.Bold ? 1 : 0) | (settings.Italic ? 2 : 0)); ((TMP_Text)textWidget).alignment = (TextAlignmentOptions)((settings.Alignment == 0) ? 513 : ((settings.Alignment == 2) ? 516 : 514)); ((TMP_Text)textWidget).enableAutoSizing = true; ((TMP_Text)textWidget).fontSizeMax = _baseFontSize * settings.TextSize; ((TMP_Text)textWidget).fontSizeMin = Mathf.Min(((TMP_Text)textWidget).fontSizeMax, Mathf.Max(1f, _baseFontSize * 0.25f)); ((TMP_Text)textWidget).fontSize = ((TMP_Text)textWidget).fontSizeMax; RectTransform rectTransform = ((TMP_Text)textWidget).rectTransform; Vector2 baseTextPosition = _baseTextPosition; Rect rect = ((TMP_Text)textWidget).rectTransform.rect; rectTransform.anchoredPosition = baseTextPosition + Vector2.Scale(((Rect)(ref rect)).size, new Vector2(settings.Horizontal, settings.Vertical)); if (!Object.op_Implicit((Object)(object)_background) && settings.Background != 0) { GameObject val = new GameObject("RunicSignsBackground", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(((TMP_Text)textWidget).transform.parent, false); _background = val.GetComponent<Image>(); ((Graphic)_background).raycastTarget = false; RectTransform rectTransform2 = ((Graphic)_background).rectTransform; RectTransform rectTransform3 = ((TMP_Text)textWidget).rectTransform; rectTransform2.anchorMin = rectTransform3.anchorMin; rectTransform2.anchorMax = rectTransform3.anchorMax; rectTransform2.pivot = rectTransform3.pivot; rectTransform2.sizeDelta = rectTransform3.sizeDelta; ((Transform)rectTransform2).localRotation = ((Transform)rectTransform3).localRotation; ((Transform)rectTransform2).localScale = ((Transform)rectTransform3).localScale; ((Transform)rectTransform2).localPosition = ((Transform)rectTransform3).localPosition; rectTransform2.anchoredPosition = _baseTextPosition; ((Transform)rectTransform2).SetSiblingIndex(((Transform)rectTransform3).GetSiblingIndex()); } if (Object.op_Implicit((Object)(object)_background)) { ((Component)_background).gameObject.SetActive(settings.Background != 0); ((Graphic)_background).color = ((settings.Background == 1) ? Color.white : Color.black); } } } private void Restore() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.localScale = _baseScale; if (Object.op_Implicit((Object)(object)_background)) { ((Component)_background).gameObject.SetActive(false); } TextMeshProUGUI textWidget = _sign.m_textWidget; if (Object.op_Implicit((Object)(object)textWidget)) { ((TMP_Text)textWidget).fontSize = _baseFontSize; ((TMP_Text)textWidget).fontSizeMin = _baseFontMin; ((TMP_Text)textWidget).fontSizeMax = _baseFontMax; ((TMP_Text)textWidget).enableAutoSizing = _baseAutoSize; ((TMP_Text)textWidget).richText = _baseRichText; ((Graphic)textWidget).color = _baseColor; ((TMP_Text)textWidget).fontStyle = _baseStyle; ((TMP_Text)textWidget).alignment = _baseAlignment; ((TMP_Text)textWidget).rectTransform.anchoredPosition = _baseTextPosition; } } private void OnDestroy() { CancelSave(); Restore(); if (Object.op_Implicit((Object)(object)_background)) { Object.Destroy((Object)(object)((Component)_background).gameObject); } if (Object.op_Implicit((Object)(object)_view)) { _view.Unregister("RunicSigns_RequestSave_v1"); _view.Unregister("RunicSigns_SaveResponse_v1"); } } } [HarmonyPatch] internal static class SignPatches { [HarmonyPostfix] [HarmonyPatch(typeof(Sign), "Awake")] private static void Attach(Sign __instance) { SignRuntime.Attach(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(TextInput), "RequestText")] private static bool Edit(TextReceiver sign) { Sign val = (Sign)(object)((sign is Sign) ? sign : null); if (val == null || !SignAccess.Eligible(val)) { return true; } SignEditor.Open(val); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Sign), "SetText")] private static bool ProtectSave(Sign __instance) { SignRuntime component = ((Component)__instance).GetComponent<SignRuntime>(); if (Object.op_Implicit((Object)(object)component)) { return component.AllowNativeWrite; } return true; } } } namespace RunicSigns.Core { internal sealed class EditorInputState { internal static readonly string[] ClosingActions = new string[7] { "Attack", "JoyAttack", "SecondaryAttack", "JoySecondaryAttack", "Use", "JoyUse", "JoyButtonB" }; private uint _heldAtClose; private float _releaseDeadline; internal bool IsOpen { get; private set; } internal void Open() { IsOpen = true; _heldAtClose = 0u; } internal void Close(float now, uint heldAtClose) { IsOpen = false; _heldAtClose = heldAtClose; _releaseDeadline = now + 1f; } internal bool SuppressClosingAction(string name, bool held, float now) { if (IsOpen || now >= _releaseDeadline) { _heldAtClose = 0u; return false; } int num = Array.IndexOf(ClosingActions, name); if (num < 0) { return false; } uint num2 = (uint)(1 << num); if (!held) { _heldAtClose &= ~num2; } return (_heldAtClose & num2) != 0; } internal void Reset() { IsOpen = false; _heldAtClose = 0u; _releaseDeadline = 0f; } } internal static class EditPolicy { internal const double LeaseSeconds = 12.0; internal static bool LeaseActive(string token, double expiry, double now) { if (!string.IsNullOrEmpty(token) && !double.IsNaN(expiry) && !double.IsInfinity(expiry) && expiry > now) { return expiry <= now + 12.0 + 2.0; } return false; } internal static string Reject(string expectedStyle, string actualStyle, string expectedText, string actualText, bool hasAccess, bool busy) { if (!hasAccess) { return "Sign access is unavailable. Move closer and check ward permissions."; } if (busy) { return "Another save is in progress. Wait a moment and try again."; } if (!string.Equals(expectedStyle, actualStyle, StringComparison.Ordinal) || !string.Equals(expectedText, actualText, StringComparison.Ordinal)) { return "This sign changed while you were editing. Copy your caption, then reopen the editor."; } return ""; } } internal static class LabelColors { internal static readonly string[] Names = new string[22] { "Red", "Cyan", "Blue", "Darkblue", "Lightblue", "Purple", "Yellow", "Lime", "Fuchsia", "White", "Silver", "Grey", "Black", "Orange", "Brown", "Maroon", "Green", "Olive", "Navy", "Teal", "Aqua", "Magenta" }; internal static readonly string[] Hex = new string[22] { "#FF0000FF", "#00FFFFFF", "#0000FFFF", "#0000A0FF", "#ADD8E6FF", "#800080FF", "#FFFF00FF", "#00FF00FF", "#FF00FFFF", "#FFFFFFFF", "#C0C0C0FF", "#808080FF", "#000000FF", "#FFA500FF", "#A52A2AFF", "#800000FF", "#008000FF", "#808000FF", "#000080FF", "#008080FF", "#00FFFFFF", "#FF00FFFF" }; internal static int Resolve(string input) { string name = (input ?? "").Trim().Replace(" ", "").Replace("-", "") .ToLowerInvariant(); if (name.Length == 0) { return 9; } int num = Array.FindIndex(Names, (string n) => n.Equals(name, StringComparison.OrdinalIgnoreCase)); if (num >= 0) { return num; } if (name == "gray") { return 11; } string text = name switch { "pink" => "FFC0CB", "hotpink" => "FF69B4", "gold" => "FFD700", "beige" => "F5F5DC", "ivory" => "FFFFF0", "violet" => "EE82EE", "indigo" => "4B0082", "turquoise" => "40E0D0", "coral" => "FF7F50", "salmon" => "FA8072", "crimson" => "DC143C", "lavender" => "E6E6FA", "tan" => "D2B48C", "chartreuse" => "7FFF00", _ => name.TrimStart('#'), }; if (text.Length == 3 || text.Length == 4) { text = string.Concat(from c in text.Take(3) select new string(c, 2)); } if ((text.Length == 6 || text.Length == 8) && text.All(Uri.IsHexDigit)) { int r = Convert.ToInt32(text.Substring(0, 2), 16); int g = Convert.ToInt32(text.Substring(2, 2), 16); int b = Convert.ToInt32(text.Substring(4, 2), 16); return (from i in Enumerable.Range(0, Names.Length) orderby Square(r - Convert.ToInt32(Hex[i].Substring(1, 2), 16)) + Square(g - Convert.ToInt32(Hex[i].Substring(3, 2), 16)) + Square(b - Convert.ToInt32(Hex[i].Substring(5, 2), 16)) select i).First(); } return (from i in Enumerable.Range(0, Names.Length) orderby Distance(name, Names[i].ToLowerInvariant()) select i).First(); } private static int Square(int x) { return x * x; } private static int Distance(string a, string b) { int[] array = Enumerable.Range(0, b.Length + 1).ToArray(); for (int i = 1; i <= a.Length; i++) { int[] array2 = new int[b.Length + 1]; array2[0] = i; for (int j = 1; j <= b.Length; j++) { array2[j] = Math.Min(Math.Min(array2[j - 1] + 1, array[j] + 1), array[j - 1] + ((a[i - 1] != b[j - 1]) ? 1 : 0)); } array = array2; } return array[b.Length]; } internal static string Markup(string caption, string hex) { return "<color=" + ((hex != null && hex.Length == 9 && hex[0] == '#' && hex.Skip(1).All(Uri.IsHexDigit)) ? hex.ToUpperInvariant() : Hex[Resolve(hex)]) + ">" + (caption ?? "").Replace("<", "‹").Replace(">", "›") + "</color>"; } } internal sealed class SignSettings { internal const int TextLimit = 256; internal const int RecordLimit = 160; internal float Scale = 1f; internal float TextSize = 1f; internal float Horizontal; internal float Vertical; internal int Color = 9; internal int Background; internal int Alignment = 1; internal bool Bold; internal bool Italic; internal bool Valid { get { if (InRange(Scale, 0.25f, 4f) && InRange(TextSize, 0.3f, 3f) && InRange(Horizontal, -0.4f, 0.4f) && InRange(Vertical, -0.4f, 0.4f) && Color >= 0 && Color < LabelColors.Names.Length && Background >= 0 && Background <= 2 && Alignment >= 0) { return Alignment <= 2; } return false; } } internal static bool InRange(float value, float min, float max) { if (!float.IsNaN(value) && !float.IsInfinity(value) && value >= min) { return value <= max; } return false; } internal string Encode() { if (!Valid) { throw new ArgumentException("Invalid sign settings."); } return string.Join("|", "1", F(Scale), F(TextSize), F(Horizontal), F(Vertical), Color, Background, Alignment, Bold ? 1 : 0, Italic ? 1 : 0); } private static string F(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } internal static bool TryDecode(string raw, out SignSettings settings) { settings = new SignSettings(); if (string.IsNullOrEmpty(raw)) { return true; } if (raw.Length > 160) { return false; } string[] array = raw.Split('|'); if (array.Length != 10 || array[0] != "1") { return false; } if (!Float(array[1], out settings.Scale) || !Float(array[2], out settings.TextSize) || !Float(array[3], out settings.Horizontal) || !Float(array[4], out settings.Vertical) || !int.TryParse(array[5], out settings.Color) || !int.TryParse(array[6], out settings.Background) || !int.TryParse(array[7], out settings.Alignment) || (array[8] != "0" && array[8] != "1") || (array[9] != "0" && array[9] != "1")) { return false; } settings.Bold = array[8] == "1"; settings.Italic = array[9] == "1"; return settings.Valid; } private static bool Float(string s, out float f) { return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out f); } internal static bool ValidText(string text) { if (text != null && text.Length <= 256 && !text.Any((char c) => char.IsControl(c) && c != '\n')) { return ValidUnicode(text); } return false; } private static bool ValidUnicode(string text) { for (int i = 0; i < text.Length; i++) { if (char.IsSurrogate(text[i]) && (!char.IsHighSurrogate(text[i]) || ++i >= text.Length || !char.IsLowSurrogate(text[i]))) { return false; } } return true; } } }