Decompiled source of R2API Networking v1.0.3

plugins/R2API.Networking/R2API.Networking.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using R2API.AutoVersionGen;
using R2API.Networking.Interfaces;
using R2API.Networking.Messages;
using R2API.Utils;
using RoR2;
using RoR2.Networking;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("R2API.Networking")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+618e5c79de15afc414a1027c35b944a0b92fe2e8")]
[assembly: AssemblyProduct("R2API.Networking")]
[assembly: AssemblyTitle("R2API.Networking")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: TypeForwardedTo(typeof(CompatibilityLevel))]
[assembly: TypeForwardedTo(typeof(NetworkCompatibility))]
[assembly: TypeForwardedTo(typeof(VersionStrictness))]
[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 System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace R2API.AutoVersionGen
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	internal class AutoVersionAttribute : Attribute
	{
	}
}
namespace R2API.Networking
{
	internal class Header : ISerializableObject
	{
		internal int TypeCode { get; private set; }

		internal NetworkDestination Destination { get; private set; }

		public Header()
		{
		}

		internal Header(int typeCode, NetworkDestination dest)
		{
			TypeCode = typeCode;
			Destination = dest;
		}

		internal void RemoveDestination(NetworkDestination destination)
		{
			Destination &= (NetworkDestination)(byte)(~(int)destination);
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(TypeCode);
			writer.Write((byte)Destination);
		}

		public void Deserialize(NetworkReader reader)
		{
			TypeCode = reader.ReadInt32();
			Destination = (NetworkDestination)reader.ReadByte();
		}
	}
	[Flags]
	public enum NetworkDestination : byte
	{
		Clients = 1,
		Server = 2
	}
	internal static class NetworkDestinationExtensions
	{
		internal static bool ShouldSend(this NetworkDestination dest)
		{
			if (NetworkServer.active)
			{
				return dest != NetworkDestination.Server;
			}
			return true;
		}

		internal static bool ShouldRun(this NetworkDestination dest)
		{
			bool active = NetworkServer.active;
			bool active2 = NetworkClient.active;
			if (!active || (dest & NetworkDestination.Server) == 0)
			{
				if (active2)
				{
					return (dest & NetworkDestination.Clients) != 0;
				}
				return false;
			}
			return true;
		}

		internal static Header GetHeader(this NetworkDestination dest, int typeCode)
		{
			return new Header(typeCode, dest);
		}
	}
	[AutoVersion]
	public static class NetworkingAPI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__RegisterServerHandlers;

			public static Action<NetworkClient> <1>__RegisterClientHandlers;

			public static Action <2>__UnRegisterServerHandlers;

			public static Action <3>__UnRegisterClientHandlers;

			public static NetworkMessageDelegate <4>__HandleMessageServer;

			public static NetworkMessageDelegate <5>__HandleCommandServer;

			public static NetworkMessageDelegate <6>__HandleRequestServer;

			public static NetworkMessageDelegate <7>__HandleReplyServer;

			public static NetworkMessageDelegate <8>__HandleMessageClient;

			public static NetworkMessageDelegate <9>__HandleCommandClient;

			public static NetworkMessageDelegate <10>__HandleRequestClient;

