Decompiled source of MapCycler v1.0.0

MapCycler.dll

Decompiled 2 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Alipali737")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+36667c47b29edc3c3290204775b9456e984b97d6")]
[assembly: AssemblyProduct("MapCycler")]
[assembly: AssemblyTitle("MapCycler")]
[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.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]
	[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]
	[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 MapCycler
{
	internal static class CycleState
	{
		internal static Dictionary<string, int> Played()
		{
			return StatsManager.instance.dictionaryOfDictionaries["mapCyclerPlayed"];
		}
	}
	internal static class LevelPicker
	{
		internal static Level? Pick(List<Level> levels, Dictionary<string, int> played, Level? previous)
		{
			List<Level> source = levels.Where((Level l) => (Object)(object)l != (Object)null).ToList();
			List<string> available = source.Select((Level l) => ((Object)l).name).ToList();
			string picked = PickName(available, played, (previous != null) ? ((Object)previous).name : null, (int n) => Random.Range(0, n));
			if (picked == null)
			{
				return null;
			}
			return ((IEnumerable<Level>)source).FirstOrDefault((Func<Level, bool>)((Level l) => ((Object)l).name == picked));
		}

		internal static string? PickName(IReadOnlyList<string> available, Dictionary<string, int> played, string? previousName, Func<int, int> nextInt)
		{
			if (available.Count == 0)
			{
				return null;
			}
			List<string> list = played.Keys.ToList();
			foreach (string item in list)
			{
				if (!available.Contains(item))
				{
					played.Remove(item);
				}
			}
			List<string> list2 = available.Where((string n) => !played.ContainsKey(n)).ToList();
			if (list2.Count == 0)
			{
				played.Clear();
				list2 = available.ToList();
				if (list2.Count > 1 && previousName != null)
				{
					list2.Remove(previousName);
				}
			}
			return list2[nextInt(list2.Count)];
		}
	}
	[BepInPlugin("Alipali737.MapCycler", "MapCycler", "1.0")]
	public class MapCycler : BaseUnityPlugin
	{
		internal static MapCycler Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_0019: 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)
			//IL_0020: Expected O, but got Unknown
			//IL_0025: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}
	}
	[HarmonyPatch(typeof(RunManager))]
	internal static class RunManagerPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("SetRunLevel")]
		private static bool SetRunLevel_Prefix(RunManager __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			Level previousRunLevel = __instance.previousRunLevel;
			Level val = LevelPicker.Pick(__instance.levels, CycleState.Played(), previousRunLevel);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			__instance.levelCurrent = val;
			MapCycler.Logger.LogInfo((object)$"Picked {((Object)val).name}, Levels Played: {CycleState.Played().Count}, Total Levels: {__instance.levels.Count}");
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("ChangeLevel")]
		private static void ChangeLevel_Prefix(RunManager __instance, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)__instance.levelCurrent == (Object)null) && _completedLevel && !_levelFailed && (int)_changeLevelType == 0 && __instance.levels.Contains(__instance.levelCurrent))
			{
				CycleState.Played()[((Object)__instance.levelCurrent).name] = 1;
				MapCycler.Logger.LogInfo((object)$"Marked {((Object)__instance.levelCurrent).name} as played ({CycleState.Played().Count}/{__instance.levels.Count})");
			}
		}
	}
	[HarmonyPatch(typeof(StatsManager))]
	internal static class StatsManagerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void Start_Postfix(StatsManager __instance)
		{
			if (!__instance.dictionaryOfDictionaries.ContainsKey("mapCyclerPlayed"))
			{
				__instance.dictionaryOfDictionaries.Add("mapCyclerPlayed", new Dictionary<string, int>());
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("LoadGame")]
		private static void LoadGame_Postfix()
		{
			MapCycler.Logger.LogInfo((object)$"mapCyclerPlayed: {CycleState.Played().Count} elements");
			foreach (KeyValuePair<string, int> item in CycleState.Played())
			{
				MapCycler.Logger.LogInfo((object)$"Key: {item.Key}, Value: {item.Value}");
			}
		}
	}
}