Decompiled source of DarkVision v1.0.1

DarkVision.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using REPOLib.Modules;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DarkVision")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Dark Vision Upgrade Mod for R.E.P.O.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DarkVision")]
[assembly: AssemblyTitle("DarkVision")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 REPODarkVision
{
	[BepInPlugin("com.hotlatte.repo.darkvision", "Dark Vision", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class DarkVisionPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.hotlatte.repo.darkvision";

		public const string PluginName = "Dark Vision";

		public const string PluginVersion = "1.0.0";

		internal ConfigEntry<KeyboardShortcut> ToggleKey;

		internal ConfigEntry<float> AmbientBoostLevel;

		internal ConfigEntry<bool> ShowHudText;

		internal static bool IsDarkVisionActive;

		internal static bool IsUnlocked;

		internal static DarkVisionPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static Harmony HarmonyPatch { get; private set; }

		internal static DarkVisionShopUpgrade ShopUpgrade { get; private set; }

		private void Awake()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)120, Array.Empty<KeyCode>()), "Hotkey to toggle Dark Vision.");
			AmbientBoostLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "Brightness", 0.8f, new ConfigDescription("How bright the dark vision is.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3.5f), Array.Empty<object>()));
			ShowHudText = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "Show HUD Text", true, "Show the 'DARK VISION: ACTIVE' text on screen.");
			HarmonyPatch = new Harmony("com.hotlatte.repo.darkvision");
			HarmonyPatch.PatchAll();
			AssetBundle bundle = LoadAssetBundle("DarkVision.Assets.darkvision_assets");
			ShopUpgrade = new DarkVisionShopUpgrade(((BaseUnityPlugin)this).Config, bundle);
			ShopUpgrade.Register();
			Log.LogInfo((object)"Dark Vision v1.0.0 loaded successfully.");
		}

		private void OnGUI()
		{
			//IL_002c: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_005d: 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)
			if (IsUnlocked && IsDarkVisionActive && ShowHudText.Value)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 24,
					fontStyle = (FontStyle)1
				};
				val.normal.textColor = new Color(0.9f, 0.9f, 0.9f, 1f);
				GUI.Label(new Rect(30f, (float)(Screen.height - 60), 300f, 40f), "DARK VISION : ACTIVE", val);
			}
		}

		private AssetBundle LoadAssetBundle(string expectedName)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(expectedName);
			if (stream == null)
			{
				Log.LogError((object)("Failed to find embedded resource: " + expectedName));
				return null;
			}
			return AssetBundle.LoadFromStream(stream);
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "Update")]
	internal static class PlayerInputPatch
	{
		private static float _nextToggleTime;

		private static Light _dvLight;

		private static void Postfix(PlayerAvatar __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)SemiFunc.PlayerAvatarLocal())
			{
				return;
			}
			if (!DarkVisionPlugin.IsUnlocked)
			{
				if ((Object)(object)_dvLight != (Object)null)
				{
					((Behaviour)_dvLight).enabled = false;
				}
				return;
			}
			KeyboardShortcut value = DarkVisionPlugin.Instance.ToggleKey.Value;
			if ((((KeyboardShortcut)(ref value)).IsDown() || Input.GetKeyDown((KeyCode)120)) && Time.unscaledTime >= _nextToggleTime)
			{
				_nextToggleTime = Time.unscaledTime + 0.3f;
				DarkVisionPlugin.IsDarkVisionActive = !DarkVisionPlugin.IsDarkVisionActive;
				DarkVisionPlugin.Log.LogInfo((object)("[DarkVision] Status: " + (DarkVisionPlugin.IsDarkVisionActive ? "ON" : "OFF")));
			}
			if ((Object)(object)_dvLight == (Object)null && (Object)(object)PlayerController.instance != (Object)null && (Object)(object)PlayerController.instance.cameraAim != (Object)null)
			{
				_dvLight = ((Component)PlayerController.instance.cameraAim).gameObject.AddComponent<Light>();
				_dvLight.type = (LightType)0;
				_dvLight.spotAngle = 179f;
				_dvLight.innerSpotAngle = 179f;
				_dvLight.range = 150f;
				_dvLight.color = Color.white;
				_dvLight.shadows = (LightShadows)0;
				_dvLight.renderMode = (LightRenderMode)1;
			}
			if ((Object)(object)_dvLight != (Object)null)
			{
				((Behaviour)_dvLight).enabled = DarkVisionPlugin.IsDarkVisionActive;
				_dvLight.intensity = DarkVisionPlugin.Instance.AmbientBoostLevel.Value;
			}
		}
	}
	[HarmonyPatch(typeof(FlashlightController), "Update")]
	internal static class FlashlightOverridePatch
	{
		private static float _cachedIntensity = -1f;

		private static bool _wasDarkVisionActive = false;

		private static void Postfix(FlashlightController __instance)
		{
			if (!((Object)(object)__instance.PlayerAvatar != (Object)null) || !((Object)(object)__instance.PlayerAvatar == (Object)(object)SemiFunc.PlayerAvatarLocal()))
			{
				return;
			}
			if (DarkVisionPlugin.IsDarkVisionActive && !_wasDarkVisionActive)
			{
				if ((Object)(object)__instance.spotlight != (Object)null)
				{
					_cachedIntensity = __instance.spotlight.intensity;
					__instance.spotlight.intensity = 0f;
					((Behaviour)__instance.spotlight).enabled = false;
				}
				if ((Object)(object)__instance.halo != (Object)null)
				{
					__instance.halo.enabled = false;
				}
				_wasDarkVisionActive = true;
			}
			else if (!DarkVisionPlugin.IsDarkVisionActive && _wasDarkVisionActive)
			{
				if ((Object)(object)__instance.spotlight != (Object)null && __instance.LightActive)
				{
					__instance.spotlight.intensity = ((_cachedIntensity > 0f) ? _cachedIntensity : 0.7f);
					((Behaviour)__instance.spotlight).enabled = true;
				}
				if ((Object)(object)__instance.halo != (Object)null)
				{
					__instance.halo.enabled = __instance.LightActive;
				}
				_wasDarkVisionActive = false;
			}
			else if (DarkVisionPlugin.IsDarkVisionActive)
			{
				if ((Object)(object)__instance.spotlight != (Object)null)
				{
					__instance.spotlight.intensity = 0f;
					((Behaviour)__instance.spotlight).enabled = false;
				}
				if ((Object)(object)__instance.halo != (Object)null)
				{
					__instance.halo.enabled = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ChatManager), "MessageSend")]
	internal static class ChatManagerPatch
	{
		private static void Postfix()
		{
			List<string> value = Traverse.Create((object)ChatManager.instance).Field("chatHistory").GetValue<List<string>>();
			if (value != null && value.Count != 0)
			{
				string text = value[value.Count - 1].ToLower().Trim();
				if (text == "/dv unlock")
				{
					DarkVisionPlugin.IsUnlocked = true;
					DarkVisionPlugin.Log.LogInfo((object)"Dark Vision activated via chat command");
				}
			}
		}
	}
	internal class DarkVisionShopUpgrade
	{
		public const string UpgradeId = "DarkVision";

		private readonly AssetBundle _bundle;

		internal ConfigEntry<bool> Enabled { get; private set; }

		internal ConfigEntry<float> BasePriceMultiplier { get; private set; }

		internal PlayerUpgrade RegisteredUpgrade { get; private set; }

		public DarkVisionShopUpgrade(ConfigFile config, AssetBundle bundle)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			_bundle = bundle;
			Enabled = config.Bind<bool>("Shop", "Enable Dark Vision", true, "Enable the Dark Vision upgrade in the shop.");
			BasePriceMultiplier = config.Bind<float>("Shop", "Price Multiplier", 1f, new ConfigDescription("Multiplier applied to the base shop price.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
		}

		public void Register()
		{
			if (!Enabled.Value || (Object)(object)_bundle == (Object)null)
			{
				return;
			}
			string text = "assets/darkvision/item upgrade player dark vision.prefab";
			GameObject val = _bundle.LoadAsset<GameObject>(text);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ItemAttributes component = val.GetComponent<ItemAttributes>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.item == (Object)null)
			{
				return;
			}
			Item val2 = (component.item = CreateRuntimeItem(component.item));
			((Object)val).name = ((Object)val2).name;
			REPOLibItemUpgrade component2 = val.GetComponent<REPOLibItemUpgrade>();
			if ((Object)(object)component2 != (Object)null)
			{
				FieldInfo field = typeof(REPOLibItemUpgrade).GetField("_upgradeId", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(component2, "DarkVision");
				}
			}
			Items.RegisterItem(component);
			RegisteredUpgrade = Upgrades.RegisterUpgrade("DarkVision", val2, (Action<PlayerAvatar, int>)OnRunStart, (Action<PlayerAvatar, int>)OnUpgradeBought);
		}

		public bool IsUnlocked(PlayerAvatar player)
		{
			if (RegisteredUpgrade == null || !Enabled.Value || (Object)(object)player == (Object)null)
			{
				return false;
			}
			return RegisteredUpgrade.GetLevel(player) > 0;
		}

		private void OnRunStart(PlayerAvatar player, int level)
		{
			UpdateLocalState(player, level);
		}

		private void OnUpgradeBought(PlayerAvatar player, int level)
		{
			DarkVisionPlugin.Log.LogInfo((object)$"{((Object)player).name} purchased Dark Vision! Level is now {level}.");
			UpdateLocalState(player, level);
		}

		private void UpdateLocalState(PlayerAvatar player, int level)
		{
			if ((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)SemiFunc.PlayerAvatarLocal())
			{
				DarkVisionPlugin.IsUnlocked = level > 0;
				if (!DarkVisionPlugin.IsUnlocked && DarkVisionPlugin.IsDarkVisionActive)
				{
					DarkVisionPlugin.IsDarkVisionActive = false;
				}
			}
		}

		private Item CreateRuntimeItem(Item source)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Item val = ScriptableObject.CreateInstance<Item>();
			((Object)val).name = "Item Upgrade Player Dark Vision";
			val.disabled = false;
			val.itemName = "Dark Vision";
			val.itemNameLocalized = null;
			val.description = source.description;
			val.itemType = (itemType)3;
			val.physicalItem = source.physicalItem;
			val.spawnRotationOffset = source.spawnRotationOffset;
			val.emojiIcon = source.emojiIcon;
			val.itemVolume = source.itemVolume;
			val.itemSecretShopType = source.itemSecretShopType;
			val.colorPreset = source.colorPreset;
			Value val2 = ScriptableObject.CreateInstance<Value>();
			if ((Object)(object)source.value != (Object)null)
			{
				val2.valueMin = source.value.valueMin * BasePriceMultiplier.Value;
				val2.valueMax = source.value.valueMax * BasePriceMultiplier.Value;
			}
			val.value = val2;
			val.maxAmount = ((source.maxAmount > 0) ? source.maxAmount : 10);
			val.maxAmountInShop = ((source.maxAmountInShop > 0) ? source.maxAmountInShop : 2);
			val.minPlayerCount = ((source.minPlayerCount <= 0) ? 1 : source.minPlayerCount);
			val.maxPurchase = source.maxPurchase;
			val.maxPurchaseAmount = source.maxPurchaseAmount;
			return val;
		}
	}
}