			public static NetworkMessageDelegate <11>__HandleReplyClient;
		}

		public const string PluginGUID = "com.bepis.r2api.networking";

		public const string PluginName = "R2API.Networking";

		private static readonly Dictionary<int, INetMessage> NetMessages = new Dictionary<int, INetMessage>();

		private static readonly Dictionary<int, INetCommand> NetCommands = new Dictionary<int, INetCommand>();

		private static readonly Dictionary<int, RequestPerformerBase> NetRequests = new Dictionary<int, RequestPerformerBase>();

		private static bool _hooksEnabled = false;

		public const string PluginVersion = "1.0.3";

		[Obsolete("All submodules are automatically loaded and this property is now unused")]
		public static bool Loaded => true;

		internal static short MessageIndex => 2048;

		internal static short CommandIndex => 4096;

		internal static short RequestIndex => 6144;

		internal static short ReplyIndex => 8192;

		private static NetworkWriter UniversalWriter { get; } = new NetworkWriter();


		public static bool RegisterMessageType<TMessage>() where TMessage : INetMessage, new()
		{
			SetHooks();
			return RegisterMessageTypeInternal<TMessage>();
		}

		internal static bool RegisterMessageTypeInternal<TMessage>() where TMessage : INetMessage, new()
		{
			TMessage val = new TMessage();
			int networkHash = GetNetworkHash(val.GetType());
			if (NetMessages.ContainsKey(networkHash))
			{
				NetworkingPlugin.Logger.LogError((object)"Tried to register a message type with a duplicate hash");
				return false;
			}
			NetMessages[networkHash] = val;
			return true;
		}

		public static bool RegisterCommandType<TCommand>() where TCommand : INetCommand, new()
		{
			SetHooks();
			return RegisterCommandTypeInternal<TCommand>();
		}

		internal static bool RegisterCommandTypeInternal<TCommand>() where TCommand : INetCommand, new()
		{
			TCommand val = new TCommand();
			int networkHash = GetNetworkHash(val.GetType());
			if (NetCommands.ContainsKey(networkHash))
			{
				NetworkingPlugin.Logger.LogError((object)"Tried to register a command type with a duplicate hash");
				return false;
			}
			NetCommands[networkHash] = val;
			return true;
		}

		public static bool RegisterRequestTypes<TRequest, TReply>() where TRequest : INetRequest<TRequest, TReply>, new() where TReply : INetRequestReply<TRequest, TReply>, new()
		{
			SetHooks();
			return RegisterRequestTypesInternal<TRequest, TReply>();
		}

		internal static bool RegisterRequestTypesInternal<TRequest, TReply>() where TRequest : INetRequest<TRequest, TReply>, new() where TReply : INetRequestReply<TRequest, TReply>, new()
		{
			TRequest request = new TRequest();
			TReply reply = new TReply();
			int networkHash = GetNetworkHash(request.GetType());
			if (NetRequests.ContainsKey(networkHash))
			{
				NetworkingPlugin.Logger.LogError((object)"Tried to register a request type with a duplicate hash");
				return false;
			}
			NetRequests[networkHash] = new RequestPerformer<TRequest, TReply>(request, reply);
			return true;
		}

		internal static void SetHooks()
		{
			if (!_hooksEnabled)
			{
				RegisterMessageTypeInternal<DamageMessage>();
				RegisterMessageTypeInternal<BuffMessage>();
				RegisterMessageTypeInternal<DotMessage>();
				RegisterMessageTypeInternal<ExampleMessage>();
				RegisterRequestTypesInternal<ExamplePing, ExamplePingReply>();
				NetworkManagerSystem.onStartServerGlobal += RegisterServerHandlers;
				NetworkManagerSystem.onStartClientGlobal += RegisterClientHandlers;
				NetworkManagerSystem.onStopServerGlobal -= UnRegisterServerHandlers;
				NetworkManagerSystem.onStopClientGlobal -= UnRegisterClientHandlers;
				_hooksEnabled = true;
			}
		}

		internal static void UnsetHooks()
		{
			NetworkManagerSystem.onStartServerGlobal -= RegisterServerHandlers;
			NetworkManagerSystem.onStartClientGlobal -= RegisterClientHandlers;
			NetworkManagerSystem.onStopServerGlobal += UnRegisterServerHandlers;
			NetworkManagerSystem.onStopClientGlobal += UnRegisterClientHandlers;
			_hooksEnabled = false;
		}

		private static void RegisterServerHandlers()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			NetworkingPlugin.Logger.LogInfo((object)"Server Handlers registered");
			short messageIndex = MessageIndex;
			object obj = <>O.<4>__HandleMessageServer;
			if (obj == null)
			{
				NetworkMessageDelegate val = HandleMessageServer;
				<>O.<4>__HandleMessageServer = val;
				obj = (object)val;
			}
			NetworkServer.RegisterHandler(messageIndex, (NetworkMessageDelegate)obj);
			short commandIndex = CommandIndex;
			object obj2 = <>O.<5>__HandleCommandServer;
			if (obj2 == null)
			{
				NetworkMessageDelegate val2 = HandleCommandServer;
				<>O.<5>__HandleCommandServer = val2;
				obj2 = (object)val2;
			}
			NetworkServer.RegisterHandler(commandIndex, (NetworkMessageDelegate)obj2);
			short requestIndex = RequestIndex;
			object obj3 = <>O.<6>__HandleRequestServer;
			if (obj3 == null)
			{
				NetworkMessageDelegate val3 = HandleRequestServer;
				<>O.<6>__HandleRequestServer = val3;
				obj3 = (object)val3;
			}
			NetworkServer.RegisterHandler(requestIndex, (NetworkMessageDelegate)obj3);
			short replyIndex = ReplyIndex;
			object obj4 = <>O.<7>__HandleReplyServer;
			if (obj4 == null)
			{
				NetworkMessageDelegate val4 = HandleReplyServer;
				<>O.<7>__HandleReplyServer = val4;
				obj4 = (object)val4;
			}
			NetworkServer.RegisterHandler(replyIndex, (NetworkMessageDelegate)obj4);
		}

		private static void RegisterClientHandlers(NetworkClient client)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			NetworkingPlugin.Logger.LogInfo((object)"Client Handlers registered");
			short messageIndex = MessageIndex;
			object obj = <>O.<8>__HandleMessageClient;
			if (obj == null)
			{
				NetworkMessageDelegate val = HandleMessageClient;
				<>O.<8>__HandleMessageClient = val;
				obj = (object)val;
			}
			client.RegisterHandler(messageIndex, (NetworkMessageDelegate)obj);
			short commandIndex = CommandIndex;
			object obj2 = <>O.<9>__HandleCommandClient;
			if (obj2 == null)
			{
				NetworkMessageDelegate val2 = HandleCommandClient;
				<>O.<9>__HandleCommandClient = val2;
				obj2 = (object)val2;
			}
			client.RegisterHandler(commandIndex, (NetworkMessageDelegate)obj2);
			short requestIndex = RequestIndex;
			object obj3 = <>O.<10>__HandleRequestClient;
			if (obj3 == null)
			{
				NetworkMessageDelegate val3 = HandleRequestClient;
				<>O.<10>__HandleRequestClient = val3;
				obj3 = (object)val3;
			}
			client.RegisterHandler(requestIndex, (NetworkMessageDelegate)obj3);
			short replyIndex = ReplyIndex;
			object obj4 = <>O.<11>__HandleReplyClient;
			if (obj4 == null)
			{
				NetworkMessageDelegate val4 = HandleReplyClient;
				<>O.<11>__HandleReplyClient = val4;
				obj4 = (object)val4;
			}
			client.RegisterHandler(replyIndex, (NetworkMessageDelegate)obj4);
		}

		private static void UnRegisterServerHandlers()
		{
			NetworkingPlugin.Logger.LogInfo((object)"Server Handlers unregistered");
			NetworkServer.UnregisterHandler(MessageIndex);
			NetworkServer.UnregisterHandler(CommandIndex);
			NetworkServer.UnregisterHandler(RequestIndex);
			NetworkServer.UnregisterHandler(ReplyIndex);
		}

		private static void UnRegisterClientHandlers()
		{
			NetworkingPlugin.Logger.LogInfo((object)"Client Handlers unregistered");
			foreach (NetworkClient allClient in NetworkClient.allClients)
			{
				allClient.UnregisterHandler(MessageIndex);
				allClient.UnregisterHandler(CommandIndex);
				allClient.UnregisterHandler(RequestIndex);
				allClient.UnregisterHandler(ReplyIndex);
			}
		}

		internal static int GetNetworkHash(Type type)
		{
			return (type.Assembly.FullName + type.FullName).GetHashCode();
		}

		internal static Writer GetWriter(short messageIndex, NetworkConnection target, QosType qos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return new Writer(UniversalWriter, messageIndex, target, qos);
		}

		private static void HandleCommandServer(NetworkMessage msg)
		{
			Header header = msg.reader.Read<Header>();
			if (header.Destination.ShouldRun())
			{
				header.RemoveDestination(NetworkDestination.Server);
				if (NetCommands.TryGetValue(header.TypeCode, out INetCommand value))
				{
					value.OnReceived();
				}
				else
				{
					NetworkingPlugin.Logger.LogError((object)"Unhandled command received, you may be missing mods");
				}
			}
			if (!header.Destination.ShouldSend())
			{
				return;
			}
			int connectionId = msg.conn.connectionId;
			for (int i = 0; i < NetworkServer.connections.Count; i++)
			{
				if (i == connectionId)
				{
					continue;
				}
				NetworkConnection val = NetworkServer.connections[i];
				if (val != null && (!NetworkServer.localClientActive || !NetworkServer.localConnections.Contains(val)))
				{
					using Writer writer = GetWriter(CommandIndex, val, (QosType)3);
					SerializableObjectExtensions.Write(writer, header);
				}
			}
		}

		private static void HandleMessageServer(NetworkMessage msg)
		{
			NetworkReader reader = msg.reader;
			Header header = reader.Read<Header>();
			if (header.Destination.ShouldRun())
			{
				header.RemoveDestination(NetworkDestination.Server);
				if (NetMessages.TryGetValue(header.TypeCode, out INetMessage value))
				{
					value.Deserialize(reader);
					value.OnReceived();
				}
				else
				{
					NetworkingPlugin.Logger.LogError((object)"Unhandled message received, you may be missing mods");
				}
			}
			if (!header.Destination.ShouldSend())
			{
				return;
			}
			int connectionId = msg.conn.connectionId;
			byte[] array = reader.ReadBytes((int)(reader.Length - reader.Position));
			for (int i = 0; i < NetworkServer.connections.Count; i++)
			{
				if (i == connectionId)
				{
					continue;
				}
				NetworkConnection val = NetworkServer.connections[i];
				if (val != null && (!NetworkServer.localClientActive || !NetworkServer.localConnections.Contains(val)))
				{
					using Writer writer = GetWriter(MessageIndex, val, (QosType)3);
					NetworkWriter obj = writer;
					obj.Write(header);
					obj.WriteBytesFull(array);
				}
			}
		}

		private static void HandleRequestServer(NetworkMessage msg)
		{
			NetworkReader reader = msg.reader;
			Header header = reader.Read<Header>();
			if (header.Destination.ShouldRun())
			{
				header.RemoveDestination(NetworkDestination.Server);
				if (NetRequests.TryGetValue(header.TypeCode, out RequestPerformerBase value))
				{
					ISerializableObject target = value.PerformRequest(reader);
					Header target2 = new Header(header.TypeCode, NetworkDestination.Clients);
					using Writer writer = GetWriter(ReplyIndex, msg.conn, (QosType)3);
					NetworkWriter writer2 = writer;
					writer2.Write(target2);
					writer2.Write(target);
				}
				else
				{
					NetworkingPlugin.Logger.LogError((object)"Unhandled request message received, you may be missing mods");
				}
			}
			if (!header.Destination.ShouldSend())
			{
				return;
			}
			int connectionId = msg.conn.connectionId;
			byte[] array = reader.ReadBytes((int)(reader.Length - reader.Position));
			for (int i = 0; i < NetworkServer.connections.Count; i++)
			{
				if (i == connectionId)
				{
					continue;
				}
				NetworkConnection val = NetworkServer.connections[i];
				if (val != null && (!NetworkServer.localClientActive || !NetworkServer.localConnections.Contains(val)))
				{
					using Writer writer3 = GetWriter(RequestIndex, val, (QosType)3);
					NetworkWriter obj = writer3;
					obj.Write(header);
					obj.WriteBytesFull(array);
				}
			}
		}

		private static void HandleReplyServer(NetworkMessage msg)
		{
			NetworkReader reader = msg.reader;
			Header header = reader.Read<Header>();
			if (header.Destination.ShouldRun())
			{
				header.RemoveDestination(NetworkDestination.Server);
				if (NetRequests.TryGetValue(header.TypeCode, out RequestPerformerBase value))
				{
					value.PerformReply(reader);
				}
				else
				{
					NetworkingPlugin.Logger.LogError((object)"Unhandled reply received, you may be missing mods");
				}
			}
			if (!header.Destination.ShouldSend())
			{
				return;
			}
			int connectionId = msg.conn.connectionId;
			for (int i = 0; i < NetworkServer.connections.Count; i++)
			{
				if (i == connectionId)
				{
					continue;
				}
				NetworkConnection val = NetworkServer.connections[i];
				if (val != null && (!NetworkServer.localClientActive || !NetworkServer.localConnections.Contains(val)))
				{
					using Writer writer = GetWriter(RequestIndex, val, (QosType)3);
					SerializableObjectExtensions.Write(writer, header);
				}
			}
		}

		private static void HandleCommandClient(NetworkMessage msg)
		{
			Header header = msg.reader.Read<Header>();
			if (header.Destination.ShouldRun())
			{
				header.RemoveDestination(NetworkDestination.Clients);
				if (NetCommands.TryGetValue(header.TypeCode, out INetCommand value))
				{
					value.OnReceived();
				}
				else
				{
					NetworkingPlugin.Logger.LogError((object)"Unhandled command received, you may be missing mods");
				}
			}
		}

		private static void HandleMessageClient(NetworkMessage msg)
		{
			NetworkReader reader = msg.reader;
			Header header = reader.Read<Header>();
			if (header.Destination.ShouldRun())
			{
				header.RemoveDestination(NetworkDestination.Clients);
				if (NetMessages.TryGetValue(header.TypeCode, out INetMessage value))
				{
					value.Deserialize(reader);
					value.OnReceived();
				}
				else
				{
					NetworkingPlugin.Logger.LogError((object)"Unhandled message received, you may be missing mods");
				}
			}
		}

		private static void HandleRequestClient(NetworkMessage msg)
		{
			NetworkReader reader = msg.reader;
			Header header = reader.Read<Header>();
			if (!header.Destination.ShouldRun())
			{
				return;
			}
			header.RemoveDestination(NetworkDestination.Clients);
			if (NetRequests.TryGetValue(header.TypeCode, out RequestPerformerBase value))
			{
				ISerializableObject target = value.PerformRequest(reader);
				Header target2 = new Header(header.TypeCode, NetworkDestination.Clients);
				using Writer writer = GetWriter(ReplyIndex, msg.conn, (QosType)3);
				NetworkWriter writer2 = writer;
				writer2.Write(target2);
				writer2.Write(target);
				return;
			}
			NetworkingPlugin.Logger.LogError((object)"Unhandled request message received, you may be missing mods");
		}

		private static void HandleReplyClient(NetworkMessage msg)
		{
			NetworkReader reader = msg.reader;
			Header header = reader.Read<Header>();
			if (header.Destination.ShouldRun())
			{
				header.RemoveDestination(NetworkDestination.Clients);
				if (NetRequests.TryGetValue(header.TypeCode, out RequestPerformerBase value))
				{
					value.PerformReply(reader);
				}
				else
				{
					NetworkingPlugin.Logger.LogError((object)"Unhandled reply received, you may be missing mods");
				}
			}
		}
	}
	public static class NetworkingHelpers
	{
		public static void DealDamage(this DamageInfo? damage, HurtBox? target, bool callDamage, bool callHitEnemy, bool callHitWorld)
		{
			if (NetworkServer.active)
			{
				if (callDamage && (Object)(object)target != (Object)null && (Object)(object)target.healthComponent != (Object)null)
				{
					target.healthComponent.TakeDamage(damage);
				}
				if (callHitEnemy && (Object)(object)target != (Object)null && (Object)(object)target.healthComponent != (Object)null)
				{
					GlobalEventManager.instance.OnHitEnemy(damage, ((Component)target.healthComponent).gameObject);
				}
				if (callHitWorld)
				{
					GlobalEventManager.instance.OnHitAll(damage, (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)target.healthComponent)) ? ((Component)target.healthComponent).gameObject : null);
				}
			}
			else
			{
				new DamageMessage(damage, target, callDamage, callHitEnemy, callHitWorld).Send(NetworkDestination.Server);
			}
		}

		public static void ApplyBuff(this CharacterBody? body, BuffIndex buff, int stacks = 1, float duration = -1f)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				if (duration < 0f)
				{
					body.SetBuffCount(buff, stacks);
					return;
				}
				if (stacks < 0)
				{
					NetworkingPlugin.Logger.LogError((object)"Cannot remove duration from a buff");
					return;
				}
				for (int i = 0; i < stacks; i++)
				{
					body.AddTimedBuff(buff, duration);
				}
			}
			else
			{
				new BuffMessage(body, buff, stacks, duration).Send(NetworkDestination.Server);
			}
		}

		public static void ApplyDot(this HealthComponent victim, GameObject attacker, DotIndex dotIndex, float duration = 8f, float damageMultiplier = 1f)
		{
			//IL_0028: 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)
			if (NetworkServer.active)
			{
				DotController.InflictDot(((Component)victim).gameObject, attacker, dotIndex, duration, damageMultiplier, (uint?)null);
			}
			else
			{
				new DotMessage(((Component)victim).gameObject, attacker, dotIndex, duration, damageMultiplier).Send(NetworkDestination.Server);
			}
		}
	}
	[BepInPlugin("com.bepis.r2api.networking", "R2API.Networking", "1.0.3")]
	public sealed class NetworkingPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			NetworkingAPI.SetHooks();
		}

		private void OnDestroy()
		{
			NetworkingAPI.UnsetHooks();
		}
	}
	internal abstract class RequestPerformerBase
	{
		internal abstract ISerializableObject PerformRequest(NetworkReader reader);

		internal abstract void PerformReply(NetworkReader reader);
	}
	internal sealed class RequestPerformer<TRequest, TReply> : RequestPerformerBase where TRequest : INetRequest<TRequest, TReply> where TReply : INetRequestReply<TRequest, TReply>
	{
		private readonly TRequest _request;

		private readonly TReply _reply;

		internal RequestPerformer(TRequest request, TReply reply)
		{
			_request = request;
			_reply = reply;
		}

		internal override ISerializableObject PerformRequest(NetworkReader reader)
		{
			_request.Deserialize(reader);
			return _request.OnRequestReceived();
		}

		internal override void PerformReply(NetworkReader reader)
		{
			_reply.Deserialize(reader);
			_reply.OnReplyReceived();
		}
	}
	internal class Writer : IDisposable
	{
		private readonly NetworkWriter _netWriter;

		private readonly NetworkConnection _target;

		private readonly QosType _qos;

		internal Writer(NetworkWriter writer, short messageIndex, NetworkConnection target, QosType qos)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			_netWriter = writer;
			_target = target;
			_qos = qos;
			writer.StartMessage(messageIndex);
		}

		public static implicit operator NetworkWriter(Writer writer)
		{
			return writer._netWriter;
		}

		public void Dispose()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected I4, but got Unknown
			_netWriter.FinishMessage();
			_target.SendWriter(_netWriter, (int)_qos);
		}
	}
}
namespace R2API.Networking.Messages
{
	internal struct BuffMessage : INetMessage, ISerializableObject
	{
		private CharacterBody _body;

