Please disclose if your mod was created primarily 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 LetMePlay v1.6.1
LetMePlay.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using ComfyLib; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LetMePlay")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LetMePlay")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("89ef3289-8b5a-4174-8b1e-a082ab4fe9be")] [assembly: AssemblyFileVersion("1.6.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.6.1.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LetMePlay { public static class PluginConfig { public static ConfigEntry<bool> IsModEnabled { get; private set; } public static ConfigEntry<bool> DisableWardShieldFlash { get; private set; } public static ConfigEntry<bool> DisableBuildPlacementMarker { get; private set; } public static ConfigEntry<bool> DisableWeatherSnowParticles { get; private set; } public static ConfigEntry<bool> DisableWeatherAshParticles { get; private set; } public static void BindConfig(ConfigFile config) { IsModEnabled = config.BindInOrder("_Global", "isModEnabled", defaultValue: true, "Globally enable or disable this mod."); IsModEnabled.OnSettingChanged<bool>(EnvManagerUtils.SetupCurrentWeather); DisableWardShieldFlash = config.BindInOrder("Effects", "disableWardShieldFlash", defaultValue: false, "Disable wards from flashing their blue shield."); DisableBuildPlacementMarker = config.BindInOrder("Build", "disableBuildPlacementMarker", defaultValue: false, "Disables the yellow placement marker (and gizmo indicator) when building."); DisableWeatherSnowParticles = config.BindInOrder("Weather", "disableWeatherSnowParticles", defaultValue: false, "Disables ALL snow particles during snow/snowstorm weather."); DisableWeatherSnowParticles.OnSettingChanged<bool>(EnvManagerUtils.SetupCurrentWeather); DisableWeatherAshParticles = config.BindInOrder("Weather", "disableWeatherAshParticles", defaultValue: false, "Disables ALL ash particles during ash rain weather."); DisableWeatherAshParticles.OnSettingChanged<bool>(EnvManagerUtils.SetupCurrentWeather); } } public static class EnvManagerUtils { public static bool IsSnowWeather(string weatherName) { switch (weatherName) { case "Snow": case "SnowStorm": case "Twilight_Snow": case "Twilight_SnowStorm": return true; default: return false; } } public static bool IsAshWeather(string weatherName) { if (weatherName == "Ashlands_ashrain" || weatherName == "Ashlands_storm") { return true; } return false; } public static void SetupCurrentWeather() { EnvMan s_instance = EnvMan.s_instance; if (Object.op_Implicit((Object)(object)s_instance) && s_instance.m_currentEnv != null && s_instance.m_currentPSystems != null) { if (IsSnowWeather(s_instance.m_currentEnv.m_name)) { s_instance.SetParticleArrayEnabled(s_instance.m_currentPSystems, !PluginConfig.IsModEnabled.Value || !PluginConfig.DisableWeatherSnowParticles.Value); } if (IsAshWeather(s_instance.m_currentEnv.m_name)) { s_instance.SetParticleArrayEnabled(s_instance.m_currentPSystems, !PluginConfig.IsModEnabled.Value || !PluginConfig.DisableWeatherAshParticles.Value); } } } } public static class ItemDropUtils { public static readonly ResourceCache<Sprite> SpriteCache = new ResourceCache<Sprite>(); public static void ValidateIcons(ItemData itemData, int variant, int iconCount) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (variant >= 0 && variant < iconCount) { return; } if (iconCount > 0) { itemData.m_variant = 0; return; } SharedData shared = itemData.m_shared; Array.Resize(ref shared.m_icons, variant + 1); shared.m_icons[variant] = SpriteCache.GetResource("hammer_icon_small"); shared.m_name = ((Object)itemData.m_dropPrefab).name; shared.m_description = "Non-player item: " + shared.m_name; shared.m_itemType = (ItemType)16; if (itemData.m_crafterID == 0L) { itemData.m_crafterID = 12345678L; } if (string.IsNullOrEmpty(itemData.m_crafterName)) { itemData.m_crafterName = "redseiko.valheim.letmeplay"; } } } [BepInPlugin("redseiko.valheim.letmeplay", "LetMePlay", "1.6.1")] public sealed class LetMePlay : BaseUnityPlugin { public const string PluginGUID = "redseiko.valheim.letmeplay"; public const string PluginName = "LetMePlay"; public const string PluginVersion = "1.6.1"; public void Awake() { PluginConfig.BindConfig(((BaseUnityPlugin)this).Config); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "redseiko.valheim.letmeplay"); } } [HarmonyPatch(typeof(EnvMan))] internal static class EnvManPatch { [HarmonyTranspiler] [HarmonyPatch("SetEnv")] private static IEnumerable<CodeInstruction> SetEnvTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown List<Label> labels; Label label; return new CodeMatcher(instructions, generator).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[5] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(EnvSetup), "m_psystems"), (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(EnvMan), "SetParticleArrayEnabled", (Type[])null, (Type[])null), (string)null) }).ThrowIfInvalid("Could not patch EnvMan.SetEnv()! (set-particle-array-enabled-true") .ExtractLabels(out labels) .CreateLabelOffset(5, out label) .Insert((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(EnvManPatch), "SetEnvDelegate", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Brfalse, (object)label) }) .AddLabels((IEnumerable<Label>)labels) .InstructionEnumeration(); } private static bool SetEnvDelegate(EnvSetup envSetup) { if (PluginConfig.IsModEnabled.Value) { if (PluginConfig.DisableWeatherSnowParticles.Value && EnvManagerUtils.IsSnowWeather(envSetup.m_name)) { return false; } if (PluginConfig.DisableWeatherAshParticles.Value && EnvManagerUtils.IsAshWeather(envSetup.m_name)) { return false; } } return true; } } [HarmonyPatch(typeof(ItemData))] internal static class ItemDataPatch { [HarmonyPrefix] [HarmonyPatch("GetIcon")] private static void GetIconPrefix(ItemData __instance) { if (PluginConfig.IsModEnabled.Value) { ItemDropUtils.ValidateIcons(__instance, __instance.m_variant, __instance.m_shared.m_icons.Length); } } } [HarmonyPatch(typeof(Player))] internal static class PlayerPatch { [HarmonyPostfix] [HarmonyPatch("UpdatePlacementGhost")] private static void UpdatePlacementGhostPostfix(Player __instance) { if (Object.op_Implicit((Object)(object)__instance)) { SetupPlacementMarker(__instance.m_placementMarkerInstance); } } public static void SetupPlacementMarker(GameObject placementMarker) { if (Object.op_Implicit((Object)(object)placementMarker) && PluginConfig.IsModEnabled.Value && PluginConfig.DisableBuildPlacementMarker.Value) { placementMarker.SetActive(false); } } } [HarmonyPatch(typeof(PrivateArea))] internal static class PrivateAreaPatch { [HarmonyPrefix] [HarmonyPatch("RPC_FlashShield")] private static bool PrivateAreaRpcFlashShield() { if (PluginConfig.IsModEnabled.Value && PluginConfig.DisableWardShieldFlash.Value) { return false; } return true; } } [HarmonyPatch(typeof(SpawnArea))] internal static class SpawnAreaPatch { private static readonly Predicate<SpawnData> _hasInvalidPrefab = HasInvalidPrefab; [HarmonyPostfix] [HarmonyPatch("Awake")] private static void AwakePostfix(SpawnArea __instance) { if (PluginConfig.IsModEnabled.Value && __instance.m_prefabs != null) { __instance.m_prefabs.RemoveAll(_hasInvalidPrefab); } } private static bool HasInvalidPrefab(SpawnData spawnData) { return !Object.op_Implicit((Object)(object)spawnData.m_prefab); } } } namespace ComfyLib { public static class CodeMatcherExtensions { public static CodeMatcher CreateLabelOffset(this CodeMatcher matcher, int offset, out Label label) { return matcher.CreateLabelAt(matcher.Pos + offset, ref label); } public static CodeMatcher ExtractLabels(this CodeMatcher matcher, out List<Label> labels) { labels = matcher.Labels.ToList(); matcher.Labels.Clear(); return matcher; } public static CodeMatcher SaveOperand(this CodeMatcher matcher, out object operand) { operand = matcher.Operand; return matcher; } } public static class ConfigFileExtensions { internal sealed class ConfigurationManagerAttributes { public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public bool? HideDefaultButton; public bool? HideSettingName; public bool? IsAdvanced; public int? Order; public bool? ReadOnly; } private static readonly Dictionary<string, int> _sectionToSettingOrder = new Dictionary<string, int>(); private static int GetSettingOrder(string section) { if (!_sectionToSettingOrder.TryGetValue(section, out var value)) { value = 0; } _sectionToSettingOrder[section] = value - 1; return value; } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false, bool isAdvanced = false, bool readOnly = false) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1] { new ConfigurationManagerAttributes { Browsable = browsable, CustomDrawer = null, HideDefaultButton = hideDefaultButton, HideSettingName = hideSettingName, IsAdvanced = isAdvanced, Order = GetSettingOrder(section), ReadOnly = readOnly } })); } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, Action<ConfigEntryBase> customDrawer = null, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false, bool isAdvanced = false, bool readOnly = false) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = browsable, CustomDrawer = customDrawer, HideDefaultButton = hideDefaultButton, HideSettingName = hideSettingName, IsAdvanced = isAdvanced, Order = GetSettingOrder(section), ReadOnly = readOnly } })); } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action settingChangedHandler) { configEntry.SettingChanged += delegate { settingChangedHandler(); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<T> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((T)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<ConfigEntry<T>> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((ConfigEntry<T>)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue); }; } } public static class ObjectExtensions { public static T FirstByNameOrThrow<T>(this T[] unityObjects, string name) where T : Object { foreach (T val in unityObjects) { if (((Object)val).name == name) { return val; } } throw new InvalidOperationException($"Could not find Unity object of type {typeof(T)} with name: {name}"); } public static T Ref<T>(this T unityObject) where T : Object { if (!Object.op_Implicit((Object)(object)unityObject)) { return default(T); } return unityObject; } } public sealed class ResourceCache<T> where T : Object { private readonly Dictionary<string, T> _cache = new Dictionary<string, T>(); public T GetResource(string resourceName) { if (!_cache.TryGetValue(resourceName, out var value)) { value = Resources.FindObjectsOfTypeAll<T>().FirstByNameOrThrow(resourceName); _cache[resourceName] = value; } return value; } } }