Please disclose if any significant portion of your mod was created 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 ShuffleShift v1.0.1
plugins/ShuffleShift/TheWeavers.ShuffleShift.dll
Decompiled 2 years agousing 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 { } }