		private BuffIndex _buff;

		private int _stacks;

		private float _duration;

		public void Serialize(NetworkWriter writer)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(((Component)_body).gameObject);
			NetworkExtensions.WriteBuffIndex(writer, _buff);
			writer.Write(_stacks);
			writer.Write(_duration);
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			_body = reader.ReadGameObject().GetComponent<CharacterBody>();
			_buff = NetworkExtensions.ReadBuffIndex(reader);
			_stacks = reader.ReadInt32();
			_duration = reader.ReadSingle();
		}

		public void OnReceived()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_body.ApplyBuff(_buff, _stacks, _duration);
		}

		internal BuffMessage(CharacterBody body, BuffIndex buff, int stacks, float duration)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			_body = body;
			_buff = buff;
			_stacks = stacks;
			_duration = duration;
		}
	}
	internal struct DamageMessage : INetMessage, ISerializableObject
	{
		private DamageInfo _damage;

		private HurtBox _target;

		private bool _callDamage;

		private bool _callHitEnemy;

		private bool _callHitWorld;

		public void Serialize(NetworkWriter writer)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			NetworkExtensions.Write(writer, _damage);
			NetworkExtensions.Write(writer, HurtBoxReference.FromHurtBox(_target));
			byte b = 0;
			b = (byte)((uint)b | (_callHitWorld ? 1u : 0u));
			b <<= 1;
			b = (byte)((uint)b | (_callHitEnemy ? 1u : 0u));
			b <<= 1;
			b = (byte)((uint)b | (_callDamage ? 1u : 0u));
			writer.Write(b);
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			_damage = NetworkExtensions.ReadDamageInfo(reader);
			HurtBoxReference val = NetworkExtensions.ReadHurtBoxReference(reader);
			_target = ((HurtBoxReference)(ref val)).ResolveHurtBox();
			byte b = reader.ReadByte();
			_callDamage = (b & 1) > 0;
			b >>= 1;
			_callHitEnemy = (b & 1) > 0;
			b >>= 1;
			_callHitWorld = (b & 1) > 0;
		}

		public void OnReceived()
		{
			_damage.DealDamage(_target, _callDamage, _callHitEnemy, _callHitWorld);
		}

		internal DamageMessage(DamageInfo damage, HurtBox target, bool callDamage, bool callHitEnemy, bool callHitWorld)
		{
			_damage = damage;
			_target = target;
			_callDamage = callDamage;
			_callHitEnemy = callHitEnemy;
			_callHitWorld = callHitWorld;
		}
	}
	internal struct DotMessage : INetMessage, ISerializableObject
	{
		private GameObject _victim;

		private GameObject _attacker;

		private DotIndex _dotIndex;

		private float _duration;

		private float _damageMultiplier;

		public void Serialize(NetworkWriter writer)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected I4, but got Unknown
			writer.Write(_victim);
			writer.Write(_attacker);
			NetworkExtensions.WritePackedIndex32(writer, (int)_dotIndex);
			writer.Write(_duration);
			writer.Write(_damageMultiplier);
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			_victim = reader.ReadGameObject();
			_attacker = reader.ReadGameObject();
			_dotIndex = (DotIndex)NetworkExtensions.ReadPackedIndex32(reader);
			_duration = reader.ReadSingle();
			_damageMultiplier = reader.ReadSingle();
		}

		public void OnReceived()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			DotController.InflictDot(_victim, _attacker, _dotIndex, _duration, _damageMultiplier, (uint?)null);
		}

		internal DotMessage(GameObject victimObject, GameObject attackerObject, DotIndex dotIndex, float duration, float damageMultiplier)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_victim = victimObject;
			_attacker = attackerObject;
			_dotIndex = dotIndex;
			_duration = duration;
			_damageMultiplier = damageMultiplier;
		}
	}
	internal struct ExampleMessage : INetMessage, ISerializableObject
	{
		internal int Integer;

		internal string Str;

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(Integer);
			writer.Write(Str);
		}

		public void Deserialize(NetworkReader reader)
		{
			Integer = reader.ReadInt32();
			Str = reader.ReadString();
		}

		public void OnReceived()
		{
			NetworkingPlugin.Logger.LogWarning((object)("int : " + Integer + " str : " + Str));
		}
	}
	internal struct ExamplePing : INetRequest<ExamplePing, ExamplePingReply>, ISerializableObject
	{
		internal int Integer;

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(Integer);
		}

		public void Deserialize(NetworkReader reader)
		{
			Integer = reader.ReadInt32();
		}

		public ExamplePingReply OnRequestReceived()
		{
			NetworkingPlugin.Logger.LogWarning((object)("ExamplePing - Received this request : " + Integer));
			ExamplePingReply result = default(ExamplePingReply);
			result.Str = "I'm answering you back this string";
			return result;
		}
	}
	internal struct ExamplePingReply : INetRequestReply<ExamplePing, ExamplePingReply>, ISerializableObject
	{
		internal string Str;

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(Str);
		}

		public void Deserialize(NetworkReader reader)
		{
			Str = reader.ReadString();
		}

		public void OnReplyReceived()
		{
			NetworkingPlugin.Logger.LogWarning((object)("ExamplePingReply - Received this Reply : " + Str));
		}
	}
}
namespace R2API.Networking.Interfaces
{
	public interface INetCommand
	{
		void OnReceived();
	}
	public static class NetCommandExtensions
	{
		private static void SendCommand(Header header, NetworkConnection conn)
		{
			using Writer writer = NetworkingAPI.GetWriter(NetworkingAPI.CommandIndex, conn, (QosType)3);
			SerializableObjectExtensions.Write(writer, header);
		}

