Due to update 2.4.3, some mods may no longer function. FixedConfig may be necessary.
Decompiled source of Desink Detecter For MapMaker v1.0.5
DesinkDetecterForMapMaker.dll
Decompiled 5 months agousing System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BoplFixedMath; using Entwined; using HarmonyLib; using MapMaker; using Microsoft.CodeAnalysis; using Steamworks.Data; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("DesinkDetecterForMapMaker")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("My first plugin")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DesinkDetecterForMapMaker")] [assembly: AssemblyTitle("DesinkDetecterForMapMaker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 AntiKick { public static class PluginInfo { public const string PLUGIN_GUID = "DesinkDetecterForMapMaker"; public const string PLUGIN_NAME = "DesinkDetecterForMapMaker"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace DesinkDetecterForMapMaker { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.David_Loves_JellyCar_Worlds.DesinkDetecterMapMaker", "DesinkDetecterMapMaker", "1.0.0")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(Host))] public class myPatches { [HarmonyPatch("SendChecksumToPlayer1")] [HarmonyPrefix] private static bool FuncName_PlugenName_Plug(Host __instance, uint seqNum) { ulong num = CalculateChecksum(); if (seqNum == 1) { LocalChecksums = new Dictionary<uint, ulong>(); LocalDebugInfo = new Dictionary<uint, string>(); } LocalChecksums.Add(seqNum, num); string value = SerializeState(); LocalDebugInfo.Add(seqNum, value); Checksum checksum = default(Checksum); checksum.tick = seqNum; checksum.checksum = num; checksum.level = Plugin.CurrentLevelIdForInputsOnlineThingy; ChecksumsChannel.SendMessage(checksum); return false; } } [HarmonyPatch(typeof(FixTransform))] public class myPatches2 { [HarmonyPatch("Awake")] [HarmonyPrefix] private static void FuncName_PlugenName_Plug(FixTransform __instance) { FixTransforms.Add(__instance); } } [HarmonyPatch(typeof(SteamSocket))] public class myPatches3 { [HarmonyPatch("OnDisconnected")] [HarmonyPrefix] private static void FuncName_PlugenName_Plug(SteamSocket __instance, Connection connection, ConnectionInfo data) { int num = LocalDebugInfo.Count - 1; Debug.Log((object)"someone disconented! logging last 5 debug datas."); while (num > LocalDebugInfo.Count - 6) { Debug.Log((object)("debug data for frame " + num)); Debug.Log((object)("frame data = " + LocalDebugInfo[(uint)num])); num--; } } } [HarmonyPatch(typeof(SteamManager))] public class myPatches4 { [HarmonyPatch("ForceLoadNextLevel")] [HarmonyPrefix] private static void FuncName_PlugenName_Plug(SteamManager __instance) { if (LogDebugInfoAtRoundEnd) { Debug.Log((object)"logging all debug info for this round, get ready for log spam!"); LogDebugInfoAtRoundEnd = false; for (uint num = 1u; num < LocalDebugInfo.Count + 1; num++) { Debug.Log((object)$"debug data on tick {num} is {LocalDebugInfo[num]}"); } Debug.Log((object)"Log Spam Complete!"); } LocalDebugInfo.Clear(); RemoveDesyncWarning(); } } [HarmonyPatch(typeof(GameSessionHandler))] public class myPatches5 { [HarmonyPatch("WinGame")] [HarmonyPrefix] private static bool FuncName_PlugenName_Plug(GameSessionHandler __instance, int team) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) AudioManager val = AudioManager.Get(); if ((Object)(object)val != (Object)null) { val.OnMatchEnded(false); } __instance.ActivateSuddenDeath(false); for (int i = 0; i < PlayerHandler.Get().PlayerList().Count; i++) { PlayerHandler.Get().PlayerList()[i].IsMostRecentWinner = false; } if ((Object)(object)textObj == (Object)null) { for (int j = 0; j < PlayerHandler.Get().PlayerList().Count; j++) { Player val2 = PlayerHandler.Get().PlayerList()[j]; if (val2.Team == team) { val2.WinAGame(); } } AchievementHandler.CheckAchievementsOnWinRound(); } AchievementHandler.OnRoundEnded(); __instance.prepareNextlevel(); if (!Object.op_Implicit((Object)(object)__instance.winnerTriangle)) { __instance.winnerTriangleCanvas = ((Component)WinnerTriangleCanvas.instance).gameObject; __instance.winnerTriangle = ((Component)((Component)WinnerTriangleCanvas.instance.charStatsList).transform.parent).gameObject; } __instance.playerInitRoutine.Delay(__instance.DelayBeforeNextLevelInput - (Fix)2L); __instance.playerInitRoutine.Function((Action)__instance.ActivateWinnerTriangle); return false; } [HarmonyPatch("DeclareGameUndecided")] [HarmonyPrefix] private static bool FuncName_PlugenName_Plug2(GameSessionHandler __instance, List<Player> playerList) { //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) AudioManager val = AudioManager.Get(); if ((Object)(object)val != (Object)null) { val.OnMatchEnded(true); } __instance.gameInProgress = false; AchievementHandler.OnRoundEnded(); __instance.ActivateSuddenDeath(false); if ((Object)(object)textObj == (Object)null) { long num = 0L; for (int i = 0; i < playerList.Count; i++) { if (num < playerList[i].TimestampWhenKilled) { num = playerList[i].TimestampWhenKilled; } } for (int j = 0; j < playerList.Count; j++) { if (num == playerList[j].TimestampWhenKilled) { playerList[j].IsMostRecentWinner = true; } else { playerList[j].IsMostRecentWinner = false; } } for (int k = 0; k < playerList.Count; k++) { if (!playerList[k].IsMostRecentWinner) { continue; } for (int l = 0; l < playerList.Count; l++) { if (playerList[k].Team == playerList[l].Team) { playerList[l].IsMostRecentWinner = true; } } } bool flag = true; for (int m = 0; m < playerList.Count; m++) { if (!playerList[m].IsMostRecentWinner) { flag = false; } } if (flag && PlayerHandler.Get().NumberOfPlayers() == 4) { AchievementHandler.TryAwardAchievement((AchievementEnum)20); } for (int n = 0; n < playerList.Count; n++) { if (playerList[n].IsMostRecentWinner) { playerList[n].WinAGame(); } } AchievementHandler.CheckAchievementsOnWinRound(); } __instance.prepareNextlevel(); if (!Object.op_Implicit((Object)(object)__instance.winnerTriangle)) { __instance.winnerTriangleCanvas = ((Component)WinnerTriangleCanvas.instance).gameObject; __instance.winnerTriangle = ((Component)((Component)WinnerTriangleCanvas.instance.charStatsList).transform.parent).gameObject; } __instance.playerInitRoutine.Delay(__instance.DelayBeforeNextLevelInput - (Fix)2L); __instance.playerInitRoutine.Function((Action)__instance.ActivateWinnerTriangle); return false; } } [HarmonyPatch(typeof(CharacterStatsList))] public class myPatches6 { [HarmonyPatch("ForceNextLevelImmediately")] [HarmonyPrefix] private static void FuncName_PlugenName_Plug(CharacterStatsList __instance) { if (LogDebugInfoAtRoundEnd) { Debug.Log((object)"logging all debug info for this round, get ready for log spam!"); LogDebugInfoAtRoundEnd = false; for (uint num = 1u; num < LocalDebugInfo.Count + 1; num++) { Debug.Log((object)$"debug data on tick {num} is {LocalDebugInfo[num]}"); } Debug.Log((object)"Log Spam Complete!"); } LocalDebugInfo.Clear(); RemoveDesyncWarning(); } } public struct Checksum { public ulong checksum; public uint tick; public int level; } public static EntwinedPacketChannel<Checksum> ChecksumsChannel; public static Dictionary<uint, ulong> LocalChecksums = new Dictionary<uint, ulong>(); public static Dictionary<uint, string> LocalDebugInfo = new Dictionary<uint, string>(); public static List<FixTransform> FixTransforms = new List<FixTransform>(); public static ConcurrentQueue<Checksum> checksumPacketQueue = new ConcurrentQueue<Checksum>(); public static List<Checksum> receivedCheckSumPackets = new List<Checksum>(); public static bool LogDebugInfoAtRoundEnd = false; public static Canvas canvas; public static GameObject textObj; public static TextMeshProUGUI textComp; public static RectTransform location; public static string currentScene; private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin DesinkDetecterMapMaker is loaded!"); Harmony val = new Harmony("com.David_Loves_JellyCar_Worlds.DesinkDetecterMapMaker"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"harmany created"); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"DesinkDetecterMapMaker Patch Compleate!"); GenericEntwiner<Checksum> val2 = new GenericEntwiner<Checksum>((Func<Checksum, byte[]>)ChecksumToBytes, (Func<byte[], Checksum>)BytesToChecksum); ChecksumsChannel = new EntwinedPacketChannel<Checksum>((BaseUnityPlugin)(object)this, (IEntwiner<Checksum>)(object)val2); ChecksumsChannel.OnMessage += OnChecksum; } private void Start() { SteamManager.instance.checkForDesyncs = true; } private void Update() { //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) while (!checksumPacketQueue.IsEmpty) { if (checksumPacketQueue.TryDequeue(out var result)) { if (result.level == Plugin.CurrentLevelIdForInputsOnlineThingy) { receivedCheckSumPackets.Add(result); } else { Debug.Log((object)$"receved a checksum from a difrent level. my level is {Plugin.CurrentLevelIdForInputsOnlineThingy} and the packets level is {result.level}"); } } else { Debug.Log((object)"failed to dequeue checksum packet for some reson"); } } List<Checksum> list = new List<Checksum>(); foreach (Checksum receivedCheckSumPacket in receivedCheckSumPackets) { list.Add(receivedCheckSumPacket); } int num = 0; foreach (Checksum receivedCheckSumPacket2 in receivedCheckSumPackets) { if (Plugin.CurrentLevelIdForInputsOnlineThingy == receivedCheckSumPacket2.level && LocalChecksums.ContainsKey(receivedCheckSumPacket2.tick)) { if (LocalChecksums[receivedCheckSumPacket2.tick] == receivedCheckSumPacket2.checksum) { LocalChecksums.Remove(receivedCheckSumPacket2.tick); list.Remove(receivedCheckSumPacket2); break; } Debug.Log((object)$"desink happend on frame {receivedCheckSumPacket2.tick} and the outer players checksum was {receivedCheckSumPacket2.checksum} my checksum was {LocalChecksums[receivedCheckSumPacket2.tick]} my level was {Plugin.CurrentLevelIdForInputsOnlineThingy} and the packets level is {receivedCheckSumPacket2.level}"); LogDebugInfoAtRoundEnd = true; Debug.Log((object)"we will log all the debug info after the round ends"); if ((Object)(object)textObj == (Object)null) { SpawnDesyncWarning(); } LocalChecksums.Remove(receivedCheckSumPacket2.tick); list.Remove(receivedCheckSumPacket2); throw new Exception("DESINK DETECTED!!!!!!!!! AHHHHHH!!!!!!!!!!"); } if (Plugin.CurrentLevelIdForInputsOnlineThingy != receivedCheckSumPacket2.level) { Debug.Log((object)$"receved a checksum from a difrent level. my level is {Plugin.CurrentLevelIdForInputsOnlineThingy} and the packets level is {receivedCheckSumPacket2.level}"); LocalChecksums.Remove(receivedCheckSumPacket2.tick); list.Remove(receivedCheckSumPacket2); } num++; } receivedCheckSumPackets = list; string text = currentScene; Scene activeScene = SceneManager.GetActiveScene(); if (!(text != ((Scene)(ref activeScene)).name)) { return; } activeScene = SceneManager.GetActiveScene(); currentScene = ((Scene)(ref activeScene)).name; if (!(currentScene == "MainMenu")) { return; } if (LogDebugInfoAtRoundEnd) { Debug.Log((object)"logging all debug info for this round, get ready for log spam!"); LogDebugInfoAtRoundEnd = false; for (uint num2 = 1u; num2 < LocalDebugInfo.Count + 1; num2++) { Debug.Log((object)$"debug data on tick {num2} is {LocalDebugInfo[num2]}"); } Debug.Log((object)"Log Spam Complete!"); } LocalDebugInfo.Clear(); RemoveDesyncWarning(); } public byte[] ChecksumToBytes(Checksum checksum) { uint tick = checksum.tick; byte[] array = new byte[16]; int num = 0; ulong checksum2 = checksum.checksum; int level = checksum.level; uint num2 = (uint)((ulong)level - 18446744071562067968uL); num2 = NetworkTools.SwapBytesIfLittleEndian(num2); byte[] bytes = BitConverter.GetBytes(num2); array[num++] = bytes[0]; array[num++] = bytes[1]; array[num++] = bytes[2]; array[num++] = bytes[3]; tick = NetworkTools.SwapBytesIfLittleEndian(tick); byte[] bytes2 = BitConverter.GetBytes(tick); array[num++] = bytes2[0]; array[num++] = bytes2[1]; array[num++] = bytes2[2]; array[num++] = bytes2[3]; checksum2 = NetworkTools.SwapBytesIfLittleEndian(checksum2); bytes2 = BitConverter.GetBytes(checksum2); array[num++] = bytes2[0]; array[num++] = bytes2[1]; array[num++] = bytes2[2]; array[num++] = bytes2[3]; array[num++] = bytes2[4]; array[num++] = bytes2[5]; array[num++] = bytes2[6]; array[num++] = bytes2[7]; return array; } public Checksum BytesToChecksum(byte[] bytes) { Checksum result = default(Checksum); byte[] array = new byte[4]; byte[] array2 = new byte[8]; int num = 0; array[0] = bytes[num++]; array[1] = bytes[num++]; array[2] = bytes[num++]; array[3] = bytes[num++]; uint num2 = BitConverter.ToUInt32(array, 0); num2 = NetworkTools.SwapBytesIfLittleEndian(num2); result.level = (int)(num2 + int.MinValue); array[0] = bytes[num++]; array[1] = bytes[num++]; array[2] = bytes[num++]; array[3] = bytes[num++]; result.tick = BitConverter.ToUInt32(array, 0); result.tick = NetworkTools.SwapBytesIfLittleEndian(result.tick); array2[0] = bytes[num++]; array2[1] = bytes[num++]; array2[2] = bytes[num++]; array2[3] = bytes[num++]; array2[4] = bytes[num++]; array2[5] = bytes[num++]; array2[6] = bytes[num++]; array2[7] = bytes[num++]; result.checksum = BitConverter.ToUInt64(array2, 0); result.checksum = NetworkTools.SwapBytesIfLittleEndian(result.checksum); return result; } public static ulong CalculateChecksum() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) Fix val = Fix.Zero; List<FixTransform> list = new List<FixTransform>(); foreach (FixTransform fixTransform in FixTransforms) { if (!((Object)(object)fixTransform == (Object)null)) { list.Add(fixTransform); } } FixTransforms = list; for (int i = 0; i < FixTransforms.Count; i++) { if (!FixTransforms[i].IsDestroyed) { val = Fix.SlowAdd(val, FixTransforms[i].ComputeCheckSum()); } } return (ulong)val.m_rawValue; } public static string SerializeState() { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) FixTransform[] array = FixTransforms.ToArray(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("----------------"); for (int i = 0; i < array.Length; i++) { if (array[i].IsDestroyed) { continue; } MonoUpdatable[] components = ((Component)array[i]).GetComponents<MonoUpdatable>(); if (components != null) { stringBuilder.Append(((Object)((Component)array[i]).gameObject).name + " hierarchyNumbers = "); for (int j = 0; j < components.Length; j++) { if (components[j].IsDestroyed) { stringBuilder.Append("[DESTROYED]"); } stringBuilder.Append(components[j].HierarchyNumber); stringBuilder.Append(", "); } } else { stringBuilder.Append(((Object)((Component)array[i]).gameObject).name); } stringBuilder.Append("\n"); stringBuilder.Append("posX = "); stringBuilder.Append(array[i].position.x); stringBuilder.Append(", posY = "); stringBuilder.Append(array[i].position.y); stringBuilder.Append(", rotation = "); stringBuilder.Append(array[i].rotation); stringBuilder.AppendLine("----------------"); } return stringBuilder.ToString(); } public void OnChecksum(Checksum checksumPacket, PacketSourceInfo sourceInfo) { checksumPacketQueue.Enqueue(checksumPacket); } public static void SpawnDesyncWarning() { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)textObj == (Object)null)) { return; } if ((Object)(object)canvas == (Object)null) { GameObject val = GameObject.Find("AbilitySelectCanvas"); if ((Object)(object)val != (Object)null) { canvas = val.GetComponent<Canvas>(); } if ((Object)(object)canvas == (Object)null) { Debug.LogError((object)$"No suitable canvas! Canvas: {canvas}, Scene: {currentScene}"); return; } } textObj = new GameObject("Desync warning", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); textObj.transform.SetParent(((Component)canvas).transform); textComp = textObj.GetComponent<TextMeshProUGUI>(); ((Graphic)textComp).raycastTarget = false; ((Graphic)textComp).color = Color.red; ((TMP_Text)textComp).fontSize = 25f; ((TMP_Text)textComp).alignment = (TextAlignmentOptions)514; ((TMP_Text)textComp).font = LocalizedText.localizationTable.GetFont(Settings.Get().Language, false); location = textObj.GetComponent<RectTransform>(); location.pivot = new Vector2(0f, 1f); location.anchoredPosition = new Vector2(-250f, 650f); location.sizeDelta = new Vector2(400f, 50f); textObj.SetActive(true); ((TMP_Text)textComp).text = "Desync Detected! winner will not count this round, game may frezze for a second when going to the next round due to log spamming."; } public static void RemoveDesyncWarning() { if ((Object)(object)textObj != (Object)null) { Object.Destroy((Object)(object)textObj); } } } }