From 2255e7c1adb66830f2a9a7323f9a9d5cbd6457c2 Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+Misfiy@users.noreply.github.com> Date: Sun, 18 May 2025 15:37:11 +0200 Subject: [PATCH 1/4] Mirror!!??!?! --- SecretAPI/Extensions/MirrorExtensions.cs | 62 ++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 SecretAPI/Extensions/MirrorExtensions.cs diff --git a/SecretAPI/Extensions/MirrorExtensions.cs b/SecretAPI/Extensions/MirrorExtensions.cs new file mode 100644 index 0000000..2c8a36a --- /dev/null +++ b/SecretAPI/Extensions/MirrorExtensions.cs @@ -0,0 +1,62 @@ +namespace SecretAPI.Extensions +{ + using System; + using LabApi.Features.Wrappers; + using Mirror; + using Respawning; + + /// + /// Extensions related to Mirror. + /// + public static class MirrorExtensions + { + /// + /// Sends a fake cassie message to a player. + /// + /// The target to send the cassie message to. + /// The message to send. + /// Whether the cassie is held. + /// Whether the cassie is noisy. + /// Whether there is subtitles on the cassie. + /// The custom subtitles to use for the cassie. + public static void SendFakeCassieMessage( + this Player target, + string message, + bool isHeld = false, + bool isNoisy = true, + bool isSubtitles = true, + string customSubtitles = "") + { + foreach (RespawnEffectsController allController in RespawnEffectsController.AllControllers) + { + SendFakeRpcMessage(target, allController, typeof(RespawnEffectsController), nameof(RespawnEffectsController.RpcCassieAnnouncement), message, isHeld, isNoisy, isSubtitles, customSubtitles); + } + } + + /// + /// Send a fake rpc message to a player. + /// + /// The target to send the rpc to. + /// + /// + /// + /// + public static void SendFakeRpcMessage(this Player target, NetworkBehaviour behaviour, Type type, string rpc, params object[] values) + { + NetworkWriter writer = NetworkWriterPool.Get(); + + foreach (object obj in values) + writer.Write(obj); + + RpcMessage rpcMessage = new() + { + netId = behaviour.netId, + componentIndex = behaviour.ComponentIndex, + functionHash = (ushort)$"{type.FullName}.{rpc}".GetStableHashCode(), + payload = writer.ToArraySegment(), + }; + + target.Connection.Send(rpcMessage); + } + } +} \ No newline at end of file From 5a28a3cd4d5b8e20c927ab0d1c964ae9d0c9ac13 Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+Misfiy@users.noreply.github.com> Date: Sun, 18 May 2025 16:38:52 +0200 Subject: [PATCH 2/4] mirror stuff --- SecretAPI/Extensions/MirrorExtensions.cs | 15 ++++++----- SecretAPI/Extensions/ReflectionExtensions.cs | 27 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/SecretAPI/Extensions/MirrorExtensions.cs b/SecretAPI/Extensions/MirrorExtensions.cs index 2c8a36a..992c8c5 100644 --- a/SecretAPI/Extensions/MirrorExtensions.cs +++ b/SecretAPI/Extensions/MirrorExtensions.cs @@ -37,13 +37,13 @@ public static void SendFakeCassieMessage( /// Send a fake rpc message to a player. /// /// The target to send the rpc to. - /// - /// - /// - /// - public static void SendFakeRpcMessage(this Player target, NetworkBehaviour behaviour, Type type, string rpc, params object[] values) + /// The network behaviour containing the rpc. + /// The type containing the rpc. + /// The name of the rpc to call. + /// The values to write to the writer. + public static void SendFakeRpcMessage(this Player target, NetworkBehaviour behaviour, Type type, string rpcName, params object[] values) { - NetworkWriter writer = NetworkWriterPool.Get(); + NetworkWriterPooled writer = NetworkWriterPool.Get(); foreach (object obj in values) writer.Write(obj); @@ -52,11 +52,12 @@ public static void SendFakeRpcMessage(this Player target, NetworkBehaviour behav { netId = behaviour.netId, componentIndex = behaviour.ComponentIndex, - functionHash = (ushort)$"{type.FullName}.{rpc}".GetStableHashCode(), + functionHash = (ushort)ReflectionExtensions.GetLongFuncName(type, rpcName).GetStableHashCode(), payload = writer.ToArraySegment(), }; target.Connection.Send(rpcMessage); + NetworkWriterPool.Return(writer); } } } \ No newline at end of file diff --git a/SecretAPI/Extensions/ReflectionExtensions.cs b/SecretAPI/Extensions/ReflectionExtensions.cs index b09262e..8857b64 100644 --- a/SecretAPI/Extensions/ReflectionExtensions.cs +++ b/SecretAPI/Extensions/ReflectionExtensions.cs @@ -1,6 +1,7 @@ namespace SecretAPI.Extensions { using System; + using System.Linq; using System.Reflection; /// @@ -8,6 +9,32 @@ /// public static class ReflectionExtensions { + /// + /// Gets the long name of a function. + /// + /// The type containing the method. + /// The method name. + /// The long function name. + /// When the method could not be found. + public static string GetLongFuncName(Type type, string methodName) + { + const BindingFlags methodFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + + MethodInfo method = type.GetMethod(methodName, methodFlags) ?? throw new InvalidOperationException($"[ReflectionExtensions.GetLongFuncName] {type.FullName}.{methodName} could not be found."); + return GetLongFuncName(type, method); + } + + /// + /// Gets the long name of a function. + /// + /// The type containing the method. + /// The method to use. + /// The long function name. + public static string GetLongFuncName(Type type, MethodInfo method) + { + return $"{method.ReturnType.FullName} {type.FullName}::{method.Name}({string.Join(", ", method.GetParameters().Select(x => x.ParameterType.FullName))})"; + } + /// /// Copies the properties. /// From e6db83ca0b9a95c8f1121adee55b848a6a75e9bc Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+Misfiy@users.noreply.github.com> Date: Mon, 19 May 2025 14:56:08 +0200 Subject: [PATCH 3/4] FINALLY FIX THIS --- SecretAPI/Extensions/MirrorExtensions.cs | 39 ++++++++++++++++++-- SecretAPI/Extensions/ReflectionExtensions.cs | 2 +- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/SecretAPI/Extensions/MirrorExtensions.cs b/SecretAPI/Extensions/MirrorExtensions.cs index 992c8c5..f037188 100644 --- a/SecretAPI/Extensions/MirrorExtensions.cs +++ b/SecretAPI/Extensions/MirrorExtensions.cs @@ -1,6 +1,8 @@ namespace SecretAPI.Extensions { using System; + using System.Reflection; + using LabApi.Features.Console; using LabApi.Features.Wrappers; using Mirror; using Respawning; @@ -29,6 +31,9 @@ public static void SendFakeCassieMessage( { foreach (RespawnEffectsController allController in RespawnEffectsController.AllControllers) { + if (!allController) + continue; + SendFakeRpcMessage(target, allController, typeof(RespawnEffectsController), nameof(RespawnEffectsController.RpcCassieAnnouncement), message, isHeld, isNoisy, isSubtitles, customSubtitles); } } @@ -43,21 +48,47 @@ public static void SendFakeCassieMessage( /// The values to write to the writer. public static void SendFakeRpcMessage(this Player target, NetworkBehaviour behaviour, Type type, string rpcName, params object[] values) { - NetworkWriterPooled writer = NetworkWriterPool.Get(); + NetworkWriterPooled pooledWriter = NetworkWriterPool.Get(); foreach (object obj in values) - writer.Write(obj); + ProperWrite(pooledWriter, obj); RpcMessage rpcMessage = new() { netId = behaviour.netId, componentIndex = behaviour.ComponentIndex, functionHash = (ushort)ReflectionExtensions.GetLongFuncName(type, rpcName).GetStableHashCode(), - payload = writer.ToArraySegment(), + payload = pooledWriter.ToArraySegment(), }; target.Connection.Send(rpcMessage); - NetworkWriterPool.Return(writer); + NetworkWriterPool.Return(pooledWriter); + } + + /// + /// Handles writing into a . + /// + /// The writer to write the object to. + /// The object to write. + public static void ProperWrite(NetworkWriter writer, object obj) + { + Type genericType = typeof(Writer<>).MakeGenericType(obj.GetType()); + FieldInfo? writeField = genericType.GetField("write", BindingFlags.Static | BindingFlags.Public); + if (writeField == null) + { + Logger.Warn($"Tried to write type: {obj.GetType()} but has no NetworkWriter!"); + return; + } + + object? writeDelegate = writeField.GetValue(null); + if (writeDelegate is Delegate del) + { + del.DynamicInvoke(writer, obj); + } + else + { + Logger.Warn($"Writer<{obj.GetType()}>.write is not a delegate!"); + } } } } \ No newline at end of file diff --git a/SecretAPI/Extensions/ReflectionExtensions.cs b/SecretAPI/Extensions/ReflectionExtensions.cs index 8857b64..987ca0b 100644 --- a/SecretAPI/Extensions/ReflectionExtensions.cs +++ b/SecretAPI/Extensions/ReflectionExtensions.cs @@ -32,7 +32,7 @@ public static string GetLongFuncName(Type type, string methodName) /// The long function name. public static string GetLongFuncName(Type type, MethodInfo method) { - return $"{method.ReturnType.FullName} {type.FullName}::{method.Name}({string.Join(", ", method.GetParameters().Select(x => x.ParameterType.FullName))})"; + return $"{method.ReturnType.FullName} {type.FullName}::{method.Name}({string.Join(",", method.GetParameters().Select(x => x.ParameterType.FullName))})"; } /// From d0c7691a0dc0c2314d47379a689bc79f24a14033 Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+Misfiy@users.noreply.github.com> Date: Mon, 19 May 2025 15:09:02 +0200 Subject: [PATCH 4/4] mrirrorrrrrrr --- SecretAPI/Extensions/MirrorExtensions.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/SecretAPI/Extensions/MirrorExtensions.cs b/SecretAPI/Extensions/MirrorExtensions.cs index f037188..8e4de53 100644 --- a/SecretAPI/Extensions/MirrorExtensions.cs +++ b/SecretAPI/Extensions/MirrorExtensions.cs @@ -81,14 +81,13 @@ public static void ProperWrite(NetworkWriter writer, object obj) } object? writeDelegate = writeField.GetValue(null); - if (writeDelegate is Delegate del) - { - del.DynamicInvoke(writer, obj); - } - else + if (writeDelegate is not Delegate del) { Logger.Warn($"Writer<{obj.GetType()}>.write is not a delegate!"); + return; } + + del.DynamicInvoke(writer, obj); } } } \ No newline at end of file