		public static void Send(this INetCommand? command, NetworkDestination destination)
		{
			if (destination.ShouldRun())
			{
				command.OnReceived();
			}
			if (!destination.ShouldSend())
			{
				return;
			}
			Header header = destination.GetHeader(NetworkingAPI.GetNetworkHash(command.GetType()));
			if (NetworkServer.active)
			{
				for (int i = 0; i < NetworkServer.connections.Count; i++)
				{
					NetworkConnection val = NetworkServer.connections[i];
					if (val != null && (!NetworkServer.localClientActive || !NetworkServer.localConnections.Contains(val)))
					{
						SendCommand(header, val);
					}
				}
			}
			else if (NetworkClient.active)
			{
				SendCommand(header, ClientScene.readyConnection);
			}
		}

		public static void Send(this INetCommand? command, NetworkConnection target)
		{
			if (target == null)
			{
				throw new ArgumentNullException("target");
			}
			if (!NetworkServer.active)
			{
				throw new InvalidOperationException("NetworkServer is not active.");
			}
			if (NetworkClient.active)
			{
				foreach (NetworkClient allClient in NetworkClient.allClients)
				{
					if (allClient.connection != null && allClient.connection.connectionId == target.connectionId)
					{
						command.OnReceived();
						return;
					}
				}
			}
			SendCommand(NetworkDestination.Clients.GetHeader(NetworkingAPI.GetNetworkHash(command.GetType())), target);
		}
	}
	public interface INetMessage : ISerializableObject
	{
		void OnReceived();
	}
	public static class NetMessageExtensions
	{
		private static void SendMessage(INetMessage? message, Header header, NetworkConnection conn)
		{
			using Writer writer = NetworkingAPI.GetWriter(NetworkingAPI.MessageIndex, conn, (QosType)3);
			NetworkWriter writer2 = writer;
			writer2.Write(header);
			writer2.Write(message);
		}

