Decompiled source of ShuffleShift v1.0.1

plugins/ShuffleShift/TheWeavers.ShuffleShift.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ShuffleShift.ActiveObject;
using ShuffleShift.Configurations;
using ShuffleShift.Patches;
using StaticNetcodeLib;
using TheWeavers.ShuffleShift.NetcodePatcher;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;

[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("TheWeavers.ShuffleShift")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+6fc5b0ca20f1073d721b78dfbdf58d0d7ef2ae39")]
[assembly: AssemblyProduct("ShuffleShift")]
[assembly: AssemblyTitle("TheWeavers.ShuffleShift")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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 ShuffleShift
{
	[BepInPlugin("TheWeavers.ShuffleShift", "ShuffleShift", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static AssetBundle? ModAssets;

		private readonly Harmony harmony = new Harmony("TheWeavers.ShuffleShift");

		public static Config ShuffleShiftConfig { get; internal set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			ShuffleShiftConfig = new Config(((BaseUnityPlugin)this).Config);
			Logger.LogInfo((object)"Loading : TheWeavers.ShuffleShift Version : 1.0.1");
			harmony.PatchAll(typeof(ConfigurationsPatch));
			harmony.PatchAll(typeof(StartOfRoundPatch));
			Logger.LogInfo((object)"Patch applied and ready to play!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TheWeavers.ShuffleShift";

		public const string PLUGIN_NAME = "ShuffleShift";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace ShuffleShift.Patches
{
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatch
	{
		[HarmonyPatch("UnloadSceneObjectsEarly")]
		[HarmonyPostfix]
		private static void UnloadSceneObjectEarly(RoundManager __instance)
		{
			SwapPositionHandler[] array = Object.FindObjectsOfType<SwapPositionHandler>();
			foreach (SwapPositionHandler swapPositionHandler in array)
			{
				if ((Object)(object)swapPositionHandler != (Object)null)
				{
					if (swapPositionHandler.swapCoroutine != null)
					{
						((MonoBehaviour)swapPositionHandler).StopCoroutine(swapPositionHandler.swapCoroutine);
					}
					Object.Destroy((Object)(object)((Component)swapPositionHandler).gameObject);
				}
			}
		}

		[HarmonyPatch("StartGame")]
		[HarmonyPostfix]
		private static void PostfixSpawn()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			SwapPositionHandler[] array = Object.FindObjectsOfType<SwapPositionHandler>();
			foreach (SwapPositionHandler swapPositionHandler in array)
			{
				if ((Object)(object)swapPositionHandler != (Object)null)
				{
					if (swapPositionHandler.swapCoroutine != null)
					{
						((MonoBehaviour)swapPositionHandler).StopCoroutine(swapPositionHandler.swapCoroutine);
					}
					Object.Destroy((Object)(object)((Component)swapPositionHandler).gameObject);
				}
			}
			if (!((NetworkBehaviour)RoundManager.Instance).IsHost)
			{
				return;
			}
			Scene sceneByName = SceneManager.GetSceneByName("SampleSceneRelay");
			if (!((Scene)(ref sceneByName)).IsValid() || !((Scene)(ref sceneByName)).isLoaded)
			{
				return;
			}
			GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
			bool flag = false;
			GameObject[] array2 = rootGameObjects;
			foreach (GameObject val in array2)
			{
				if (((Object)val).name == "ShuffleSwapHandler")
				{
					flag = true;
					break;
				}
			}
			if ((Object)(object)SwapPositionHandler.Instance == (Object)null && !flag)
			{
				GameObject val2 = new GameObject("ShuffleSwapHandler");
				val2.AddComponent<SwapPositionHandler>();
				SceneManager.MoveGameObjectToScene(val2, sceneByName);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		[HarmonyPatch("EndGameServerRpc")]
		[HarmonyPostfix]
		private static void UnloadSceneObjectEarly(RoundManager __instance)
		{
			if ((Object)(object)SwapPositionHandler.Instance != (Object)null)
			{
				SwapPositionHandler.Instance.DestroyManager();
			}
		}

		[HarmonyPatch("StartGame")]
		[HarmonyPostfix]
		private static void PostfixSpawn()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if ((Object)(object)SwapPositionHandler.Instance == (Object)null)
			{
				GameObject val = new GameObject("ShuffleSwapHandler");
				val.AddComponent<SwapPositionHandler>();
			}
		}
	}
}
namespace ShuffleShift.Configurations
{
	[Serializable]
	public class Config : SyncedInstance<Config>
	{
		public ConfigEntry<bool> ENABLE_POSITION_SWAP { get; private set; }

		public ConfigEntry<float> TIME_BETWEEN_SWAP { get; private set; }

		public ConfigEntry<float> TIME_BEFORE_FIRST_SWAP { get; private set; }

		public ConfigEntry<int> CHANCE_FOR_SWAP_TO_HAPPEN { get; private set; }

		public ConfigEntry<bool> ENABLE_SCREEN_SHAKE { get; private set; }

		public Config(ConfigFile cfg)
		{
			InitInstance(this);
			ENABLE_POSITION_SWAP = cfg.Bind<bool>("Position Swap", "Enable position swap", true, "Set to true if you want the position swap to possibly happen");
			TIME_BETWEEN_SWAP = cfg.Bind<float>("Position Swap", "Time Between each swap", 45f, "How much time between each position swap of the players!");
			TIME_BEFORE_FIRST_SWAP = cfg.Bind<float>("Position Swap", "Time before the first swap", 30f, "Time before the first swap occurs");
			CHANCE_FOR_SWAP_TO_HAPPEN = cfg.Bind<int>("Position Swap", "Chance of the swap happening", 100, "Chance in percentage for the position swap to happen. Must not be lower than 0");
			ENABLE_SCREEN_SHAKE = cfg.Bind<bool>("Position Swap", "Make the screen shake when teleporting", false, "true the screen shake will be, false, it will not");
		}

		public static void RequestSync()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(SyncedInstance<Config>.IntSize, (Allocator)2, -1);
			try
			{
				SyncedInstance<Config>.MessageManager.SendNamedMessage("Xilef992SwapShift_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsHost)
			{
				return;
			}
			Plugin.Logger.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] array = SyncedInstance<Config>.SerializeToBytes(SyncedInstance<Config>.Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<Config>.IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				SyncedInstance<Config>.MessageManager.SendNamedMessage("Xilef992SwapShift_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<Config>.IntSize))
			{
				Plugin.Logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				Plugin.Logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			SyncedInstance<Config>.SyncInstance(data);
			Plugin.Logger.LogInfo((object)"Successfully synced config with host.");
		}
	}
	public static class ConfigurationsPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if (((NetworkBehaviour)RoundManager.Instance).IsHost)
			{
				CustomMessagingManager messageManager = SyncedInstance<Config>.MessageManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = Config.OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				messageManager.RegisterNamedMessageHandler("SwapShift_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				SyncedInstance<Config>.Synced = true;
				return;
			}
			SyncedInstance<Config>.Synced = false;
			CustomMessagingManager messageManager2 = SyncedInstance<Config>.MessageManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = Config.OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messageManager2.RegisterNamedMessageHandler("SwapShift_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			Config.RequestSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			SyncedInstance<Config>.RevertSync();
		}
	}
	public class SyncedInstance<T>
	{
		[NonSerialized]
		protected static int IntSize = 4;

		internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;

		internal static bool IsClient => NetworkManager.Singleton.IsClient;

		internal static bool IsHost => NetworkManager.Singleton.IsHost;

		public static T Default { get; private set; }

		public static T Instance { get; private set; }

		public static bool Synced { get; internal set; }

		protected void InitInstance(T instance)
		{
			Default = instance;
			Instance = instance;
			IntSize = 4;
		}

		internal static void SyncInstance(byte[] data)
		{
			Instance = DeserializeFromBytes(data);
			Synced = true;
		}

		internal static void RevertSync()
		{
			Instance = Default;
			Synced = false;
		}

		public static byte[] SerializeToBytes(T val)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream memoryStream = new MemoryStream();
			try
			{
				binaryFormatter.Serialize(memoryStream, val);
				return memoryStream.ToArray();
			}
			catch (Exception arg)
			{
				Debug.Log((object)$"Error serializing instance: {arg}");
				return null;
			}
		}

		public static T DeserializeFromBytes(byte[] data)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream serializationStream = new MemoryStream(data);
			try
			{
				return (T)binaryFormatter.Deserialize(serializationStream);
			}
			catch (Exception arg)
			{
				Debug.Log((object)$"Error deserializing instance: {arg}");
				return default(T);
			}
		}
	}
}
namespace ShuffleShift.ActiveObject
{
	public class SwapPositionHandler : MonoBehaviour
	{
		private static SwapPositionHandler _instance;

		private int indexOfPick;

		private bool isInsideFactory;

		private bool isInHangarShipRoom;

		public Coroutine swapCoroutine;

		public static SwapPositionHandler Instance => _instance;

		private IEnumerator ActivationCoroutine()
		{
			while (true)
			{
				yield return (object)new WaitForSeconds(Plugin.ShuffleShiftConfig.TIME_BETWEEN_SWAP.Value);
				ActivateSwap();
			}
		}

		private void Awake()
		{
			if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				_instance = this;
			}
		}

		private void Start()
		{
			if (Plugin.ShuffleShiftConfig.ENABLE_POSITION_SWAP.Value && ((NetworkBehaviour)RoundManager.Instance).IsHost)
			{
				swapCoroutine = ((MonoBehaviour)this).StartCoroutine(ActivationCoroutine());
			}
		}

		public void ActivateSwap()
		{
			if (RandomNumberGenerator.GetInt32(0, 100) <= Plugin.ShuffleShiftConfig.CHANCE_FOR_SWAP_TO_HAPPEN.Value)
			{
				PositionHandler.ShufflePlayerTransforms();
			}
			else
			{
				Plugin.Logger.LogInfo((object)"Teleport was a miss!");
			}
		}

		public void OnDestroy()
		{
			((MonoBehaviour)this).StopCoroutine(swapCoroutine);
		}

		public void DestroyManager()
		{
			((Behaviour)this).enabled = false;
			((MonoBehaviour)this).StopCoroutine(swapCoroutine);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	[StaticNetcode]
	public static class PositionHandler
	{
		private static bool isInsideFactory;

		private static bool isInHangarShipRoom;

		private static int indexOfPick;

		private const float Y_OFFSET = 1f;

		public static void ShufflePlayerTransforms()
		{
			List<PlayerControllerB> allPlayer = GetAllPlayer();
			Plugin.Logger.LogInfo((object)("SWAPPING POSITION OF " + allPlayer.Count + " players !"));
			int[] array = Enumerable.Range(0, allPlayer.Count).ToArray();
			Shuffle(array);
			List<Vector3> list = allPlayer.Select((PlayerControllerB player) => ((Component)player).transform.position).ToList();
			List<Quaternion> list2 = allPlayer.Select((PlayerControllerB player) => ((Component)player).transform.rotation).ToList();
			FinalizeTeleportClientRpc(array, list.ToArray(), list2.ToArray());
		}

		[ClientRpc]
		private static void FinalizeTeleportClientRpc(int[] indexes, Vector3[] positions, Quaternion[] rotations)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = RoundManager.Instance.playersManager.allPlayerScripts;
			for (int i = 0; i < indexes.Length; i++)
			{
				int num = indexes[i];
				PlayerControllerB val = allPlayerScripts[num];
				if (val.isPlayerControlled && !val.isPlayerDead)
				{
					Transform transform = ((Component)val).transform;
					positions[i].y += 1f;
					transform.position = positions[i];
					transform.rotation = rotations[i];
					val.isInHangarShipRoom = isInsideFactory;
					val.isInHangarShipRoom = isInHangarShipRoom;
				}
			}
			if (Plugin.ShuffleShiftConfig.ENABLE_SCREEN_SHAKE.Value)
			{
				HUDManager.Instance.DisplayTip("SWAP", $"{indexes.Length} players position got swapped!", false, false, "LC_Tip1");
			}
		}

		private static List<PlayerControllerB> GetAllPlayer()
		{
			return RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB player) => player.isPlayerControlled && !player.isPlayerDead && !player.isClimbingLadder && !player.inTerminalMenu).ToList();
		}

		private static void Shuffle(int[] array)
		{
			Random random = new Random();
			int num = array.Length;
			while (num > 1)
			{
				num--;
				int num2 = random.Next(num + 1);
				int num3 = array[num2];
				array[num2] = array[num];
				array[num] = num3;
			}
		}
	}
}
namespace TheWeavers.ShuffleShift.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}