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
{
}
}