Decompiled source of ChunkysFriendTweaks v1.0.0

ChunkysFriendTweaks.dll

Decompiled 11 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ChunkysFriendTweaks.patch;
using HarmonyLib;
using LethalLevelLoader;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[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("qwcan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0112b5cf92437133d49350afbbbf8d3a39178158")]
[assembly: AssemblyProduct("FriendTweaks")]
[assembly: AssemblyTitle("ChunkysFriendTweaks")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 ChunkysFriendTweaks
{
	[BepInPlugin("111.ChunkysFriendTweaks", "ChunkysFriendTweaks", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("ChunkysFriendTweaks");

		public static readonly HashSet<string> BlacklistedItems = new HashSet<string>();

		public static Plugin Instance { get; set; }

		public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		public Plugin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Instance = this;
			ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Blacklisted Item Names", "", "Comma separated list of names of items to add to the blacklist. Blacklisted items will be skipped when being registered with LethalLib or LethalLevelLoader. The item names must match exactly. Use with caution, as a mod trying to directly spawn a blacklisted item may cause problems. If you don't want an item to spawn naturally, just set the spawn weights to zero instead.");
			string[] array = val.Value.Split(',');
			foreach (string text in array)
			{
				BlacklistedItems.Add(text.Trim());
			}
		}

		private void Awake()
		{
			Log.LogInfo((object)"Applying patches...");
			ApplyPluginPatch();
			Log.LogInfo((object)"Patches applied");
		}

		private void ApplyPluginPatch()
		{
			_harmony.PatchAll(typeof(LLLPatch));
			_harmony.PatchAll(typeof(LethalLibPatch));
			_harmony.PatchAll(typeof(NetworkPrefab));
		}

		public static string SafeName(string name)
		{
			char[] array = new char[8] { '=', '\n', '\t', '\\', '"', '\'', '[', ']' };
			char[] array2 = array;
			foreach (char oldChar in array2)
			{
				name = name.Replace(oldChar, '_');
			}
			return name;
		}
	}
	public class PluginInfo
	{
		public const string GUID = "111.ChunkysFriendTweaks";
	}
}
namespace ChunkysFriendTweaks.patch
{
	[HarmonyPatch(typeof(Items))]
	public class LethalLibPatch
	{
		[HarmonyPatch(typeof(Items), "RegisterScrap", new Type[]
		{
			typeof(Item),
			typeof(int),
			typeof(LevelTypes)
		})]
		[HarmonyPrefix]
		public static bool PrefixRegisterScrap(ref Item spawnableItem, ref int rarity, ref LevelTypes levelFlags)
		{
			if (MatchesBlacklist(spawnableItem))
			{
				return false;
			}
			spawnableItem = UpdateItemValues(spawnableItem);
			Dictionary<LevelTypes, int> levelRarities = new Dictionary<LevelTypes, int> { { levelFlags, rarity } };
			levelRarities = UpdateLevelRarities(spawnableItem, levelRarities);
			Items.RegisterScrap(spawnableItem, levelRarities, (Dictionary<string, int>)null);
			return false;
		}

		[HarmonyPatch(typeof(Items), "RegisterScrap", new Type[]
		{
			typeof(Item),
			typeof(int),
			typeof(LevelTypes),
			typeof(string[])
		})]
		[HarmonyPrefix]
		public static bool PrefixRegisterScrap2(ref Item spawnableItem, ref int rarity, ref LevelTypes levelFlags, ref string[]? levelOverrides)
		{
			if (MatchesBlacklist(spawnableItem))
			{
				return false;
			}
			spawnableItem = UpdateItemValues(spawnableItem);
			Dictionary<LevelTypes, int> levelRarities = new Dictionary<LevelTypes, int> { { levelFlags, rarity } };
			levelRarities = UpdateLevelRarities(spawnableItem, levelRarities);
			int rarityConst = rarity;
			Dictionary<string, int> levelRarities2 = levelOverrides?.ToDictionary((string level) => level, (string _) => rarityConst);
			levelRarities2 = UpdateCustomLevelRarities(spawnableItem, levelRarities2);
			Items.RegisterScrap(spawnableItem, levelRarities, levelRarities2);
			return false;
		}

		[HarmonyPatch(typeof(Items), "RegisterScrap", new Type[]
		{
			typeof(Item),
			typeof(Dictionary<LevelTypes, int>),
			typeof(Dictionary<string, int>)
		})]
		[HarmonyPrefix]
		public static bool PrefixRegisterScrap3(ref Item spawnableItem, ref Dictionary<LevelTypes, int>? levelRarities, ref Dictionary<string, int>? customLevelRarities)
		{
			if (MatchesBlacklist(spawnableItem))
			{
				return false;
			}
			spawnableItem = UpdateItemValues(spawnableItem);
			levelRarities = UpdateLevelRarities(spawnableItem, levelRarities);
			customLevelRarities = UpdateCustomLevelRarities(spawnableItem, customLevelRarities);
			return true;
		}

		private static bool MatchesBlacklist(Item spawnableItem)
		{
			if (Plugin.BlacklistedItems.Contains(Plugin.SafeName(spawnableItem.itemName)))
			{
				Plugin.Log.LogInfo((object)("Item " + spawnableItem.itemName + " is blacklisted, not registering."));
				return true;
			}
			return false;
		}

		private static Dictionary<string, int>? UpdateCustomLevelRarities(Item item, Dictionary<string, int>? levelRarities)
		{
			string text = Plugin.SafeName(item.itemName);
			ConfigEntry<string> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("ScrapSpawnWeights", text + " Custom Level Weights", ((levelRarities == null) ? "" : string.Join(",", levelRarities.Select<KeyValuePair<string, int>, string>((KeyValuePair<string, int> pair) => "Key:" + pair.Value))) ?? "", "A comma-separated list of custom level names and scrap spawn weights for this item. For example, Experimentation:10,Vow:20 will make the item spawn twice as often on Experimentation as on Vow. A blank value will use the mod's default settings");
			if (levelRarities == null)
			{
				return levelRarities;
			}
			if (!string.IsNullOrEmpty(val.Value))
			{
				IEnumerable<string[]> enumerable = from pair in val.Value.Split(',')
					select pair.Split(':');
				try
				{
					foreach (string[] item2 in enumerable)
					{
						item2[0] = item2[0].Trim();
						item2[1] = item2[1].Trim();
						levelRarities[item2[0]] = int.Parse(item2[1]);
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Error parsing config for LethalLib item " + text + ": " + val.Value + " - " + ex.Message + "\n" + ex.StackTrace));
					return levelRarities;
				}
			}
			return levelRarities;
		}

		private static Dictionary<LevelTypes, int>? UpdateLevelRarities(Item item, Dictionary<LevelTypes, int>? levelRarities)
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			string text = Plugin.SafeName(item.itemName);
			ConfigEntry<string> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("ScrapSpawnWeights", text + " LevelType Weights", ((levelRarities == null) ? "" : string.Join(",", levelRarities.Select(delegate(KeyValuePair<LevelTypes, int> pair)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				LevelTypes key2 = pair.Key;
				return ((object)(LevelTypes)(ref key2)).ToString() + ":" + pair.Value;
			}))) ?? "", "A comma-separated list of level names and scrap spawn weights for this item. For example, AssuranceLevel:10,Modded:20 will make the item spawn twice as often on Assurance as on Modded levels. A blank value will use the mod's default settings");
			if (levelRarities == null)
			{
				return levelRarities;
			}
			if (!string.IsNullOrEmpty(val.Value))
			{
				IEnumerable<string[]> enumerable = from pair in val.Value.Split(',')
					select pair.Split(':');
				try
				{
					foreach (string[] item2 in enumerable)
					{
						item2[0] = item2[0].Trim();
						item2[1] = item2[1].Trim();
						LevelTypes key = Enum.Parse<LevelTypes>(item2[0]);
						levelRarities[key] = int.Parse(item2[1]);
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Error parsing config for LethalLib item " + text + ": " + val.Value + " - " + ex.Message + "\n" + ex.StackTrace));
					return levelRarities;
				}
			}
			return levelRarities;
		}

		private static Item UpdateItemValues(Item spawnableItem)
		{
			string text = Plugin.SafeName(spawnableItem.itemName);
			ConfigEntry<string> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("ScrapValues", text + " Scrap Values", $"{spawnableItem.minValue},{spawnableItem.maxValue}", "The minimum and maximum scrap values for this item, separated by a comma. Lethal Company multiplies all scrap values by 0.4, so a value of 50,100 would mean the item can be worth between 20 and 40. A blank value will use the mod's default settings");
			if (string.IsNullOrEmpty(val.Value))
			{
				return spawnableItem;
			}
			try
			{
				int[] array = val.Value.Split(',')?.Select(int.Parse).ToArray();
				if (array == null || array.Length < 2)
				{
					return spawnableItem;
				}
				spawnableItem.minValue = array[0];
				spawnableItem.maxValue = array[1];
				return spawnableItem;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error parsing config for LethalLib item " + text + ": " + val.Value + " - " + ex.Message + "\n" + ex.StackTrace));
				return spawnableItem;
			}
		}
	}
	public class LLLPatch
	{
		[HarmonyPatch(typeof(ExtendedMod), "RegisterExtendedContent", new Type[] { typeof(ExtendedItem) })]
		[HarmonyPrefix]
		public static bool RegisterExtendedContentPatch(ref ExtendedMod __instance, ref ExtendedItem extendedItem)
		{
			if (__instance.ModName == "LethalCompany" || __instance.AuthorName == "Zeekerss")
			{
				return true;
			}
			if (extendedItem.LevelMatchingProperties == null)
			{
				Plugin.Log.LogWarning((object)("Skipping " + ((Object)extendedItem).name + " (missing LevelMatchingProperties)."));
				return true;
			}
			if (MatchesBlacklist(extendedItem))
			{
				return false;
			}
			extendedItem = UpdateItem(extendedItem);
			return true;
		}

		private static bool MatchesBlacklist(ExtendedItem extendedItem)
		{
			string item = Plugin.SafeName(((Object)extendedItem).name);
			if (Plugin.BlacklistedItems.Contains(item))
			{
				Plugin.Log.LogInfo((object)("Item " + ((Object)extendedItem).name + " is blacklisted, not registering."));
				return true;
			}
			return false;
		}

		private static ExtendedItem UpdateItem(ExtendedItem extendedItem)
		{
			return UpdateItemValues(UpdateItemWeights(extendedItem));
		}

		private static ExtendedItem UpdateItemValues(ExtendedItem extendedItem)
		{
			string text = Plugin.SafeName(((Object)extendedItem).name);
			ConfigEntry<string> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("ScrapValues", text + " Scrap Values", $"{extendedItem.Item.minValue},{extendedItem.Item.maxValue}", "The minimum and maximum scrap values for this item, separated by a comma. Lethal Company multiplies all scrap values by 0.4, so a value of 50,100 would mean the item can be worth between 20 and 40.");
			if (string.IsNullOrEmpty(val.Value))
			{
				return extendedItem;
			}
			int[] array = val.Value.Split(',')?.Select(int.Parse).ToArray();
			if (array == null || array.Length < 2)
			{
				return extendedItem;
			}
			extendedItem.Item.minValue = array[0];
			extendedItem.Item.maxValue = array[1];
			return extendedItem;
		}

		private static ExtendedItem UpdateItemWeights(ExtendedItem extendedItem)
		{
			string itemName = Plugin.SafeName(((Object)extendedItem).name);
			LevelMatchingProperties levelMatchingProperties = extendedItem.LevelMatchingProperties;
			extendedItem.LevelMatchingProperties = LevelMatchingProperties.Create((ExtendedContent)(object)extendedItem);
			extendedItem.LevelMatchingProperties.ApplyValues(((MatchingProperties)levelMatchingProperties).modNames, ((MatchingProperties)levelMatchingProperties).authorNames, levelMatchingProperties.levelTags, levelMatchingProperties.currentRoutePrice, levelMatchingProperties.currentWeather, levelMatchingProperties.planetNames);
			extendedItem.LevelMatchingProperties.planetNames = UpdateList(itemName, extendedItem.LevelMatchingProperties.planetNames, "Planet Weights", "A comma-separated list of moon names and scrap spawn weights for this item. For example, Experimentation:10,Vow:20 will make the item spawn twice as often on Experimentation as on Vow. A blank value will use the mod's default settings");
			extendedItem.LevelMatchingProperties.levelTags = UpdateList(itemName, extendedItem.LevelMatchingProperties.levelTags, "Level Tag Weights", "A comma-separated list of level tags and scrap spawn weights for this item. For example, Vanilla:20 will make the item spawn with a weight of 20 on Vanilla levels. A blank value will use the mod's default settings");
			extendedItem.LevelMatchingProperties.currentWeather = UpdateList(itemName, extendedItem.LevelMatchingProperties.currentWeather, "Current Weather Weights", "A comma-separated list of current weather and scrap spawn weights for this item. For example, Rainy:100 will make the item spawn with a weight of 100 when the current weather is Rainy. A blank value will use the mod's default settings");
			return extendedItem;
		}

		private static List<StringWithRarity> UpdateList(string itemName, List<StringWithRarity> stringWithRarityList, string configName, string description)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			List<StringWithRarity> list = new List<StringWithRarity>();
			foreach (StringWithRarity stringWithRarity in stringWithRarityList)
			{
				list.Add(new StringWithRarity(stringWithRarity.Name, stringWithRarity.Rarity));
			}
			Dictionary<string, int> source = list.ToDictionary((StringWithRarity planet) => planet.Name, (StringWithRarity planet) => planet.Rarity);
			ConfigEntry<string> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("ScrapSpawnWeights", itemName + " " + configName, string.Join(",", source.Select((KeyValuePair<string, int> pair) => pair.Key + ":" + pair.Value)) ?? "", description);
			if (!string.IsNullOrEmpty(val.Value))
			{
				IEnumerable<string[]> enumerable = from pair in val.Value.Split(',')
					select pair.Split(':');
				foreach (string[] nameRarityPair in enumerable)
				{
					nameRarityPair[0] = nameRarityPair[0].Trim();
					nameRarityPair[1] = nameRarityPair[1].Trim();
					StringWithRarity val2 = ((IEnumerable<StringWithRarity>)list).FirstOrDefault((Func<StringWithRarity, bool>)((StringWithRarity planet) => planet.Name.Trim() == nameRarityPair[0]));
					try
					{
						if (val2 == null)
						{
							list.Add(new StringWithRarity(nameRarityPair[0], int.Parse(nameRarityPair[1])));
						}
						else
						{
							val2.Rarity = int.Parse(nameRarityPair[1]);
						}
					}
					catch (Exception ex)
					{
						Plugin.Log.LogError((object)("Error parsing config for LLL item" + itemName + ": " + val.Value + " - " + ex.Message + "\n" + ex.StackTrace));
					}
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(NetworkManager))]
	internal static class NetworkPrefab
	{
		private static readonly string MOD_GUID = "111.ChunkysFriendTweaks";

		[HarmonyPostfix]
		[HarmonyPatch("SetSingleton")]
		private static void RegisterPrefab()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(MOD_GUID + " Prefab");
			((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x3D);
			Object.DontDestroyOnLoad((Object)(object)val);
			NetworkObject obj = val.AddComponent<NetworkObject>();
			FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic);
			field.SetValue(obj, GetHash(MOD_GUID));
			NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(val);
			static uint GetHash(string value)
			{
				return value?.Aggregate(17u, (uint current, char c) => (current * 31) ^ c) ?? 0;
			}
		}
	}
}