Decompiled source of ExtractionRandomizerPlus v1.0.1

plugins/ExtractionRandomizerPlus.dll

Decompiled 25 minutes ago
using 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.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
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("ExtractionRandomizerPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("ExtractionRandomizerPlus")]
[assembly: AssemblyTitle("ExtractionRandomizerPlus")]
[assembly: AssemblyVersion("1.0.1.0")]
[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 ExtractionRandomizerPlus
{
	[HarmonyPatch]
	[HarmonyPriority(0)]
	internal static class LevelGeneratorExtractionAmountPatch
	{
		private static readonly FieldInfo ExtractionAmount = AccessTools.Field(typeof(LevelGenerator), "ExtractionAmount");

		private static MethodBase TargetMethod()
		{
			Type type = typeof(LevelGenerator).GetNestedTypes(BindingFlags.NonPublic).FirstOrDefault((Type t) => t.Name.StartsWith("<TileGeneration>d__", StringComparison.Ordinal));
			if (!(type == null))
			{
				return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(LevelGeneratorExtractionAmountPatch), "ApplyExtractionCount", (Type[])null, (Type[])null);
			int num = list.FindIndex((CodeInstruction code) => code.opcode == OpCodes.Call && (code.operand as MethodInfo)?.Name == "IsLevelShop");
			if (num >= 0)
			{
				list.Insert(num, new CodeInstruction(OpCodes.Ldloc_1, (object)null));
				list.Insert(num + 1, new CodeInstruction(OpCodes.Call, (object)methodInfo));
			}
			else
			{
				Plugin.Log.LogWarning((object)"[ExtractionRandomizerPlus] Could not find IsLevelShop in TileGeneration; ExtractionAmount will not be raised.");
			}
			return list;
		}

		private static void ApplyExtractionCount(LevelGenerator generator)
		{
			try
			{
				if (!((Object)(object)generator == (Object)null) && SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel() && !SemiFunc.IsLevelShop(generator.Level))
				{
					int num = (int)ExtractionAmount.GetValue(generator);
					int num2 = Plugin.EnsureTargetCount();
					int num3 = Math.Max(0, num2 - 1);
					if (num == num3)
					{
						Plugin.Log.LogInfo((object)($"[ExtractionRandomizerPlus] ExtractionAmount already {num3} " + $"(total {num2} incl. truck extraction)"));
						return;
					}
					ExtractionAmount.SetValue(generator, num3);
					Plugin.Log.LogInfo((object)($"[ExtractionRandomizerPlus] ExtractionAmount: {num} -> {num3} " + $"(total {num2} incl. truck extraction)"));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ExtractionRandomizerPlus] Could not set ExtractionAmount: " + ex));
			}
		}
	}
	internal static class LevelSeed
	{
		internal static string Describe()
		{
			return RoomName() + "|" + LevelName() + "|" + SemiFunc.RunGetLevelsCompleted();
		}

		private static string LevelName()
		{
			RunManager instance = RunManager.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.levelCurrent == (Object)null)
			{
				return "unknown-level";
			}
			return ((Object)instance.levelCurrent).name;
		}

		private static string RoomName()
		{
			try
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				if (currentRoom != null && !string.IsNullOrEmpty(currentRoom.Name))
				{
					return currentRoom.Name;
				}
			}
			catch
			{
			}
			return "offline";
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "HaulGoalSet")]
	internal static class HaulGoalPatch
	{
		private static void Prefix(ref int value)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel())
			{
				float value2 = Plugin.HaulGoalMultiplier.Value;
				int num = Mathf.Max(1, (int)((float)value * value2));
				Plugin.Log.LogInfo((object)$"[ExtractionRandomizerPlus] HaulGoal scaled on host: {value} * {value2} -> {num}");
				value = num;
			}
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "TileGeneration")]
	internal static class LevelGeneratorTileGenerationResetPatch
	{
		private static void Prefix()
		{
			Plugin.TargetCount = -1;
			Plugin.Log.LogInfo((object)"[ExtractionRandomizerPlus] New level - target count reset");
		}
	}
	[BepInPlugin("firenyth.extractionrandomizerplus", "Extraction Randomizer Plus", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "firenyth.extractionrandomizerplus";

		public const string PluginVersion = "1.0.1";

		public static ConfigEntry<int> MinExtractionPoints;

		public static ConfigEntry<int> MaxExtractionPoints;

		public static ConfigEntry<float> HaulGoalMultiplier;

		internal static int TargetCount = -1;

		internal static Plugin Instance { get; private set; }

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

		internal static int EnsureTargetCount()
		{
			int num = MinExtractionPoints.Value;
			int value = MaxExtractionPoints.Value;
			if (num > value)
			{
				num = value;
			}
			if (TargetCount == -1)
			{
				string text = LevelSeed.Describe();
				int num2 = StableHash.Of(text);
				TargetCount = new Random(num2).Next(num, value + 1);
				Log.LogInfo((object)($"[ExtractionRandomizerPlus] Level: {text}, Seed: {num2}, " + $"Target: {TargetCount} total extraction points (range {num}-{value})"));
			}
			return TargetCount;
		}

		private void Awake()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			MinExtractionPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Extraction Points", "Minimum", 1, new ConfigDescription("Minimum total extraction points per level (the truck extraction counts toward this)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			MaxExtractionPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Extraction Points", "Maximum", 3, new ConfigDescription("Maximum total extraction points per level (the truck extraction counts toward this)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			HaulGoalMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Rewards", "Haul Goal Multiplier", 0.33f, new ConfigDescription("Host-side haul goal multiplier. 0.33 is one third of vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			new Harmony("firenyth.extractionrandomizerplus").PatchAll();
			Log.LogInfo((object)(string.Format("ExtractionRandomizerPlus {0} loaded! Min={1}, ", "1.0.1", MinExtractionPoints.Value) + $"Max={MaxExtractionPoints.Value}, HaulGoalMultiplier={HaulGoalMultiplier.Value}. " + "The host decides extraction count by setting LevelGenerator.ExtractionAmount."));
		}
	}
	internal static class StableHash
	{
		internal static int Of(string value)
		{
			uint num = 5381u;
			for (int i = 0; i < value.Length; i++)
			{
				num = ((num << 5) + num) ^ value[i];
			}
			return (int)(num & 0x7FFFFFFF);
		}
	}
}