using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using CessilCellsCeaChells.CeaChore;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Steamworks;
using Unity.Netcode;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RequiresField(typeof(ConnectionPayload), "MMRestrictorVersions", typeof(string), true)]
[assembly: IgnoresAccessChecksTo("Cessil.Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("wwwDayDream.MultiplayerModRestrictor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.1.0")]
[assembly: AssemblyInformationalVersion("0.4.1+7fc36a207ff49bf5fe4e340872069220e173cf07")]
[assembly: AssemblyProduct("MultiplayerModRestrictor")]
[assembly: AssemblyTitle("wwwDayDream.MultiplayerModRestrictor")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.1.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.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 BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace MultiplayerModRestrictor
{
[Serializable]
public class ModData
{
public string ModGUID;
public string ModName;
public string ModVersion;
}
[AttributeUsage(AttributeTargets.Class)]
internal class MMReqVersion : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
internal class MMReqExist : Attribute
{
}
[MMReqVersion]
[MMReqExist]
[BepInPlugin("wwwDayDream.MultiplayerModRestrictor", "MultiplayerModRestrictor", "0.4.1")]
public class MultiplayerModRestrictor : BaseUnityPlugin
{
public static List<ModData> ModDatas = new List<ModData>();
public const string Id = "wwwDayDream.MultiplayerModRestrictor";
public static ManualLogSource? Logger { get; private set; }
public static Harmony Patcher { get; } = new Harmony("wwwDayDream.MultiplayerModRestrictor");
public static string Name => "MultiplayerModRestrictor";
public static string Version => "0.4.1";
public void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
Patcher.PatchAll();
int num;
Logger.LogDebug((object)string.Format("Successfully patched {0} method{1}.", num = Patcher.GetPatchedMethods().Count(), (num == 1) ? "" : "s"));
}
public void Start()
{
GatherModVersions();
}
private void OnDestroy()
{
GatherModVersions();
}
private void GatherModVersions()
{
if (ModDatas.Count > 0)
{
return;
}
ManualLogSource? logger = Logger;
if (logger != null)
{
logger.LogDebug((object)"Gathering Mod Restrictions...");
}
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
pluginInfo.Deconstruct(out var key, out var value);
string text = key;
PluginInfo val = value;
bool flag = ((object)val.Instance).GetType().CustomAttributes.Any((CustomAttributeData attr) => attr.AttributeType.Name == "MMReqVersion");
if (flag || ((object)val.Instance).GetType().CustomAttributes.Any((CustomAttributeData attr) => attr.AttributeType.Name == "MMReqExist"))
{
string name = val.Metadata.Name;
string modVersion = (flag ? val.Metadata.Version.ToString() : "*");
ManualLogSource? logger2 = Logger;
if (logger2 != null)
{
logger2.LogDebug((object)("Found mod that requires multiplayer restriction: [" + text + "] " + name));
}
ModDatas.Add(new ModData
{
ModGUID = text,
ModName = name,
ModVersion = modVersion
});
}
}
ManualLogSource? logger3 = Logger;
if (logger3 != null)
{
logger3.LogDebug((object)string.Format("Located {0} mod{1}: {2}", ModDatas.Count, (ModDatas.Count == 1) ? "" : "s", GetVersionText()));
}
}
public static string GetVersionText()
{
return JsonConvert.SerializeObject((object)ModDatas);
}
public static bool CompareModDatas(string modDataJson, out string error)
{
ModData[] source = ((!string.IsNullOrEmpty(modDataJson)) ? (JsonConvert.DeserializeObject<ModData[]>(modDataJson) ?? Array.Empty<ModData>()) : Array.Empty<ModData>());
bool result = true;
StringBuilder stringBuilder = new StringBuilder("Requires:\n");
foreach (ModData modData in ModDatas)
{
ModData modData2 = source.FirstOrDefault((ModData data) => modData.ModGUID == data.ModGUID);
bool flag = modData2?.ModVersion == modData.ModVersion;
if (!(modData2 != null && flag))
{
result = false;
stringBuilder.AppendLine((modData2 != null) ? ("Version Mismatch: " + modData.ModName + " v" + modData.ModVersion + " (v" + modData2.ModVersion + ")") : ("Missing Mod: " + modData.ModName + " v" + modData.ModVersion));
}
}
error = stringBuilder.ToString().TrimEnd('\n', '\r');
return result;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "wwwDayDream.MultiplayerModRestrictor";
public const string PLUGIN_NAME = "MultiplayerModRestrictor";
public const string PLUGIN_VERSION = "0.4.1";
}
}
namespace MultiplayerModRestrictor.Patches
{
[HarmonyPatch(typeof(LobbyBrowserLobbyPanel))]
public static class LobbyBrowserLobbyPanelPatch
{
[HarmonyPatch("OnPointerUp")]
[HarmonyPrefix]
public static bool PreventJoining(LobbyBrowserLobbyPanel __instance)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
string text = SteamMatchmaking.GetLobbyData(__instance.steamLobbyID, "mmrestrictor") ?? "";
ManualLogSource? logger = MultiplayerModRestrictor.Logger;
if (logger != null)
{
logger.LogDebug((object)text);
}
if (MultiplayerModRestrictor.CompareModDatas(text, out string error))
{
return true;
}
ManualLogSource? logger2 = MultiplayerModRestrictor.Logger;
if (logger2 != null)
{
logger2.LogDebug((object)("Skipping lobby: " + __instance.serverNameText.text + " because " + error));
}
MainMenuManager.Singleton.ShowUIGroup_FailedToJoinServer();
MainMenuManager.Singleton.reasonForServerDisconnectText.text = error;
return false;
}
}
[HarmonyPatch(typeof(LobbyBrowserManager))]
public static class LobbyBrowserManagerPatch
{
[HarmonyPatch("OnLobbyCreated")]
[HarmonyPostfix]
public static void AddLobbyData(LobbyBrowserManager __instance)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
SteamMatchmaking.SetLobbyData(new CSteamID(__instance.currentSteamLobbyID), "mmrestrictor", MultiplayerModRestrictor.GetVersionText());
}
}
[HarmonyPatch(typeof(RelayManager))]
public static class RelayManagerPatch
{
[HarmonyPatch("ApprovalCallback")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> InsertNewResponseCase(IEnumerable<CodeInstruction> codeInstructions)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Expected O, but got Unknown
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Expected O, but got Unknown
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Expected O, but got Unknown
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Expected O, but got Unknown
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(codeInstructions, (ILGenerator)null);
val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
{
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldarg_2), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldc_I4_0), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Stfld), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldarg_2), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldflda), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Initobj), (string)null)
}).ThrowIfInvalid("Failure to find patch location in RelayManager::ApprovalCallback!");
val.Insert((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldloc_1, (object)null),
new CodeInstruction(OpCodes.Ldarg_2, (object)null),
new CodeInstruction(OpCodes.Call, (object)typeof(RelayManagerPatch).GetMethod("CheckModVersions"))
});
return val.Instructions();
}
[HarmonyPatch("GetPayloadBytes")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> InsertNewFieldAssignment(IEnumerable<CodeInstruction> codeInstructions)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Expected O, but got Unknown
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(codeInstructions, (ILGenerator)null);
val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[3]
{
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Newobj), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Dup), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldsfld), (string)null)
}).ThrowIfInvalid("Failure to find patch location in RelayManager::GetPayloadBytes!");
val.Insert((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Call, (object)typeof(MultiplayerModRestrictor).GetMethod("GetVersionText")),
new CodeInstruction(OpCodes.Stfld, (object)typeof(ConnectionPayload).GetField("MMRestrictorVersions")),
new CodeInstruction(OpCodes.Dup, (object)null)
});
return val.Instructions();
}
public static void CheckModVersions(ConnectionPayload? connectionPayload, ConnectionApprovalResponse response)
{
string error;
if (connectionPayload == null)
{
ManualLogSource? logger = MultiplayerModRestrictor.Logger;
if (logger != null)
{
logger.LogWarning((object)"ConnectionPayload was null!");
}
}
else if (!MultiplayerModRestrictor.CompareModDatas(connectionPayload.MMRestrictorVersions, out error))
{
response.Reason = error;
response.Approved = false;
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}