		public static void Send(this INetMessage? message, NetworkDestination destination)
		{
			if (destination.ShouldRun())
			{
				message.OnReceived();
			}
			if (!destination.ShouldSend())
			{
				return;
			}
			Header header = destination.GetHeader(NetworkingAPI.GetNetworkHash(message.GetType()));
			if (NetworkServer.active)
			{
				for (int i = 0; i < NetworkServer.connections.Count; i++)
				{
					NetworkConnection val = NetworkServer.connections[i];
					if (val != null && (!NetworkServer.localClientActive || !NetworkServer.localConnections.Contains(val)))
					{
						SendMessage(message, header, val);
					}
				}
			}
			else if (NetworkClient.active)
			{
				SendMessage(message, header, ClientScene.readyConnection);
			}
		}

		public static void Send(this INetMessage? message, NetworkConnection target)
		{
			if (target == null)
			{
				throw new ArgumentNullException("target");
			}
			if (!NetworkServer.active)
			{
				throw new InvalidOperationException("NetworkServer is not active.");
			}
			if (NetworkClient.active)
			{
				foreach (NetworkClient allClient in NetworkClient.allClients)
				{
					if (allClient.connection != null && allClient.connection.connectionId == target.connectionId)
					{
						message.OnReceived();
						return;
					}
				}
			}
			Header header = NetworkDestination.Clients.GetHeader(NetworkingAPI.GetNetworkHash(message.GetType()));
			SendMessage(message, header, target);
		}
	}
	public interface INetRequest<TRequest, TReply> : ISerializableObject where TRequest : INetRequest<TRequest, TReply> where TReply : INetRequestReply<TRequest, TReply>
	{
		TReply OnRequestReceived();
	}
	public interface INetRequestReply<TRequest, TReply> : ISerializableObject where TRequest : INetRequest<TRequest, TReply> where TReply : INetRequestReply<TRequest, TReply>
	{
		void OnReplyReceived();
	}
	public static class NetRequestExtensions
	{
		private static void SendRequest<TRequest, TReply>(TRequest request, Header header, NetworkConnection conn) where TRequest : INetRequest<TRequest, TReply> where TReply : INetRequestReply<TRequest, TReply>
		{
			using Writer writer = NetworkingAPI.GetWriter(NetworkingAPI.RequestIndex, conn, (QosType)3);
			NetworkWriter writer2 = writer;
			writer2.Write(header);
			writer2.Write(request);
		}

