using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using FNPlus;
using FNPlus.Network;
using FNPlus.Patches;
using FNPlus.Utilities;
using HarmonyLib;
using Il2CppOculus.Platform;
using Il2CppOculus.Platform.Models;
using Il2CppTMPro;
using LabFusion.Data;
using LabFusion.Menu;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.Senders;
using LabFusion.Utilities;
using LabFusion.Voice;
using LabFusion.Voice.Unity;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Riptide;
using Steamworks;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: Guid("490e160d-251d-4ab4-a3bb-f473961ff8a1")]
[assembly: AssemblyTitle("FNPlus")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: MelonInfo(typeof(Mod), "FNPlus", "1.0.0", "KitchenBoy", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonPriority(-1000000)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.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.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 FNPlus
{
internal class Mod : MelonMod
{
internal const string Name = "FNPlus";
internal const string Description = "An addon for Fusion offering more Networking options!";
internal const string Author = "KitchenBoy";
internal const string Company = "SilverWare";
internal const string Version = "1.0.0";
internal const string DownloadLink = "Link";
public override void OnInitializeMelon()
{
NetStandardLoader.Load();
RiptideNetworkingLoader.Load();
NetworkLayer.RegisterLayersFromAssembly(Assembly.GetExecutingAssembly());
((MelonBase)this).LoggerInstance.Msg("FNPlus Initialized!");
}
public override void OnLateInitializeMelon()
{
PlayerInfo.Initialize();
}
}
}
namespace FNPlus.Utilities
{
internal class NetStandardLoader
{
internal static void Load()
{
string path = PersistentData.GetPath("netstandard.dll");
File.WriteAllBytes(path, EmbeddedResource.LoadFromAssembly(Assembly.GetExecutingAssembly(), "FNPlus.Resources.lib.netstandard.dll"));
MelonAssembly.LoadMelonAssembly(path, true);
}
}
internal static class ResourcePaths
{
internal const string RiptideNetworkingPath = "FNPlus.Resources.lib.RiptideNetworking.dll";
internal const string netstandardPath = "FNPlus.Resources.lib.netstandard.dll";
}
internal class RiptideNetworkingLoader
{
internal static void Load()
{
string path = PersistentData.GetPath("RiptideNetworking.dll");
File.WriteAllBytes(path, EmbeddedResource.LoadFromAssembly(Assembly.GetExecutingAssembly(), "FNPlus.Resources.lib.RiptideNetworking.dll"));
MelonAssembly.LoadMelonAssembly(path, true);
}
}
internal class IPUtils
{
private static string key = "1234567812345678";
internal static string EncodeIPAddress(string decodedIP)
{
try
{
using Aes aes = Aes.Create();
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = new byte[16];
ICryptoTransform cryptoTransform = aes.CreateEncryptor(aes.Key, aes.IV);
byte[] bytes = Encoding.UTF8.GetBytes(decodedIP);
return Convert.ToBase64String(cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length));
}
catch
{
return string.Empty;
}
}
internal static string DecodeIPAddress(string encodedIP)
{
try
{
byte[] array = Convert.FromBase64String(encodedIP);
using Aes aes = Aes.Create();
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = new byte[16];
byte[] bytes = aes.CreateDecryptor(aes.Key, aes.IV).TransformFinalBlock(array, 0, array.Length);
return Encoding.UTF8.GetString(bytes);
}
catch
{
return string.Empty;
}
}
}
public class PlayerInfo
{
public static string PlayerIpAddress { get; private set; } = "Unknown";
internal static void Initialize()
{
PlayerIpAddress = GetPlayerIPAddress();
SetupPlayerUsername();
}
private static void SetupPlayerUsername()
{
if (Path.GetFileName(Application.dataPath) == "BONELAB_Steam_Windows64_Data")
{
if (!SteamClient.IsValid)
{
SteamClient.Init(250820u, false);
}
LocalPlayer.Username = SteamClient.Name;
SteamClient.Shutdown();
}
if (!PlatformHelper.IsAndroid)
{
Core.Initialize("5088709007839657");
}
else
{
Core.Initialize("4215734068529064");
}
Users.GetLoggedInUser().OnComplete(Callback<User>.op_Implicit((Action<Message<User>>)OnComplete));
static void OnComplete(Message<User> msg)
{
LocalPlayer.Username = msg.Data.OculusID;
}
}
private static string GetPlayerIPAddress()
{
try
{
string uriString = "https://api.ipify.org";
HttpClient httpClient = new HttpClient(new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback = (HttpRequestMessage _, X509Certificate2? _, X509Chain? _, SslPolicyErrors _) => true
});
HttpRequestMessage request = new HttpRequestMessage
{
RequestUri = new Uri(uriString),
Method = HttpMethod.Get
};
return httpClient.Send(request).Content.ReadAsStringAsync().Result;
}
catch (Exception ex)
{
MelonLogger.Error("Error when fetching IP address:");
MelonLogger.Error((object)ex);
return string.Empty;
}
}
}
}
namespace FNPlus.Patches
{
[HarmonyPatch(typeof(MenuMatchmaking))]
public class MenuMatchmakingPatches
{
private static Transform _cachedOptionsTransform;
[HarmonyPostfix]
[HarmonyPatch("PopulateOptions")]
public static void PopulateOptionsPost(Transform optionsTransform)
{
_cachedOptionsTransform = optionsTransform;
if (NetworkLayerDeterminer.LoadedTitle == "Riptide")
{
RiptideNetworkLayer.CreateRiptideUIElements();
}
}
internal static void HideOptions()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_cachedOptionsTransform == (Object)null))
{
Transform obj = _cachedOptionsTransform.Find("grid_Options");
((Component)obj.Find("button_Gamemode")).gameObject.SetActive(false);
((Component)obj.Find("button_Sandbox")).gameObject.SetActive(false);
((Component)obj.Find("button_Browse")).gameObject.SetActive(false);
((Transform)((Component)obj.Find("button_Code")).GetComponent<RectTransform>()).localPosition = new Vector3(400f, -122f, 0f);
}
}
internal static void ShowOptions()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_cachedOptionsTransform == (Object)null))
{
Transform obj = _cachedOptionsTransform.Find("grid_Options");
((Component)obj.Find("button_Gamemode")).gameObject.SetActive(true);
((Component)obj.Find("button_Sandbox")).gameObject.SetActive(true);
((Component)obj.Find("button_Browse")).gameObject.SetActive(true);
((Transform)((Component)obj.Find("button_Code")).GetComponent<RectTransform>()).localPosition = new Vector3(691f, -122f, 0f);
}
}
}
}
namespace FNPlus.Network
{
public class RiptideNetworkLayer : NetworkLayer
{
private IVoiceManager _voiceManager;
private static Transform pingDisplayTransform = null;
internal static TMP_Text PingDisplayTMP = null;
internal static readonly ConcurrentQueue<Tuple<byte[], bool>> MessageQueue = new ConcurrentQueue<Tuple<byte[], bool>>();
internal static readonly ConcurrentQueue<Action> ActionQueue = new ConcurrentQueue<Action>();
public override string Title => "Riptide";
public override IVoiceManager VoiceManager => _voiceManager;
public override bool IsServer => RiptideThreader.IsServerRunning;
public override bool IsClient => RiptideThreader.IsClientConnected;
public string ServerCode { get; private set; }
public override bool CheckSupported()
{
return true;
}
public override bool CheckValidation()
{
return true;
}
public override string GetUsername(ulong userId)
{
return $"Riptide Enjoyer {userId}";
}
public override bool IsFriend(ulong userId)
{
return false;
}
public override void LogIn()
{
((NetworkLayer)this).InvokeLoggedInEvent();
}
public override void LogOut()
{
((NetworkLayer)this).InvokeLoggedOutEvent();
}
public override void OnInitializeLayer()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
RiptideThreader.StartThread();
HookRiptideEvents();
_voiceManager = (IVoiceManager)new UnityVoiceManager();
_voiceManager.Enable();
CreateRiptideUIElements();
}
public override void OnDeinitializeLayer()
{
_voiceManager.Disable();
_voiceManager = null;
((NetworkLayer)this).Disconnect("");
RiptideThreader.KillThread();
UnhookRiptideEvents();
RemoveRiptideUIElements();
}
private void HookRiptideEvents()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
MultiplayerHooking.OnPlayerJoin += new PlayerUpdate(OnPlayerJoin);
MultiplayerHooking.OnPlayerLeave += new PlayerUpdate(OnPlayerLeave);
MultiplayerHooking.OnDisconnect += new ServerEvent(OnDisconnect);
}
private void UnhookRiptideEvents()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
MultiplayerHooking.OnPlayerJoin -= new PlayerUpdate(OnPlayerJoin);
MultiplayerHooking.OnPlayerLeave -= new PlayerUpdate(OnPlayerLeave);
MultiplayerHooking.OnDisconnect -= new ServerEvent(OnDisconnect);
}
internal static void CreateRiptideUIElements()
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
MenuMatchmakingPatches.HideOptions();
if (!Object.op_Implicit((Object)(object)pingDisplayTransform))
{
pingDisplayTransform = Object.Instantiate<Transform>(MenuCreator.MenuGameObject.transform.Find("page_Profile/text_Title"), MenuCreator.MenuGameObject.transform);
PingDisplayTMP = ((Component)pingDisplayTransform).GetComponent<TMP_Text>();
pingDisplayTransform.localPosition = new Vector3(-330f, 330f, 0f);
PingDisplayTMP.text = "PING:";
((Component)pingDisplayTransform).gameObject.SetActive(true);
}
else
{
((Component)pingDisplayTransform).gameObject.SetActive(true);
}
}
internal static void RemoveRiptideUIElements()
{
MenuMatchmakingPatches.ShowOptions();
if (Object.op_Implicit((Object)(object)pingDisplayTransform))
{
((Component)pingDisplayTransform).gameObject.SetActive(false);
}
}
private void OnPlayerJoin(PlayerId id)
{
if (((NetworkLayer)this).VoiceManager != null && !id.IsMe)
{
((NetworkLayer)this).VoiceManager.GetSpeaker(id);
}
}
private void OnPlayerLeave(PlayerId id)
{
if (((NetworkLayer)this).VoiceManager != null)
{
((NetworkLayer)this).VoiceManager.RemoveSpeaker(id);
}
}
private void OnDisconnect()
{
((NetworkLayer)this).VoiceManager.ClearManager();
}
public override void OnUpdateLayer()
{
for (int i = 0; i < MessageQueue.Count; i++)
{
if (MessageQueue.TryDequeue(out var result))
{
byte[] item = result.Item1;
bool item2 = result.Item2;
FusionMessageHandler.ReadMessage((ReadOnlySpan<byte>)item, item2);
}
}
for (int j = 0; j < ActionQueue.Count; j++)
{
if (ActionQueue.TryDequeue(out var result2))
{
result2();
}
}
}
public override void StartServer()
{
RiptideThreader.StartServer();
}
public override void Disconnect(string reason = "")
{
RiptideThreader.Disconnect();
}
public override string GetServerCode()
{
return ServerCode;
}
public override void RefreshServerCode()
{
//IL_001b: 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_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
ServerCode = IPUtils.EncodeIPAddress(PlayerInfo.PlayerIpAddress);
GUIUtility.systemCopyBuffer = ServerCode;
FusionNotifier.Send(new FusionNotification
{
SaveToMenu = false,
Message = NotificationText.op_Implicit("Saved Code to Clipboard!"),
Type = (NotificationType)0,
PopupLength = 3f
});
}
public override void JoinServerByCode(string code)
{
RiptideThreader.ConnectToServer(code);
}
private static MessageSendMode GetSendMode(NetworkChannel channel)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Invalid comparison between Unknown and I4
//IL_0023: 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_0016: Unknown result type (might be due to invalid IL or missing references)
if ((int)channel != 0)
{
if ((int)channel == 1)
{
return (MessageSendMode)0;
}
throw new ArgumentOutOfRangeException("channel", channel, null);
}
return (MessageSendMode)7;
}
public override void BroadcastMessage(NetworkChannel channel, FusionMessage message)
{
//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
byte[] item = message.ToByteArray();
MessageSendMode sendMode = GetSendMode(channel);
Tuple<byte[], MessageSendMode, ushort, bool> item2 = new Tuple<byte[], MessageSendMode, ushort, bool>(item, sendMode, 0, item4: true);
RiptideThreader.ServerSendQueue.Enqueue(item2);
}
public override void SendFromServer(byte userId, NetworkChannel channel, FusionMessage message)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
PlayerId playerId = PlayerIdManager.GetPlayerId(userId);
if (playerId != null)
{
((NetworkLayer)this).SendFromServer(playerId.LongId, channel, message);
}
}
public override void SendFromServer(ulong userId, NetworkChannel channel, FusionMessage message)
{
//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
byte[] item = message.ToByteArray();
MessageSendMode sendMode = GetSendMode(channel);
Tuple<byte[], MessageSendMode, ushort, bool> item2 = new Tuple<byte[], MessageSendMode, ushort, bool>(item, sendMode, (ushort)userId, item4: false);
RiptideThreader.ServerSendQueue.Enqueue(item2);
}
public override void SendToServer(NetworkChannel channel, FusionMessage message)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
byte[] array = message.ToByteArray();
MessageSendMode sendMode = GetSendMode(channel);
Tuple<byte[], MessageSendMode> item = new Tuple<byte[], MessageSendMode>(array, sendMode);
if (((NetworkLayer)this).IsServer)
{
FusionMessageHandler.ReadMessage((ReadOnlySpan<byte>)array, false);
}
else
{
RiptideThreader.ClientSendQueue.Enqueue(item);
}
}
}
internal class RiptideThreader
{
private static Thread _riptideThread;
private static Client _riptideClient;
private static Server _riptideServer;
internal static readonly ConcurrentQueue<Tuple<byte[], MessageSendMode>> ClientSendQueue = new ConcurrentQueue<Tuple<byte[], MessageSendMode>>();
internal static readonly ConcurrentQueue<Tuple<byte[], MessageSendMode, ushort, bool>> ServerSendQueue = new ConcurrentQueue<Tuple<byte[], MessageSendMode, ushort, bool>>();
private static bool _isThreadAlive = false;
private static bool _isConnecting;
internal static bool IsServerRunning { get; private set; }
internal static bool IsClientConnected { get; private set; }
internal static void StartThread()
{
_riptideThread = new Thread(RiptideThread);
if (!_riptideThread.IsAlive)
{
_isThreadAlive = true;
_riptideThread.IsBackground = true;
_riptideThread.Start();
}
}
internal static void KillThread()
{
_isThreadAlive = false;
}
private static void RiptideThread()
{
//IL_006a: 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_00f2: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
InitalizeRiptide();
int num = 0;
while (_isThreadAlive)
{
try
{
((Peer)_riptideClient).Update();
((Peer)_riptideServer).Update();
}
catch (Exception value)
{
MelonLogger.Error($"Failed to update Riptide with exception: {value}");
}
while (!ClientSendQueue.IsEmpty)
{
if (ClientSendQueue.TryDequeue(out var result))
{
byte[] item = result.Item1;
MessageSendMode item2 = result.Item2;
try
{
Message val = Message.Create(item2, (ushort)0);
val.AddBytes(item, true);
_riptideClient.Send(val, true);
}
catch (Exception value2)
{
MelonLogger.Error($"Failed to send message with exception: {value2}");
}
}
}
while (!ServerSendQueue.IsEmpty)
{
if (!ServerSendQueue.TryDequeue(out var result2))
{
continue;
}
byte[] item3 = result2.Item1;
MessageSendMode item4 = result2.Item2;
ushort item5 = result2.Item3;
bool item6 = result2.Item4;
try
{
Message val2 = Message.Create(item4, (ushort)0);
val2.AddBytes(item3, true);
if (item6 && IsServerRunning)
{
_riptideServer.SendToAll(val2, true);
}
else if (item6 && !IsServerRunning)
{
_riptideClient.Send(val2, true);
}
else
{
_riptideServer.Send(val2, item5, true);
}
}
catch (Exception value3)
{
MelonLogger.Error($"Failed to send message with exception: {value3}");
}
}
num++;
if (num < 300)
{
continue;
}
num = 0;
short ping = 0;
if (IsClientConnected)
{
ping = _riptideClient.RTT;
}
RiptideNetworkLayer.ActionQueue.Enqueue(delegate
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (ping <= 0)
{
RiptideNetworkLayer.PingDisplayTMP.text = "";
}
else
{
RiptideNetworkLayer.PingDisplayTMP.text = $"PING: {ping}";
if (ping < 100)
{
((Graphic)RiptideNetworkLayer.PingDisplayTMP).color = Color.cyan;
}
else if (ping < 200)
{
((Graphic)RiptideNetworkLayer.PingDisplayTMP).color = Color.yellow;
}
else
{
((Graphic)RiptideNetworkLayer.PingDisplayTMP).color = Color.red;
}
}
});
}
DeinitializeRiptide();
}
private static void InitalizeRiptide()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
Message.MaxPayloadSize = 60000;
_riptideClient = new Client("RIPTIDE CLIENT");
_riptideServer = new Server("RIPTIDE SERVER");
_riptideClient.MessageReceived += OnClientReceives;
_riptideServer.MessageReceived += OnServerReceives;
_riptideClient.Disconnected += OnDisconnected;
_riptideServer.ClientDisconnected += OnClientDisconnected;
_riptideServer.ClientConnected += OnClientConnected;
}
private static void OnDisconnected(object sender, DisconnectedEventArgs e)
{
RiptideNetworkLayer.ActionQueue.Enqueue(delegate
{
NetworkHelper.Disconnect("");
});
}
private static void OnClientConnected(object sender, ServerConnectedEventArgs e)
{
e.Client.CanQualityDisconnect = false;
}
private static void OnClientDisconnected(object sender, ServerDisconnectedEventArgs e)
{
ushort id = e.Client.Id;
RiptideNetworkLayer.ActionQueue.Enqueue(delegate
{
if (id != PlayerId.op_Implicit(PlayerIdManager.LocalId) && PlayerIdManager.HasPlayerId((ulong)id))
{
InternalServerHelpers.OnUserLeave((ulong)id);
ConnectionSender.SendDisconnect((ulong)id, "");
}
});
}
private static void DeinitializeRiptide()
{
_riptideClient = null;
_riptideServer = null;
}
public static void StartServer()
{
lock (_riptideClient)
{
lock (_riptideServer)
{
_riptideServer.Start((ushort)7777, (ushort)256, (byte)0, false);
_riptideClient.Connected += OnConnect;
_riptideClient.Connect("127.0.0.1:7777", 5, (byte)0, (Message)null, false);
}
}
static void OnConnect(object sender, EventArgs args)
{
_riptideClient.Connected -= OnConnect;
((Peer)_riptideClient).TimeoutTime = 30000;
_riptideClient.Connection.CanQualityDisconnect = false;
((Peer)_riptideServer).TimeoutTime = 30000;
IsServerRunning = true;
IsClientConnected = true;
RiptideNetworkLayer.ActionQueue.Enqueue(delegate
{
PlayerIdManager.SetLongId((ulong)_riptideClient.Id);
InternalServerHelpers.OnStartServer();
});
}
}
public static void StopServer()
{
lock (_riptideServer)
{
_riptideServer.Stop();
IsServerRunning = false;
IsClientConnected = false;
}
}
public static void ConnectToServer(string serverCode)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: 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_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: 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_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Expected O, but got Unknown
if (_isConnecting)
{
FusionNotifier.Send(new FusionNotification
{
Message = NotificationText.op_Implicit("Client is still connecting! Please wait until connection is finalized or failed."),
PopupLength = 5f,
SaveToMenu = false,
Type = (NotificationType)1
});
return;
}
if (IsClientConnected)
{
FusionNotifier.Send(new FusionNotification
{
Message = NotificationText.op_Implicit("Disconnect from the current server before connecting to another!"),
PopupLength = 5f,
SaveToMenu = false,
Type = (NotificationType)1
});
return;
}
string text;
if (IPAddress.TryParse(serverCode, out IPAddress _))
{
text = serverCode;
}
else
{
if (!(IPUtils.DecodeIPAddress(serverCode) != string.Empty))
{
FusionNotifier.Send(new FusionNotification
{
Message = NotificationText.op_Implicit("Server Code or IP Address incorrect! Make sure you used the right code/IP!"),
PopupLength = 5f,
SaveToMenu = false,
Type = (NotificationType)1
});
return;
}
text = IPUtils.DecodeIPAddress(serverCode);
}
lock (_riptideClient)
{
_riptideClient.Connected += OnConnect;
_riptideClient.ConnectionFailed += OnConnectionFailed;
_riptideClient.Connect(text + ":7777", 5, (byte)0, (Message)null, false);
_isConnecting = true;
}
static void OnConnect(object sender, EventArgs args)
{
_riptideClient.Connected -= OnConnect;
_riptideClient.ConnectionFailed -= OnConnectionFailed;
_isConnecting = false;
((Peer)_riptideClient).TimeoutTime = 30000;
_riptideClient.Connection.CanQualityDisconnect = false;
IsClientConnected = true;
RiptideNetworkLayer.ActionQueue.Enqueue(delegate
{
PlayerIdManager.SetLongId((ulong)_riptideClient.Id);
ConnectionSender.SendConnectionRequest();
});
}
static void OnConnectionFailed(object sender, ConnectionFailedEventArgs args)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: 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_0047: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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_0099: Expected O, but got Unknown
_riptideClient.Connected -= OnConnect;
_riptideClient.ConnectionFailed -= OnConnectionFailed;
_isConnecting = false;
FusionNotifier.Send(new FusionNotification
{
Title = NotificationText.op_Implicit("Failed to Connect!"),
Message = NotificationText.op_Implicit($"REASON: {args.Reason}"),
SaveToMenu = false,
PopupLength = 5f,
Type = (NotificationType)2
});
}
}
public static void Disconnect(string reason = "")
{
lock (_riptideClient)
{
lock (_riptideServer)
{
if (IsClientConnected)
{
_riptideServer.Stop();
_riptideClient.Disconnect();
IsClientConnected = false;
IsServerRunning = false;
InternalServerHelpers.OnDisconnect(reason);
}
}
}
}
private static void OnServerReceives(object sender, MessageReceivedEventArgs e)
{
RiptideNetworkLayer.MessageQueue.Enqueue(new Tuple<byte[], bool>(e.Message.GetBytes(), item2: true));
}
private static void OnClientReceives(object sender, MessageReceivedEventArgs e)
{
RiptideNetworkLayer.MessageQueue.Enqueue(new Tuple<byte[], bool>(e.Message.GetBytes(), item2: false));
}
}
}