using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using ChangeHostSlot.Patches;
using GTFO.API;
using GTFO.API.JSON;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Microsoft.CodeAnalysis;
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("ChangeHostSlot")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gitab71874-main")]
[assembly: AssemblyProduct("ChangeHostSlot")]
[assembly: AssemblyTitle("ChangeHostSlot")]
[assembly: TargetPlatform("Windows7.0")]
[assembly: SupportedOSPlatform("Windows7.0")]
[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 ChangeHostSlot
{
[BepInPlugin("JarheadHME.ChangeHostSlot", "ChangeHostSlot", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class EntryPoint : BasePlugin
{
public static readonly string[] SlotToDescriptor = new string[4] { "Pink/Woods", "Green/Dauda", "Blue/Hackett", "Purple/Bishop" };
private Harmony _Harmony = null;
private static readonly string CustomPlayerSlotsPath = Path.Join(Paths.ConfigPath, "ChangeHostSlotPlayers.json");
public override void Load()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
SlotConfig.CreateBind();
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Patching on slot ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(SlotConfig.Slot);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(SlotToDescriptor[SlotConfig.Slot]);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
}
Logger.Info(val);
_Harmony = new Harmony("ChangeHostSlot.Harmony");
try
{
_Harmony.PatchAll();
}
catch (HarmonyException)
{
}
if (_Harmony.GetPatchedMethods().Count() > 0)
{
Logger.Info("Harmony Patch succeeded, skipping detour");
}
else
{
Logger.Info("Harmony Patch failed, applying detour");
DetourPatch.ApplyNative();
}
Logger.Info("Loaded successfully");
ParsePlayerSlotsFile();
}
public static void ParsePlayerSlotsFile()
{
if (!File.Exists(CustomPlayerSlotsPath))
{
CreateDefaultCustomSlotsFile();
}
PlayerSlotsJSON[] array = JsonSerializer.Deserialize<PlayerSlotsJSON[]>(File.ReadAllText(CustomPlayerSlotsPath), (JsonSerializerOptions)null);
PlayerSlotsJSON[] array2 = array;
foreach (PlayerSlotsJSON playerSlotsJSON in array2)
{
if (playerSlotsJSON.PlayerID != 0)
{
DetourPatch.PlayerSlots.Add(playerSlotsJSON.PlayerID, playerSlotsJSON.Slot);
}
}
}
public static void CreateDefaultCustomSlotsFile()
{
Logger.Info("File doesn't exist, creating default");
string contents = JsonSerializer.Serialize((object)new PlayerSlotsJSON[1]
{
new PlayerSlotsJSON
{
PlayerName = "PlayerNameGoesHere",
PlayerID = 0uL,
Slot = 0
}
}, new JsonSerializerOptions(JsonSerializerDefaults.General)
{
WriteIndented = true
});
File.WriteAllText(CustomPlayerSlotsPath, contents);
}
}
internal class PlayerSlotsJSON
{
public string PlayerName { get; set; }
public ulong PlayerID { get; set; }
public int Slot { get; set; }
}
internal static class Logger
{
private static readonly ManualLogSource _Logger;
static Logger()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
_Logger = new ManualLogSource("ChangeHostSlot");
Logger.Sources.Add((ILogSource)(object)_Logger);
}
private static string Format(object msg)
{
return msg.ToString();
}
public static void Info(BepInExInfoLogInterpolatedStringHandler handler)
{
_Logger.LogInfo(handler);
}
public static void Info(string str)
{
_Logger.LogMessage((object)str);
}
public static void Info(object data)
{
_Logger.LogMessage((object)Format(data));
}
public static void Debug(BepInExDebugLogInterpolatedStringHandler handler)
{
_Logger.LogDebug(handler);
}
public static void Debug(string str)
{
_Logger.LogDebug((object)str);
}
public static void Debug(object data)
{
_Logger.LogDebug((object)Format(data));
}
public static void Error(BepInExErrorLogInterpolatedStringHandler handler)
{
_Logger.LogError(handler);
}
public static void Error(string str)
{
_Logger.LogError((object)str);
}
public static void Error(object data)
{
_Logger.LogError((object)Format(data));
}
public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler)
{
_Logger.LogFatal(handler);
}
public static void Fatal(string str)
{
_Logger.LogFatal((object)str);
}
public static void Fatal(object data)
{
_Logger.LogFatal((object)Format(data));
}
public static void Warn(BepInExWarningLogInterpolatedStringHandler handler)
{
_Logger.LogWarning(handler);
}
public static void Warn(string str)
{
_Logger.LogWarning((object)str);
}
public static void Warn(object data)
{
_Logger.LogWarning((object)Format(data));
}
[Conditional("DEBUG")]
public static void DebugOnly(object data)
{
_Logger.LogDebug((object)Format(data));
}
}
public static class SlotConfig
{
public static int Slot;
public static void CreateBind()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
BindSlot(new ConfigFile(Path.Combine(Paths.ConfigPath, "ChangeHostSlot.cfg"), true));
if (Slot < 0 || Slot > 3)
{
Logger.Error("Slot option not in valid range (0-3), defaulting to 0");
Slot = 0;
}
}
private static void BindSlot(ConfigFile config)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//IL_002f: Expected O, but got Unknown
string text = "ChangeHostSlot";
string text2 = "Slot";
int num = 0;
string text3 = "Slot to host in. 0 = Pink/Woods, 1 = Green/Dauda, 2 = Blue/Hackett, 3 = Purple/Bishop";
Slot = config.Bind<int>(new ConfigDefinition(text, text2), num, new ConfigDescription(text3, (AcceptableValueBase)null, Array.Empty<object>())).Value;
}
}
[GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")]
[CompilerGenerated]
internal static class VersionInfo
{
public const string RootNamespace = "ChangeHostSlot";
public const string Version = "1.0.0";
public const string VersionPrerelease = null;
public const string VersionMetadata = "gitab71874-main";
public const string SemVer = "1.0.0+gitab71874-main";
public const string GitRevShort = "ab71874";
public const string GitRevLong = "ab71874e00b2606f47e7f21a0c132e8fdd449d71";
public const string GitBranch = "main";
public const string GitTag = null;
public const int GitCommitsSinceTag = 0;
public const bool GitIsDirty = false;
}
}
namespace ChangeHostSlot.Patches
{
internal static class DetourPatch
{
private unsafe delegate bool d_Internal_ManageSlot(IntPtr _this, IntPtr player, IntPtr pSlot, IntPtr slots, SNet_SlotType type, SNet_SlotHandleType handle, int index, Il2CppMethodInfo* methodInfo);
private static INativeDetour Internal_ManageSlotDetour;
private static d_Internal_ManageSlot orig_Internal_ManageSlot;
public static Dictionary<ulong, int> PlayerSlots = new Dictionary<ulong, int>();
internal unsafe static void ApplyNative()
{
Internal_ManageSlotDetour = INativeDetour.CreateAndApply<d_Internal_ManageSlot>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<SNet_PlayerSlotManager>("Internal_ManageSlot", "System.Boolean", false, new string[6]
{
"SNet_Player",
"SNet_Slot",
typeof(SNet_Slot).FullName,
"SNet_SlotType",
"SNet_SlotHandleType",
"System.Int32"
}), (d_Internal_ManageSlot)Internal_ManageSlotPatch, ref orig_Internal_ManageSlot);
}
public unsafe static bool Internal_ManageSlotPatch(IntPtr _this_ptr, IntPtr player_ptr, IntPtr pSlot, IntPtr slots_ptr, SNet_SlotType type, SNet_SlotHandleType handle, int index, Il2CppMethodInfo* methodInfo)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: 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_0024: Unknown result type (might be due to invalid IL or missing references)
if (Internal_ManageSlot_InternalPatch(_this_ptr, player_ptr, pSlot, slots_ptr, type, handle, index, methodInfo))
{
return orig_Internal_ManageSlot(_this_ptr, player_ptr, pSlot, slots_ptr, type, handle, index, methodInfo);
}
return true;
}
public unsafe static bool Internal_ManageSlot_InternalPatch(IntPtr _this_ptr, IntPtr player_ptr, IntPtr pSlot, IntPtr slots_ptr, SNet_SlotType type, SNet_SlotHandleType handle, int index, Il2CppMethodInfo* methodInfo)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Expected O, but got Unknown
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Invalid comparison between Unknown and I4
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Expected O, but got Unknown
SNet_PlayerSlotManager val = new SNet_PlayerSlotManager(_this_ptr);
SNet_Player val2 = new SNet_Player(player_ptr);
Il2CppReferenceArray<SNet_Slot> val3 = new Il2CppReferenceArray<SNet_Slot>(slots_ptr);
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(25, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Slot managing player: ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(val2.NickName);
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" - ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<ulong>(val2.Lookup);
}
Logger.Info(val4);
if (SNet.IsMaster && (int)handle == 0 && (PlayerSlots.TryGetValue(val2.Lookup, out var value) || val2.IsLocal))
{
int num = (val2.IsLocal ? SlotConfig.Slot : value);
SNet_Slot val5 = ((Il2CppArrayBase<SNet_Slot>)(object)val3)[num];
if (!val.IsHumanPermittedInSlot(num) && !val2.IsLocal)
{
val4 = new BepInExInfoLogInterpolatedStringHandler(70, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Player ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(val2.NickName);
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("'s chosen slot (");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(EntryPoint.SlotToDescriptor[num]);
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(") doesn't allow humans, using normal assignment");
}
Logger.Info(val4);
return true;
}
if ((Object)(object)val5.player != (Object)null)
{
if (!val5.player.IsBot)
{
val4 = new BepInExInfoLogInterpolatedStringHandler(67, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Player ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(val2.NickName);
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("'s chosen slot (");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(EntryPoint.SlotToDescriptor[num]);
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(") occupied by human, using normal assignment");
}
Logger.Info(val4);
return true;
}
SNet.Sync.TryKickBot(val5.player);
}
val5.player = val2;
if ((int)type == 0)
{
val2.PlayerSlot = val5;
}
else
{
val2.CharacterSlot = val5;
}
if (!val.SlottedPlayers.Contains(val2))
{
val.SlottedPlayers.Add(val2);
}
return false;
}
return true;
}
}
[HarmonyPatch]
internal class HikariaCoreHarmonyPatch
{
private static MethodBase TargetMethod()
{
Type type = Type.GetType("Hikaria.Core.Features.Dev.GameEventListener, Hikaria.Core");
if (type == null)
{
throw new Exception("Could not find GameEventListener");
}
Type nestedType = type.GetNestedType("SNet_PlayerSlotManager__Internal_ManageSlot__NativeDetour", BindingFlags.NonPublic);
if (nestedType == null)
{
throw new Exception("Could not find Detour class");
}
MethodInfo method = nestedType.GetMethod("Detour", BindingFlags.Instance | BindingFlags.NonPublic);
if (method == null)
{
throw new Exception("Could not find Detour method");
}
return method;
}
private unsafe static bool Prefix(ref bool __result, IntPtr instancePtr, IntPtr playerPtr, IntPtr slotPtr, IntPtr slotsPtr, SNet_SlotType type, SNet_SlotHandleType handle, int index, Il2CppMethodInfo* methodInfo)
{
//IL_0009: 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)
__result = true;
return DetourPatch.Internal_ManageSlot_InternalPatch(instancePtr, playerPtr, slotPtr, slotsPtr, type, handle, index, methodInfo);
}
}
}