		public static void Send<TRequest, TReply>(this TRequest request, NetworkDestination destination) where TRequest : INetRequest<TRequest, TReply> where TReply : INetRequestReply<TRequest, TReply>
		{
			if (destination.ShouldRun())
			{
				request.OnRequestReceived().OnReplyReceived();
			}
			if (!destination.ShouldSend())
			{
				return;
			}
			Header header = destination.GetHeader(NetworkingAPI.GetNetworkHash(request.GetType()));
			if (NetworkServer.active)
			{
				for (int i = 0; i < NetworkServer.connections.Count; i++)
				{
					NetworkConnection val = NetworkServer.connections[i];
					if (val != null && (!NetworkServer.localClientActive || !NetworkServer.localConnections.Contains(val)))
					{
						SendRequest<TRequest, TReply>(request, header, val);
					}
				}
			}
			else if (NetworkClient.active)
			{
				SendRequest<TRequest, TReply>(request, header, ClientScene.readyConnection);
			}
		}

		public static void Send<TRequest, TReply>(this TRequest request, NetworkConnection target) where TRequest : INetRequest<TRequest, TReply> where TReply : INetRequestReply<TRequest, TReply>
		{
			if (target == null)
			{
				throw new ArgumentNullException("target");
			}
			if (!NetworkServer.active)
			{
				throw new InvalidOperationException("NetworkServer is not active.");
			}
			if (NetworkClient.active)
			{
				foreach (NetworkClient allClient in NetworkClient.allClients)
				{
					if (allClient.connection != null && allClient.connection.connectionId == target.connectionId)
					{
						request.OnRequestReceived().OnReplyReceived();
						return;
					}
				}
			}
			Header header = NetworkDestination.Clients.GetHeader(NetworkingAPI.GetNetworkHash(request.GetType()));
			SendRequest<TRequest, TReply>(request, header, target);
		}
	}
	public interface ISerializableObject
	{
		void Serialize(NetworkWriter writer);

		void Deserialize(NetworkReader reader);
	}
	public static class SerializableObjectExtensions
	{
		public static void Write<TObject>(this NetworkWriter? writer, TObject target) where TObject : ISerializableObject
		{
			target.Serialize(writer);
		}

		public static TObject Read<TObject>(this NetworkReader? reader, TObject destination) where TObject : ISerializableObject
		{
			destination.Deserialize(reader);
			return destination;
		}

		public static TObject Read<TObject>(this NetworkReader? reader) where TObject : ISerializableObject, new()
		{
			TObject result = new TObject();
			result.Deserialize(reader);
			return result;
		}
	}
	public interface ISerializer<TObject>
	{
		void Serialize(NetworkWriter writer, TObject target);

		void Deserialize(NetworkReader reader, TObject target);
	}
	public static class SerializerExtensions
	{
		public static void Write<TObject>(this NetworkWriter? writer, TObject target, ISerializer<TObject>? serializer)
		{
			serializer.Serialize(writer, target);
		}

		public static TObject Read<TObject>(this NetworkReader? reader, ref TObject destination, ISerializer<TObject>? serializer)
		{
			serializer.Deserialize(reader, destination);
			return destination;
		}
	}
}