mirror of
https://github.com/NuclearPowered/Reactor.git
synced 2026-10-20 01:46:21 +00:00
86 lines
2.7 KiB
C#
86 lines
2.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using BepInEx.IL2CPP;
|
|
using Hazel;
|
|
using InnerNet;
|
|
|
|
namespace Reactor.Networking.MethodRpc
|
|
{
|
|
public class CustomMethodRpc : UnsafeCustomRpc
|
|
{
|
|
internal static bool SkipNextSend;
|
|
internal static Dictionary<MethodBase, CustomMethodRpc> allMethodRPCsFast = new();
|
|
|
|
private Func<object[], object> Invoker;
|
|
public Type[] Parameters { get; }
|
|
public Dictionary<Type, FieldInfo[]> StructBook { get; } = new();
|
|
|
|
public CustomMethodRpc(BasePlugin plugin, MethodInfo method, uint id, SendOption option,
|
|
RpcLocalHandling localHandling) : base(plugin, id)
|
|
{
|
|
Method = method;
|
|
LocalHandling = localHandling;
|
|
SendOption = option;
|
|
|
|
var methodParameters = method.GetParameters();
|
|
|
|
Parameters = new Type[methodParameters.Length];
|
|
for (var i = 0; i < methodParameters.Length; i++)
|
|
{
|
|
var arg = methodParameters[i];
|
|
var argType = arg.ParameterType;
|
|
if (argType.IsValueType && !argType.IsPrimitive && !StructBook.ContainsKey(arg.ParameterType))
|
|
{
|
|
var fields = argType.GetFields(BindingFlags.Instance | BindingFlags.Public)
|
|
.ToArray();
|
|
StructBook.Add(argType, fields);
|
|
}
|
|
|
|
Parameters[i] = argType;
|
|
}
|
|
|
|
Invoker = RpcPrefixHandle.GenerateCaller(Method);
|
|
|
|
allMethodRPCsFast.Add(Method, this);
|
|
}
|
|
|
|
public MethodInfo Method { get; }
|
|
public override Type InnerNetObjectType { get; } = typeof(PlayerControl);
|
|
public override RpcLocalHandling LocalHandling { get; }
|
|
public override SendOption SendOption { get; }
|
|
|
|
public override void UnsafeWrite(MessageWriter writer, object data)
|
|
{
|
|
var args = (object[]) data;
|
|
RpcSerializer.Serialize(writer, this, args);
|
|
}
|
|
|
|
public override object UnsafeRead(MessageReader reader)
|
|
{
|
|
var args = RpcSerializer.Deserialize(reader, this);
|
|
return args;
|
|
}
|
|
|
|
public override void UnsafeHandle(InnerNetObject innerNetObject, object data)
|
|
{
|
|
SkipNextSend = true;
|
|
|
|
var result = Invoker((object[]) data);
|
|
if (result != null)
|
|
{
|
|
Coroutines.Start((IEnumerator) result);
|
|
}
|
|
|
|
SkipNextSend = false;
|
|
}
|
|
|
|
public void Send(object[] args)
|
|
{
|
|
UnsafeSend(PlayerControl.LocalPlayer, args);
|
|
}
|
|
}
|
|
}
|