using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using Globals;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BypassGenerationChecksum")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BypassGenerationChecksum")]
[assembly: AssemblyTitle("BypassGenerationChecksum")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
}
}
}
namespace BypassGenerationChecksum
{
internal static class HostAllowMismatchingChecksums
{
[HarmonyPatch(typeof(SNet_SyncManager), "SessionCommand")]
[HarmonyPrefix]
private static void SNet_SyncManager__SessionCommand__Prefix(eSessionCommandType type)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Invalid comparison between Unknown and I4
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Invalid comparison between Unknown and I4
if (!SNet.IsMaster || (int)type != 1)
{
return;
}
Enumerator<SNet_Player> enumerator = SNet.Slots.PlayersSynchedWithGame.GetEnumerator();
while (enumerator.MoveNext())
{
SNet_Player current = enumerator.Current;
if (!current.IsBot && (int)current.Session.mode == 6)
{
CheckAndHandleGenerationChecksum(current);
}
}
}
[HarmonyPatch(typeof(SNet_SyncManager), "MasterReplicationUpdate_Player")]
[HarmonyPrefix]
private static void SNet_SyncManager__MasterReplicationUpdate_Player__Prefix(SNet_Player player)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Invalid comparison between Unknown and I4
if (SNet.IsMaster && (int)player.Session.mode == 12 && !player.IsMaster && !player.IsBot)
{
CheckAndHandleGenerationChecksum(player);
}
}
private static void CheckAndHandleGenerationChecksum(SNet_Player player)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Expected O, but got Unknown
if (SNet.IsMaster && !player.IsBot && player.Session.generationChecksum != SNet.LocalPlayer.Session.generationChecksum)
{
Utils.LogInfo($"Generation checksum mismatch... Client:{player.NickName}:{player.Session.generationChecksum} != (Me)Host:{SNet.LocalPlayer.NickName}:{SNet.LocalPlayer.Session.generationChecksum}");
Utils.LogInfo("Host action... Ignoring the mismatch.");
if (player.HasPlayerAgent)
{
PlayerChatManager.WantToSentTextMessage(new PlayerAgent(((Il2CppObjectBase)player.PlayerAgent).Pointer), "<color=#F10>Warning: Generation checksum mismatch!", (PlayerAgent)null);
}
pPlayerData_Session session = player.Session;
session.generationChecksum = SNet.LocalPlayer.Session.generationChecksum;
player.Session = session;
}
}
[HarmonyPatch(typeof(SNet_SyncManager), "KickPlayer")]
[HarmonyPrefix]
private static void SNet_SyncManager__KickPlayer__Prefix(ref bool __runOriginal, SNet_Player player, SNet_PlayerEventReason reason)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
if ((int)reason == 3)
{
Utils.LogError("Ignoring Kick_GenerationChecksum for " + player.NickName);
__runOriginal = false;
}
}
}
internal static class ClientSpoofChecksumToMatchHost
{
private enum eStatus
{
Inactive,
WaitingForMasterToFinishGenerating
}
private static eStatus status;
[HarmonyPatch(typeof(GS_Generating), "OnBuilderDone")]
[HarmonyPrefix]
private static void GS_Generating__OnBuilderDone__Prefix(ref bool __runOriginal)
{
if (!Global.UseStaticLevel)
{
__runOriginal = false;
ulong checksum = Builder.CombinedCheckSum.Checksum;
Debug.Log(Object.op_Implicit(">>>>>>>> GS_Generating.OnBuilderDone"));
Debug.Log(Object.op_Implicit("Builder.CombinedCheckSum.Checksum: " + checksum));
HandleGenerationChecksum(checksum);
}
}
private static void HandleGenerationChecksum(ulong generationChecksum)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Invalid comparison between Unknown and I4
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Invalid comparison between Unknown and I4
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
if (SNet.IsMaster)
{
SetGenerationChecksumAndSyncStatus(generationChecksum);
return;
}
if ((int)SNet.Master.Load<pGameState>().gameState == 6)
{
Utils.LogInfo("Client action... Waiting for master to finish generating.");
status = eStatus.WaitingForMasterToFinishGenerating;
return;
}
if (generationChecksum == SNet.Master.Session.generationChecksum)
{
SetGenerationChecksumAndSyncStatus(generationChecksum);
return;
}
Utils.LogInfo($"Generation checksum mismatch... (Me)Client:{SNet.LocalPlayer.NickName}:{generationChecksum} != Host:{SNet.Master.NickName}:{SNet.Master.Session.generationChecksum}");
Utils.LogInfo("Client action... Master has finished generating. Spoofing generationChecksum.");
Utils.SendChatMessage("<color=#F10>Warning: Generation checksum mismatch!");
if ((int)SNet.Master.Load<pGameState>().gameState == 10)
{
PlayerChatManager.PostChatMessageLocaly(SNet.LocalPlayer, "<color=#F10>Warning: Generation checksum mismatch!", (SNet_Player)null);
}
SetGenerationChecksumAndSyncStatus(SNet.Master.Session.generationChecksum);
status = eStatus.Inactive;
}
[HarmonyPatch(typeof(GameStateManager), "OnPlayerGameStateChange")]
[HarmonyPostfix]
private static void GameStateManager__OnPlayerGameStateChange__Postfix(SNet_Player player, pGameState data)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
if (status == eStatus.WaitingForMasterToFinishGenerating && player.IsMaster && (int)data.gameState == 7)
{
HandleGenerationChecksum(Builder.CombinedCheckSum.Checksum);
}
}
private static void SetGenerationChecksumAndSyncStatus(ulong generationChecksum)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
pPlayerData_Session session = SNet.LocalPlayer.Session;
session.generationChecksum = generationChecksum;
SNet.LocalPlayer.Session = session;
SNet.Sync.SendPlayerData_Session(SNet.LocalPlayer);
SNet.Sync.SessionCommand((eSessionCommandType)5, 0);
GameStateManager.ChangeState((eGameStateName)7);
}
[HarmonyPatch(typeof(GameStateManager), "ChangeState")]
[HarmonyPostfix]
private static void GameStateManager__ChangeState__Postfix(eGameStateName nextState)
{
status = eStatus.Inactive;
}
}
internal static class GeneralPatches
{
[HarmonyPatch(typeof(SNet_SessionHub), "KickPlayer")]
[HarmonyPostfix]
private static void SNet_SessionHub__KickPlayer__Postfix(SNet_Player player, SNet_PlayerEventReason reason)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
if ((int)reason == 3)
{
Utils.SendLocalMessage("<color=#F10>The host kicked " + PlayerNameExtentions.GetColoredName(player, (string)null) + "!");
Utils.SendLocalMessage("<color=#F10>Please ensure the host is running BypassGenerationChecksum.");
}
}
}
internal static class Utils
{
private static ManualLogSource logger = Logger.CreateLogSource("Andocas.BypassGenerationChecksum");
public static void LogInfo(string text)
{
logger.LogInfo((object)text);
}
public static void LogError(string text)
{
logger.LogError((object)text);
}
public static void LogGenerationChecksums(params SNet_Player[] players)
{
LogInfo(string.Join(", ", players.Select(DescriptiveString)));
static string DescriptiveString(SNet_Player player)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
string value = (player.IsMaster ? "Host" : "Client");
return $"{value}:{player.NickName}:{player.Session.generationChecksum}";
}
}
public static void SendChatMessage(string text, string prefix = "")
{
LogInfo("SendChatMessage: " + text);
int num = 50 - prefix.Length;
while (text.Length > num)
{
PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), prefix + text.Substring(0, num).Trim(), (PlayerAgent)null);
text = text.Substring(num).Trim();
}
PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), prefix + text, (PlayerAgent)null);
}
public static void SendLocalMessage(string text)
{
LogInfo("SendLocalMessage: " + text);
GuiManager.PlayerLayer.m_gameEventLog.AddLogItem(text, (eGameEventChatLogType)2);
CM_PageLoadout.Current.m_gameEventLog.AddLogItem(text, (eGameEventChatLogType)2);
}
}
internal static class PluginInfo
{
public const string GUID = "Andocas.BypassGenerationChecksum";
public const string NAME = "BypassGenerationChecksum";
public const string VERSION = "0.1.1";
}
[BepInPlugin("Andocas.BypassGenerationChecksum", "BypassGenerationChecksum", "0.1.1")]
internal class Plugin : BasePlugin
{
public override void Load()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
Utils.LogInfo("Andocas.BypassGenerationChecksum is loading...");
Harmony val = new Harmony("Andocas.BypassGenerationChecksum");
if (ConfigManager.hostAllowMismatchingChecksums.Value)
{
val.PatchAll(typeof(HostAllowMismatchingChecksums));
}
if (ConfigManager.clientEnableChecksumSpoofing.Value)
{
val.PatchAll(typeof(ClientSpoofChecksumToMatchHost));
}
val.PatchAll(typeof(GeneralPatches));
Utils.LogInfo("Andocas.BypassGenerationChecksum is loaded");
}
}
internal static class ConfigManager
{
public static readonly ConfigEntry<bool> hostAllowMismatchingChecksums;
public static readonly ConfigEntry<bool> clientEnableChecksumSpoofing;
static ConfigManager()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "Andocas.BypassGenerationChecksum.cfg"), true);
hostAllowMismatchingChecksums = val.Bind<bool>("Host", "Ignore mismatching checksums", true, "This host-only feature allows players with mismatching generation checksums to join your lobbies (instead of kicking them).");
clientEnableChecksumSpoofing = val.Bind<bool>("Client", "Enable checksum spoofing", true, "This client-side feature allows you to join hosts that don't have BypassGenerationChecksum installed by spoofing your generation checksum to match the host's.");
}
}
}