Decompiled source of LoadingTips v1.1.2

Enova.LoadingTips.dll

Decompiled 3 days ago
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.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Enova.LoadingTips")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+daf962f31d73b9a1eb34b1614f4b589b156d34e1")]
[assembly: AssemblyProduct("LoadingTips")]
[assembly: AssemblyTitle("Enova.LoadingTips")]
[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 LoadingTips
{
	[BepInPlugin("Enova.LoadingTips", "LoadingTips", "1.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class LoadingTips : BaseUnityPlugin
	{
		public static LoadingTips Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		internal static LoadingTipsConfig Config { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Config = new LoadingTipsConfig(((BaseUnityPlugin)this).Config);
			if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"))
			{
				Config.InitializeLethalConfig();
			}
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				InitializeLobbyCompatibility();
			}
			Patch();
			Logger.LogInfo((object)"Enova.LoadingTips v1.1.2 has loaded!");
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void InitializeLobbyCompatibility()
		{
			PluginHelper.RegisterPlugin("Enova.LoadingTips", new Version("1.1.2"), (CompatibilityLevel)0, (VersionStrictness)1);
		}

		internal static void Patch()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("Enova.LoadingTips");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	internal class LoadingTipsConfig
	{
		private readonly List<string> _tips = new List<string>();

		private readonly string _tipsPath = Path.Combine(Paths.ConfigPath, "LoadingTips.txt");

		private const string _defaultTip = "Create tips by editing the LoadingTips.txt file in your BepInEx config directory.";

		public ConfigEntry<string> TipPrefix { get; }

		public ConfigEntry<bool> RandomizeTip { get; }

		public IReadOnlyList<string> Tips => _tips.AsReadOnly();

		public LoadingTipsConfig(ConfigFile config)
		{
			TipPrefix = config.Bind<string>("General", "TipPrefix", string.Empty, "This text will precede all loading screen tips (e.g. TIP: My Tip Here)");
			RandomizeTip = config.Bind<bool>("General", "RandomizeTip", true, "Whether to show a random tip from the list every time it is shown or show them sequentially.");
			LoadTips();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal void InitializeLethalConfig()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			TextInputFieldConfigItem val = new TextInputFieldConfigItem(TipPrefix, false);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
			BoolCheckBoxConfigItem val2 = new BoolCheckBoxConfigItem(RandomizeTip, false);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val2);
			GenericButtonConfigItem val3 = new GenericButtonConfigItem("General", "Reload Tips", "Reloads the tips from the txt file in BepInEx/config/LoadingTips.txt", "Reload", new GenericButtonHandler(LoadTips));
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val3);
		}

		public void LoadTips()
		{
			_tips.Clear();
			try
			{
				if (!File.Exists(_tipsPath))
				{
					File.WriteAllText(_tipsPath, "Create tips by editing the LoadingTips.txt file in your BepInEx config directory.", Encoding.UTF8);
				}
			}
			catch (Exception arg)
			{
				LoadingTips.Logger.LogError((object)$"Failed to create tips file: {arg}");
				return;
			}
			try
			{
				string[] source = File.ReadAllLines(_tipsPath);
				_tips.AddRange(from l in source
					select l.UseAsSpan(0, 100).ToString().Trim()
						.Split("##")
						.First()
						.Replace("\\n", Environment.NewLine) into l
					where !string.IsNullOrWhiteSpace(l)
					select l);
			}
			catch (Exception arg2)
			{
				LoadingTips.Logger.LogError((object)$"Failed to read tips file: {arg2}");
			}
		}
	}
	internal class LoadingTipScript : MonoBehaviour
	{
		private TextMeshProUGUI _text;

		private static int _tipIndex = -1;

		private void Awake()
		{
			_text = ((Component)this).GetComponent<TextMeshProUGUI>();
		}

		private void OnEnable()
		{
			if (LoadingTips.Config.RandomizeTip.Value)
			{
				SetRandomTip();
			}
			else
			{
				SetTip(_tipIndex++);
			}
		}

		public void SetRandomTip()
		{
			if (LoadingTips.Config.Tips.Count <= 0)
			{
				LoadingTips.Logger.LogError((object)"Tips are empty, can't set tip");
				return;
			}
			int num = Random.Range(0, LoadingTips.Config.Tips.Count);
			while (LoadingTips.Config.Tips.Count > 1 && num == _tipIndex)
			{
				num = Random.Range(0, LoadingTips.Config.Tips.Count);
			}
			SetTip(num);
			_tipIndex = num;
		}

		public void SetTip(int tipIndex)
		{
			if (LoadingTips.Config.Tips.Count <= 0)
			{
				LoadingTips.Logger.LogError((object)"Tips are empty, can't set tip");
				return;
			}
			tipIndex = Math.Clamp(tipIndex, 0, LoadingTips.Config.Tips.Count - 1);
			SetTip(LoadingTips.Config.Tips[tipIndex]);
		}

		public void SetTip(string tip)
		{
			((TMP_Text)_text).text = LoadingTips.Config.TipPrefix.Value + tip;
		}
	}
	internal static class StringExtensions
	{
		private static bool IsInputStringShorter(string str, int length)
		{
			return str.Length < length;
		}

		public static ReadOnlySpan<char> UseAsSpan(this string str, int start, int length)
		{
			if (IsInputStringShorter(str, length - start))
			{
				return str;
			}
			return str.AsSpan(start, length);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Enova.LoadingTips";

		public const string PLUGIN_NAME = "LoadingTips";

		public const string PLUGIN_VERSION = "1.1.2";
	}
}
namespace LoadingTips.Patches
{
	[HarmonyPatch(typeof(HUDManager))]
	[HarmonyWrapSafe]
	internal class LoadingTipsPatches
	{
		private static GameObject? _tipsObject;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void HudStart(HUDManager __instance)
		{
			InitializeText(((TMP_Text)__instance.loadingText).transform.parent);
		}

		[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
		[HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")]
		[HarmonyPatch(typeof(StartOfRound), "SceneManager_OnLoadComplete1")]
		[HarmonyPatch(typeof(StartOfRound), "SceneManager_OnLoad")]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		public static void DarkenHudChanged()
		{
			GameObject? tipsObject = _tipsObject;
			if (tipsObject != null)
			{
				tipsObject.SetActive(((Behaviour)HUDManager.Instance.loadingText).enabled);
			}
			((Behaviour)HUDManager.Instance.loadingDarkenScreen).enabled = ((Behaviour)HUDManager.Instance.loadingText).enabled;
		}

		private static void InitializeText(Transform parent)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			_tipsObject = new GameObject("LoadingTips", new Type[2]
			{
				typeof(TextMeshProUGUI),
				typeof(LoadingTipScript)
			});
			_tipsObject.SetActive(false);
			_tipsObject.layer = LayerMask.NameToLayer("UI");
			RectTransform component = _tipsObject.GetComponent<RectTransform>();
			((Transform)component).SetParent(parent);
			((Transform)component).SetAsLastSibling();
			((Transform)component).localScale = new Vector3(1f, 1f, 1f);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(500f, 100f);
			component.anchoredPosition3D = new Vector3(0f, -200f, 0f);
			TextMeshProUGUI component2 = _tipsObject.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component2).font = ((TMP_Text)HUDManager.Instance.loadingText).font;
			((TMP_Text)component2).font.fallbackFontAssetTable.Add(((TMP_Text)HUDManager.Instance.controlTipLines[0]).font);
			((TMP_Text)component2).fontSize = 18f;
			((TMP_Text)component2).horizontalAlignment = (HorizontalAlignmentOptions)2;
			((TMP_Text)component2).enableWordWrapping = true;
			((TMP_Text)component2).overflowMode = (TextOverflowModes)2;
			((Graphic)component2).color = ((Graphic)HUDManager.Instance.loadingText).color;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}