Decompiled source of RandomWind v1.0.0

RandomWind.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 Mirror;
using TMPro;
using UnityEngine;
using UnityEngine.Localization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("GameAssembly")]
[assembly: IgnoresAccessChecksTo("SharedAssembly")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RandomWind")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1b90ff945a285959a9ec2b98a235974fe797ddc3")]
[assembly: AssemblyProduct("Random Wind")]
[assembly: AssemblyTitle("RandomWind")]
[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 RandomWind
{
	[BepInPlugin("com.sbg.randomwind", "RandomWind", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.sbg.randomwind";

		public const string PLUGIN_NAME = "RandomWind";

		public const string PLUGIN_VERSION = "1.0.0";

		internal static ManualLogSource Log { get; private set; }

		internal static RandomWindConfig Settings { get; private set; }

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new RandomWindConfig(((BaseUnityPlugin)this).Config);
			new Harmony("com.sbg.randomwind").PatchAll();
			var (num, num2) = Settings.GetNormalizedRange();
			Log.LogInfo((object)string.Format("{0} {1} loaded (random wind {2}-{3} km/h).", "RandomWind", "1.0.0", num, num2));
		}
	}
	internal sealed class RandomWindConfig
	{
		internal const int MAX_POSSIBLE_WIND_KMH = 100;

		internal const int MIN_POSSIBLE_WIND_KMH = 0;

		private const int DEFAULT_MIN_WIND_KMH = 0;

		private const int DEFAULT_MAX_WIND_KMH = 99;

		private const float NO_BIAS = 1f;

		private const float MAX_LOW_WIND_BIAS = 4f;

		private const int DEFAULT_NO_WIND_CHANCE_PERCENT = 0;

		private const string SECTION = "RandomWind";

		private const string SECTION_DISTRIBUTION = "Distribution";

		internal ConfigEntry<int> MinWindKmh { get; }

		internal ConfigEntry<int> MaxWindKmh { get; }

		internal ConfigEntry<float> LowWindBias { get; }

		internal ConfigEntry<int> NoWindChancePercent { get; }

		internal ConfigEntry<bool> UseDropdownOption { get; }

		internal ConfigEntry<bool> FallbackOverrideEnabled { get; }

		internal RandomWindConfig(ConfigFile config)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			AcceptableValueRange<int> val = new AcceptableValueRange<int>(0, 100);
			MinWindKmh = config.Bind<int>("RandomWind", "MinWindKmh", 0, new ConfigDescription("Lowest wind speed (km/h) the Random option can roll.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			MaxWindKmh = config.Bind<int>("RandomWind", "MaxWindKmh", 99, new ConfigDescription("Highest wind speed (km/h) the Random option can roll.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			LowWindBias = config.Bind<float>("Distribution", "LowWindBias", 1f, new ConfigDescription("1 = every speed equally likely. Higher skews rolls toward the minimum: 1.5 averages about 40 km/h over 0-99 (like vanilla Medium), 2 about 33.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), Array.Empty<object>()));
			NoWindChancePercent = config.Bind<int>("Distribution", "NoWindChancePercent", 0, new ConfigDescription("Extra chance (0-100) that a hole rolls exactly the minimum speed, checked before anything else. With a minimum of 0 this is the chance of no wind.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			UseDropdownOption = config.Bind<bool>("RandomWind", "UseDropdownOption", true, "Add a 'Random' entry to the Wind dropdown in the match setup menu.");
			FallbackOverrideEnabled = config.Bind<bool>("RandomWind", "FallbackOverrideEnabled", false, "Roll every non-Off wind setting in the min/max range instead of its tier. Use this if the dropdown option misbehaves after a game update.");
		}

		internal (int Min, int Max) GetNormalizedRange()
		{
			return WindSpeedRoller.Normalize(MinWindKmh.Value, MaxWindKmh.Value, 0, 100);
		}
	}
	internal static class WindSpeedRoller
	{
		private const int PERCENT_SCALE = 100;

		private const double NO_BIAS_THRESHOLD = 1.0;

		internal static (int Min, int Max) Normalize(int first, int second, int floor, int ceiling)
		{
			int num = Math.Min(Math.Max(first, floor), ceiling);
			int num2 = Math.Min(Math.Max(second, floor), ceiling);
			if (num > num2)
			{
				return (Min: num2, Max: num);
			}
			return (Min: num, Max: num2);
		}

		internal static int Roll(int min, int max, double lowWindBias, int noWindChancePercent, Func<int, int, int> nextIntExclusiveMax, Func<double> nextUnit)
		{
			if (noWindChancePercent > 0 && nextIntExclusiveMax(0, 100) < noWindChancePercent)
			{
				return min;
			}
			if (lowWindBias <= 1.0)
			{
				return nextIntExclusiveMax(min, max + 1);
			}
			int num = max - min;
			double num2 = Math.Pow(nextUnit(), lowWindBias);
			return min + Math.Min(num, (int)(num2 * (double)(num + 1)));
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "RandomWind";

		public const string PLUGIN_NAME = "Random Wind";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace RandomWind.Patches
{
	internal static class RandomWindOption
	{
		internal const int RANDOM_WIND_VALUE = 5;

		internal const string RANDOM_OPTION_LABEL = "Random";

		private const int VANILLA_OPTION_COUNT = 5;

		private static readonly HashSet<LocalizeDropdown> ExtendedDropdowns = new HashSet<LocalizeDropdown>();

		internal static bool IsExtended(LocalizeDropdown dropdown)
		{
			return ExtendedDropdowns.Contains(dropdown);
		}

		internal static void EnsureRandomOption(DropdownOption windDropdown)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			LocalizeDropdown val = (((Object)(object)windDropdown != (Object)null) ? windDropdown.Localized : null);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Wind dropdown has no LocalizeDropdown; cannot add the Random option. Cause: the game's menu layout changed. Resolution: enable FallbackOverrideEnabled in the config.");
			}
			else if (!ExtendedDropdowns.Contains(val))
			{
				List<LocalizedString> dropdownOptions = val.dropdownOptions;
				if (dropdownOptions.Count != 5)
				{
					Plugin.Log.LogWarning((object)($"Wind dropdown has {dropdownOptions.Count} options, expected {5}; " + "leaving it untouched."));
					return;
				}
				LocalizedString val2 = dropdownOptions[dropdownOptions.Count - 1];
				dropdownOptions.Add(new LocalizedString(((LocalizedReference)val2).TableReference, ((LocalizedReference)val2).TableEntryReference));
				ExtendedDropdowns.Add(val);
				val.RefreshOptions();
			}
		}
	}
	[HarmonyPatch(typeof(MatchSetupRules), "Initialize")]
	internal static class AddRandomOptionPatch
	{
		[HarmonyPrefix]
		private static void Prefix(MatchSetupRules __instance)
		{
			if (Plugin.Settings.UseDropdownOption.Value)
			{
				RandomWindOption.EnsureRandomOption(__instance.wind);
			}
		}
	}
	[HarmonyPatch(typeof(LocalizeDropdown), "RefreshOptions")]
	internal static class RelabelRandomOptionPatch
	{
		[HarmonyPostfix]
		private static void Postfix(LocalizeDropdown __instance)
		{
			if (RandomWindOption.IsExtended(__instance))
			{
				List<OptionData> options = __instance.tmpDropdown.options;
				if (options.Count > 5)
				{
					options[5].text = "Random";
					__instance.tmpDropdown.RefreshShownValue();
				}
			}
		}
	}
	[HarmonyPatch(typeof(MatchSetupRules), "GetFormattedValue")]
	internal static class FormatRandomValuePatch
	{
		[HarmonyPostfix]
		private static void Postfix(MatchSetupRules __instance, Rule rule, ref string __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if ((int)rule == 20 && (int)__instance.GetValueInternal(rule) == 5)
			{
				__result = "Random";
			}
		}
	}
	[HarmonyPatch(typeof(WindManager), "RandomizeWind")]
	internal static class WindRollPatch
	{
		private const int WIND_RULE_OFF_VALUE = 0;

		[HarmonyPostfix]
		private static void Postfix(WindManager __instance)
		{
			if (NetworkServer.active && __instance.initialized && ShouldRollRandomSpeed())
			{
				var (min, max) = Plugin.Settings.GetNormalizedRange();
				__instance.NetworkcurrentWindSpeed = WindSpeedRoller.Roll(min, max, (double)Plugin.Settings.LowWindBias.Value, Plugin.Settings.NoWindChancePercent.Value, (Func<int, int, int>)Random.Range, (Func<double>)(() => Random.value));
			}
		}

		private static bool ShouldRollRandomSpeed()
		{
			int num = (int)MatchSetupRules.GetValue((Rule)20);
			if (num == 5)
			{
				return Plugin.Settings.UseDropdownOption.Value;
			}
			if (Plugin.Settings.FallbackOverrideEnabled.Value)
			{
				return num != 0;
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}