Decompiled source of CWMissing v2.0.8

off_grid.MissingItems.dll

Decompiled 6 months ago
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;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DefaultNamespace;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using ShopTweaks;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("off_grid.MissingItems")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.8.0")]
[assembly: AssemblyInformationalVersion("2.0.8")]
[assembly: AssemblyProduct("MissingItems")]
[assembly: AssemblyTitle("off_grid.MissingItems")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.8.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 MissingItems
{
	[BepInPlugin("off_grid.MissingItems", "MissingItems", "2.0.8")]
	public class MissingItems : BaseUnityPlugin, IOnEventCallback, IInRoomCallbacks
	{
		[HarmonyPatch(typeof(RoundSpawner), "Start")]
		public class RoundSpawnerPatch
		{
			private static void Postfix(RoundSpawner __instance)
			{
				Instance.AddMonstersToRoundSpawner(__instance);
			}
		}

		[HarmonyPatch(typeof(ShopHandler))]
		[HarmonyPatch("InitShop")]
		public static class ShopHandler_InitShop_Patch
		{
			private static void Postfix()
			{
				Instance.shopInitialized = true;
			}
		}

		private ShopItemCategory Nil1;

		private bool configSynced;

		private bool shopInitialized;

		private bool LobbyStatus;

		private bool UseCustomTabs;

		private string? ConfigVersion;

		public ConfigFile config;

		private readonly List<string> NameList = new List<string>
		{
			"Radio", "PersistantRadio", "WalkieTalkie", "Wide Flashlight 2", "Wide Flashlight 3", "GrabberArm", "Emote_Choked", "Emote_Choke", "Emote_Dance4TokTok", "Bomb",
			"FakeOldFlashlight", "NorfGun"
		};

		private readonly List<string> MonsterNameList = new List<string> { "Angler", "Wallo", "MimicMan", "Ghost" };

		public static MissingItems Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		public static List<Item> AllItems => ((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects.ToList();

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			InitializeConfig();
			Patch();
			Update();
			PhotonNetwork.AddCallbackTarget((object)this);
			Logger.LogInfo((object)"off_grid.MissingItems v2.0.8 has fully loaded!");
		}

		private void InitializeConfig()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Paths.ConfigPath, "CWMissing");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string text2 = Path.Combine(text, "config.cfg");
			config = new ConfigFile(text2, true);
			ConfigVersion = config.Bind<string>("Version", "Current Version", "", (ConfigDescription)null).Value;
			if (ConfigVersion != "2.0.8")
			{
				config.Clear();
				DefineConfig();
			}
			UseCustomTabs = config.Bind<bool>("Custom Tabs", "Use Custom Tabs", false, (ConfigDescription)null).Value;
			if (UseCustomTabs)
			{
				Nil1 = ShopCategories.RegisterCategory("CWMissing");
			}
		}

		private void OnDestroy()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		private void OnEnable()
		{
			PhotonNetwork.AddCallbackTarget((object)this);
		}

		private void OnDisable()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		private 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("off_grid.MissingItems");
			}
			Harmony.PatchAll();
		}

		private void AddMonstersToRoundSpawner(RoundSpawner spawner)
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			List<IBudgetCost> list = new List<IBudgetCost>();
			int num = 0;
			foreach (string monsterName in MonsterNameList)
			{
				float value = config.Bind<float>(monsterName, "SpawnWeight", 0.5f, (ConfigDescription)null).Value;
				int value2 = config.Bind<int>(monsterName, "Slots", 10, (ConfigDescription)null).Value;
				if (Random.value <= value && config.Bind<bool>(monsterName, "Enabled", false, (ConfigDescription)null).Value)
				{
					IBudgetCost val = LoadMonster(monsterName);
					if (val != null)
					{
						list.Add(val);
						num += val.Cost;
					}
				}
			}
			spawner.testBudget += num;
			spawner.possibleSpawns = spawner.possibleSpawns.Concat(list.Select((IBudgetCost m) => m.gameObject)).ToArray();
		}

		private IBudgetCost LoadMonster(string monsterName)
		{
			GameObject val = Resources.Load<GameObject>(monsterName ?? "");
			if ((Object)(object)val != (Object)null)
			{
				return val.GetComponent<IBudgetCost>();
			}
			return null;
		}

		private void DefineConfig()
		{
			config.Bind<string>("Version", "Current Version", "2.0.8", "Autoupdates the config / lets the mod know what version of config it is.");
			config.Bind<bool>("Custom Tabs", "Use Custom Tabs", false, "Use Custom Tabs?");
			DefineItemConfig("Radio", 100, purchasable: true, spawnable: true, "epic", "Phonk Radio", "Misc");
			DefineItemConfig("PersistantRadio", 100, purchasable: true, spawnable: true, "epic", "Money Radio", "Misc");
			DefineItemConfig("WalkieTalkie", 25, purchasable: true, spawnable: true, "epic", "Walkie Talkie", "Gadgets");
			DefineItemConfig("Wide Flashlight 2", 600, purchasable: true, spawnable: true, "epic", "Wide Flashlight", "Lights");
			DefineItemConfig("Wide Flashlight 3", 800, purchasable: true, spawnable: true, "legendary", "Wide Flashlight Pro", "Lights");
			DefineItemConfig("GrabberArm", 150, purchasable: true, spawnable: true, "epic", "Grabber", "Gadgets");
			DefineItemConfig("Emote_Choked", 200, purchasable: true, spawnable: false, "epic", "Choked", "Emotes");
			DefineItemConfig("Emote_Choke", 200, purchasable: true, spawnable: false, "epic", "Choke", "Emotes");
			DefineItemConfig("Emote_Dance4TokTok", 200, purchasable: true, spawnable: false, "epic", "Dance 104", "Emotes");
			DefineItemConfig("Bomb", 5, purchasable: true, spawnable: false, "epic", "Firework", "Misc");
			DefineItemConfig("FakeOldFlashlight", 20, purchasable: true, spawnable: false, "epic", "RealOldFlashlight", "Lights");
			DefineItemConfig("NorfGun", 60, purchasable: true, spawnable: true, "legendary", "Nerf Blaster 3000", "Gadgets");
			DefineMonsterConfig("MimicMan", 0.1f, 4, 300, 1, 0, UseSlots: false, isEnabled: true);
			DefineMonsterConfig("Angler", 0.1f, 4, 300, 1, 0, UseSlots: false, isEnabled: true);
			DefineMonsterConfig("Wallo", 0.1f, 4, 300, 1, 0, UseSlots: false, isEnabled: true);
			DefineMonsterConfig("Toolkit_Fan", 0.1f, 4, 300, 1, 0, UseSlots: false, isEnabled: false);
			DefineMonsterConfig("Toolkit_Hammer", 0.1f, 4, 300, 1, 0, UseSlots: false, isEnabled: false);
			DefineMonsterConfig("Toolkit_Iron", 0.1f, 4, 300, 1, 0, UseSlots: false, isEnabled: false);
			DefineMonsterConfig("Toolkit_Vaccuum", 0.1f, 4, 300, 1, 0, UseSlots: false, isEnabled: false);
			DefineMonsterConfig("Ghost", 0.1f, 0, 300, 1, 0, UseSlots: false, isEnabled: true);
		}

		private void DefineItemConfig(string itemName, int price, bool purchasable, bool spawnable, string rarity, string DisplayName, string Category)
		{
			config.Bind<int>(itemName, "Price", price, "Price of the " + itemName + ".");
			config.Bind<bool>(itemName, "Purchasable", purchasable, "Is " + itemName + " purchasable?");
			config.Bind<bool>(itemName, "Spawnable", spawnable, "Is " + itemName + " spawnable?");
			config.Bind<string>(itemName, "Rarity", rarity, "Spawn rarity of the " + itemName + ". Options: always, superCommon, moreCommon, common, lessCommon, uncommon, rare, epic, legendary, mythic");
			config.Bind<string>(itemName, "DisplayName", DisplayName, "Display name for " + itemName + ".");
			config.Bind<string>(itemName, "Category", Category, "Category " + itemName + " will be listed under. Options: Lights, Medical, Gadgets, Emotes, Misc, CWMissing");
		}

		private void DefineMonsterConfig(string monsterName, float spawnWeight, int minDays, int minTime, int maxMonsters, int nsSlots, bool UseSlots, bool isEnabled)
		{
			config.Bind<float>(monsterName, "SpawnWeight", spawnWeight, "Spawn weight for the " + monsterName + ". (0.1 = 10%, 1 = 100%, Will not be accurate if it is in current round*)");
			config.Bind<int>(monsterName, "MinimumDays", minDays, "Minimum days before " + monsterName + " is allowed to spawn.");
			config.Bind<int>(monsterName, "MinimumTime", minTime, "Minimum time before " + monsterName + " is allowed to spawn.");
			config.Bind<int>(monsterName, "MaximumOfEntity", maxMonsters, "Maximum amount of " + monsterName + " that can spawn.");
			config.Bind<int>(monsterName, "Slots", nsSlots, "Amount of slots " + monsterName + " will take up.");
			config.Bind<bool>(monsterName, "UseSlots", UseSlots, "Should slots be used instead of actual monster cost?");
			config.Bind<bool>(monsterName, "Enabled", isEnabled, "Is spawning for " + monsterName + " allowed.");
		}

		private void AddShopItems()
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			foreach (Item allItem in AllItems)
			{
				if (NameList.Contains(((Object)allItem).name))
				{
					int value = config.Bind<int>(((Object)allItem).name, "Price", 100, (ConfigDescription)null).Value;
					bool value2 = config.Bind<bool>(((Object)allItem).name, "Purchasable", false, (ConfigDescription)null).Value;
					bool value3 = config.Bind<bool>(((Object)allItem).name, "Spawnable", false, (ConfigDescription)null).Value;
					string value4 = config.Bind<string>(((Object)allItem).name, "Rarity", "epic", (ConfigDescription)null).Value;
					string value5 = config.Bind<string>(((Object)allItem).name, "Category", "Misc", (ConfigDescription)null).Value;
					string value6 = config.Bind<string>(((Object)allItem).name, "DisplayName", "Null", (ConfigDescription)null).Value;
					allItem.price = value;
					allItem.purchasable = value2;
					allItem.spawnable = value3;
					allItem.toolSpawnRarity = ParseRarity(value4);
					allItem.Category = (UseCustomTabs ? Nil1 : ParseCategory(value5));
					allItem.displayName = value6;
				}
			}
			ShopHandler.Instance.InitShopHandler();
		}

		private void Update()
		{
			if (PhotonNetwork.InRoom && !LobbyStatus)
			{
				LobbyStatus = true;
				if (PhotonNetwork.IsMasterClient)
				{
					AddShopItems();
				}
				else
				{
					((MonoBehaviour)this).StartCoroutine(WaitForConfigSync());
				}
			}
			if (!PhotonNetwork.InRoom && LobbyStatus)
			{
				LobbyStatus = false;
			}
		}

		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code == 1 && photonEvent.CustomData is object[] array && array.Length != 0 && array[0] is string configData)
			{
				ApplyHostConfig(configData);
			}
		}

		private void ApplyHostConfig(string configData)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "CWMissing");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string text2 = Path.Combine(text, "HostConfig.cfg");
			File.WriteAllText(text2, FormatConfig(configData));
			config = new ConfigFile(text2, true);
			configSynced = true;
		}

		private string FormatConfig(string brokenConfig)
		{
			string[] array = brokenConfig.Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
			StringBuilder stringBuilder = new StringBuilder();
			string text = "";
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string[] array3 = text2.Split(':');
				if (array3.Length > 1)
				{
					if (text != array3[0])
					{
						text = array3[0];
						stringBuilder.AppendLine("[" + text + "]");
					}
					string[] array4 = array3[1].Split('=');
					stringBuilder.AppendLine(array4[0].Trim() + " = " + array4[1].Trim());
				}
				else
				{
					stringBuilder.AppendLine(text2);
				}
			}
			return stringBuilder.ToString();
		}

		private void SendConfigToPlayer(Player player)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			string text = SerializeConfig(config);
			object[] array = new object[1] { text };
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)0
			};
			PhotonNetwork.RaiseEvent((byte)1, (object)array, val, SendOptions.SendReliable);
		}

		private string SerializeConfig(ConfigFile config)
		{
			using StringWriter stringWriter = new StringWriter();
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config)
			{
				stringWriter.WriteLine($"{item.Key.Section}:{item.Key.Key}={item.Value.BoxedValue}");
			}
			return stringWriter.ToString();
		}

		private ShopItemCategory ParseCategory(string Category)
		{
			//IL_0044: 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_0048: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			return (ShopItemCategory)(Category switch
			{
				"Lights" => 1, 
				"Gadgets" => 3, 
				"Misc" => 7, 
				"Medical" => 2, 
				"Emotes" => 4, 
				_ => 0, 
			});
		}

		private RARITY ParseRarity(string rarity)
		{
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			return (RARITY)(rarity switch
			{
				"always" => 10, 
				"superCommon" => 50, 
				"moreCommon" => 75, 
				"common" => 100, 
				"lessCommon" => 150, 
				"uncommon" => 1000, 
				"rare" => 10000, 
				"epic" => 100000, 
				"legendary" => 1000000, 
				"mythic" => 10000000, 
				_ => 100000, 
			});
		}

		private IEnumerator WaitForConfigSync()
		{
			while (!configSynced && !shopInitialized)
			{
				yield return null;
			}
			AddShopItems();
		}

		public void OnPlayerEnteredRoom(Player newPlayer)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				SendConfigToPlayer(newPlayer);
			}
		}

		public void OnPlayerLeftRoom(Player otherPlayer)
		{
		}

		public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
		}

		public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
		}

		public void OnMasterClientSwitched(Player newMasterClient)
		{
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "off_grid.MissingItems";

		public const string PLUGIN_NAME = "MissingItems";

		public const string PLUGIN_VERSION = "2.0.8";
	}
}
namespace MissingItems.Patches
{
	internal class NetworkHandler
	{
	}
	internal class RoundSpawner
	{
	}
	internal class ShopHandler
	{
	}
}