using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Managers;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
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: AssemblyTitle("ZSocket2Fix")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZSocket2Fix")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("38BC09F8-9E36-47D6-994E-CB74C81FAF2B")]
[assembly: AssemblyFileVersion("1.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
namespace ZSocket2Fix;
internal class PatchServerBind
{
[HarmonyPatch(typeof(SteamManager))]
private class SteamManagerPatch
{
[HarmonyTranspiler]
[HarmonyPatch("Awake")]
private static IEnumerable<CodeInstruction> AwakeTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
if (!ZSocket2Fix.m_disableSteamSetting.Value && ZSocket2Fix.m_isDedicated && ZSocket2Fix.m_serverBindAddressIPv4 != 0)
{
return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ci.opcode.Equals(OpCodes.Call) && ci.operand.ToString().Contains("Init")), (string)null)
}).MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null)
}).SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(ZSocket2Fix), "m_serverBindAddressIPv4"))
.InstructionEnumeration();
}
return instructions;
}
}
[HarmonyPatch(typeof(ZSocket2))]
private class ZSocket2Patch
{
[HarmonyPrefix]
[HarmonyPatch("StartHost")]
private static bool StartHostPrefix(ref bool __result, ref ZSocket2 __instance, int port)
{
if (ZSocket2Fix.m_isDedicated && ZSocket2Fix.m_serverBindAddressIPv4 != 0)
{
try
{
if (__instance.m_listner != null)
{
__instance.m_listner.Stop();
__instance.m_listner = null;
}
__instance.m_listner = new TcpListener(ZSocket2Fix.m_serverBindIpAddress, port);
__instance.m_listner.Start();
__instance.m_listenPort = port;
__result = true;
}
catch
{
__result = false;
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ZSteamSocket))]
private class ZSteamSocketPatch
{
[HarmonyTranspiler]
[HarmonyPatch("StartHost")]
private static IEnumerable<CodeInstruction> StartHostTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
if (!ZSocket2Fix.m_disableSteamSetting.Value && ZSocket2Fix.m_isDedicated && ZSocket2Fix.m_serverBindAddressIPv4 != 0)
{
return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ci.opcode.Equals(OpCodes.Stfld) && ci.operand.ToString().Contains("m_port")), (string)null)
}).Advance(-2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(ZSocket2Fix), "m_serverBindAddressIPv4"))
})
.Advance(2)
.Set(OpCodes.Callvirt, (object)AccessTools.Method(typeof(SteamNetworkingIPAddr), "SetIPv4", (Type[])null, (Type[])null))
.InstructionEnumeration();
}
return instructions;
}
}
}
[BepInPlugin("com.crzi.ZSocket2Fix", "ZSocket2Fix", "1.0.2")]
internal class ZSocket2Fix : BaseUnityPlugin
{
[HarmonyPatch(typeof(ServerList))]
private class ServerListPatch
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static UnityAction <>9__0_0;
internal void <OnEnablePostfix>b__0_0()
{
m_connectUsingTCP = true;
FejdStartup.instance.OnJoinStart();
}
}
[HarmonyPostfix]
[HarmonyPatch("OnEnable")]
public static void OnEnablePostfix(ServerList __instance)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: 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_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Expected O, but got Unknown
if ((Object)(object)ZS2Button != (Object)null)
{
return;
}
if (GUIManager.Instance == null)
{
LOGGER.LogError((object)"GUIManager instance is null");
return;
}
m_connectUsingTCP = false;
Button joinGameButton = ServerList.instance.m_joinGameButton;
RectTransform component = ((Component)joinGameButton).GetComponent<RectTransform>();
Vector2 sizeDelta = component.sizeDelta;
component.sizeDelta = new Vector2(sizeDelta.x, sizeDelta.y * 0.55f);
Transform transform = ((Component)joinGameButton).transform;
transform.position += new Vector3(0f, 17f);
ZS2Button = Object.Instantiate<GameObject>(((Component)joinGameButton).gameObject, ((Component)joinGameButton).transform.parent);
ButtonClickedEvent onClick = ZS2Button.GetComponent<Button>().onClick;
object obj = <>c.<>9__0_0;
if (obj == null)
{
UnityAction val = delegate
{
m_connectUsingTCP = true;
FejdStartup.instance.OnJoinStart();
};
<>c.<>9__0_0 = val;
obj = (object)val;
}
((UnityEvent)onClick).AddListener((UnityAction)obj);
Transform transform2 = ZS2Button.transform;
float x = ((Transform)component).position.x;
float y = ((Transform)component).position.y;
Rect rect = component.rect;
transform2.position = Vector2.op_Implicit(new Vector2(x, y - ((Rect)(ref rect)).height));
ZS2Button.SetActive(true);
((Object)ZS2Button).name = "ZS2Button";
((TMP_Text)ZS2Button.GetComponentInChildren<TextMeshProUGUI>()).text = "Connect with TCP";
}
[HarmonyPostfix]
[HarmonyPatch("UpdateButtons")]
private static void UpdateButtonsPostfix(ref ServerList __instance)
{
int selectedServer = __instance.GetSelectedServer();
bool interactable = selectedServer >= 0;
((Selectable)ZS2Button.GetComponent<Button>()).interactable = interactable;
}
}
[HarmonyPatch(typeof(DLCMan))]
private class DLCManPatch
{
[HarmonyPrefix]
[HarmonyPatch("CheckDLCsSTEAM")]
private static bool CheckDLCsSTEAMPrefix(ref DLCMan __instance)
{
return !m_disableSteamSetting.Value;
}
}
[HarmonyPatch(typeof(FejdStartup))]
private class FejdStartupPatch
{
[HarmonyPrefix]
[HarmonyPatch("TransitionToMainScene")]
private static void TransitionToMainScenePrefix(ref FejdStartup __instance)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (ZNet.m_isServer || m_connectUsingTCP)
{
ZNet.m_onlineBackend = (OnlineBackendType)3;
}
}
[HarmonyPrefix]
[HarmonyPatch("InitializeSteam")]
private static bool InitializeSteamPrefix(ref bool __result)
{
if (m_disableSteamSetting.Value)
{
__result = true;
}
return !m_disableSteamSetting.Value;
}
[HarmonyPrefix]
[HarmonyPatch("AwakePlayFab")]
private static bool AwakePlayfabPrefix(ref bool __result)
{
if (m_disableSteamSetting.Value)
{
__result = true;
}
return !m_disableSteamSetting.Value;
}
}
[HarmonyPatch(typeof(FileHelpers))]
private class FileHelpersPatch
{
[HarmonyPrefix]
[HarmonyPatch("UpdateCloudEnabledStatus")]
private static bool UpdateCloudEnabledStatusPrefix()
{
return !m_disableSteamSetting.Value;
}
}
[HarmonyPatch(typeof(SteamManager))]
private class SteamManagerPatch
{
[HarmonyPrefix]
[HarmonyPatch("Initialize")]
private static bool InitializePrefix(ref bool __result)
{
if (m_disableSteamSetting.Value)
{
__result = true;
}
return !m_disableSteamSetting.Value;
}
[HarmonyPrefix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static bool InitializedPrefix(ref bool __result)
{
if (m_disableSteamSetting.Value)
{
__result = true;
}
return !m_disableSteamSetting.Value;
}
}
[HarmonyPatch(typeof(PrivilegeManager))]
private class PrivilegeManagerPatch
{
[HarmonyPrefix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static bool CanAccessOnlineMultiplayerPrefix(ref bool __result)
{
if (m_disableSteamSetting.Value)
{
__result = true;
}
return !m_disableSteamSetting.Value;
}
}
[HarmonyPatch(typeof(ZNet))]
private class ZNetPatch
{
[HarmonyTranspiler]
[HarmonyPatch("Awake")]
private static IEnumerable<CodeInstruction> AwakeTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Expected O, but got Unknown
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Expected O, but got Unknown
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
if (m_disableSteamSetting.Value)
{
val = val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ci.opcode.Equals(OpCodes.Call) && ci.operand.ToString().Contains("GetPersonaName")), (string)null)
});
val = ((!val.IsValid) ? val.Start() : val.SetAndAdvance(OpCodes.Ldstr, (object)"nosteam"));
val = val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)typeof(ZNet).GetField("m_openServer"), (string)null)
}).SetInstruction(new CodeInstruction(OpCodes.Ldc_I4_0, (object)null));
}
return val.End().Insert((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Call, Transpilers.EmitDelegate<Action>((Action)ZNetAwakePostfixDelegate).operand)
}).InstructionEnumeration();
}
[HarmonyTranspiler]
[HarmonyPatch("StopAll")]
private static IEnumerable<CodeInstruction> StopAllTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Expected O, but got Unknown
if (m_disableSteamSetting.Value)
{
return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)typeof(ZSteamMatchmaking).GetMethod("ReleaseSessionTicket"), (string)null)
}).Advance(-1).RemoveInstructions(4)
.InstructionEnumeration();
}
return instructions;
}
[HarmonyTranspiler]
[HarmonyPatch("SendPeerInfo")]
private static IEnumerable<CodeInstruction> SendPeerInfoTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
if (m_disableSteamSetting.Value)
{
return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)typeof(ZSteamMatchmaking).GetMethod("RequestSessionTicket"), (string)null)
}).Advance(-2).RemoveInstructions(3)
.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
new CodeInstruction(OpCodes.Newarr, (object)typeof(byte))
})
.InstructionEnumeration();
}
return instructions;
}
[HarmonyPrefix]
[HarmonyPatch("Start")]
private static void StartPrefix(ref ZNet __instance)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (ZNet.m_isServer || m_connectUsingTCP)
{
ZNet.m_onlineBackend = (OnlineBackendType)3;
}
}
[HarmonyPostfix]
[HarmonyPatch("Update")]
private static void UpdatePostfix(ref ZNet __instance)
{
if (!ZNet.m_isServer && m_connectUsingTCP)
{
__instance.UpdateClientConnector(Time.deltaTime);
}
}
}
[HarmonyPatch(typeof(ZSteamMatchmaking))]
private class ZSteamMatchmakingPatch
{
[HarmonyPrefix]
[HarmonyPatch("Initialize")]
private static bool InitializePrefix()
{
return !m_disableSteamSetting.Value;
}
}
public const string PluginGUID = "com.crzi.ZSocket2Fix";
public const string PluginName = "ZSocket2Fix";
public const string PluginVersion = "1.0.2";
private Harmony _harmony;
public static ConfigEntry<bool> m_disableSteamSetting;
public static ConfigEntry<string> m_serverBindAddressSetting;
public static uint m_serverBindAddressIPv4;
public static IPAddress m_serverBindIpAddress;
public static bool m_connectUsingTCP;
public static bool m_isDedicated;
public static GameObject ZS2Button;
public static ManualLogSource LOGGER;
private void Awake()
{
Game.isModded = true;
m_disableSteamSetting = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "DisableSteam", false, "Whether to disable steam integration");
m_serverBindAddressSetting = ((BaseUnityPlugin)this).Config.Bind<string>("Server", "ServerBindAddress", "0.0.0.0", "Custom address to bind server listen socket on");
LOGGER = ((BaseUnityPlugin)this).Logger;
string[] commandLineArgs = Environment.GetCommandLineArgs();
for (int i = 0; i < commandLineArgs.Length; i++)
{
string text = commandLineArgs[i].ToLower();
if (text == "-password")
{
m_isDedicated = true;
}
}
if (m_disableSteamSetting.Value && !m_isDedicated)
{
ZLog.LogWarning((object)"ZSocket2Fix disabling steam integration...");
}
if (m_isDedicated)
{
m_disableSteamSetting.Value = false;
m_serverBindIpAddress = IPAddress.Parse(m_serverBindAddressSetting.Value);
byte[] addressBytes = m_serverBindIpAddress.GetAddressBytes();
if (BitConverter.IsLittleEndian)
{
Array.Reverse((Array)addressBytes);
}
m_serverBindAddressIPv4 = BitConverter.ToUInt32(addressBytes, 0);
ZLog.LogWarning((object)"Bytes + ip converted:::");
ZLog.LogWarning((object)m_serverBindAddressSetting.Value);
ZLog.LogWarning((object)BitConverter.ToString(addressBytes));
ZLog.LogWarning((object)m_serverBindAddressIPv4);
}
_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.crzi.ZSocket2Fix");
ZLog.LogWarning((object)"Loaded ZSocket2Fix");
}
public static void dump_instructions(IEnumerable<CodeInstruction> instructions)
{
for (int i = 0; i < instructions.Count(); i++)
{
CodeInstruction val = instructions.ElementAt(i);
object operand = val.operand;
string text = operand?.GetType()?.ToString() ?? "";
MethodInfo methodInfo = operand as MethodInfo;
if (methodInfo != null)
{
text = text + ", " + methodInfo.Name + ", " + methodInfo.Module?.FullyQualifiedName;
}
string[] obj = new string[7]
{
i.ToString(),
": ",
null,
null,
null,
null,
null
};
OpCode opcode = val.opcode;
obj[2] = opcode.ToString();
obj[3] = " | ";
obj[4] = operand?.ToString();
obj[5] = " ||| ";
obj[6] = text;
ZLog.Log((object)string.Concat(obj));
}
}
private static void ZNetAwakePostfixDelegate()
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
ZNet instance = ZNet.instance;
if (ZNet.m_isServer)
{
if (instance.m_hostSocket != null)
{
ZLog.LogWarning((object)("Closing host socket: " + ((object)instance).GetType().Name));
instance.m_hostSocket.Close();
instance.m_hostSocket.Dispose();
}
ZSocket2 val = new ZSocket2();
val.StartHost(ZSteamSocket.m_steamDataPort);
instance.m_hostSocket = (ISocket)(object)val;
ZLog.LogWarning((object)"Started TCP Custom Socket");
}
}
}