From 3b8f32c19beac26b48e717b090b4850957b899ab Mon Sep 17 00:00:00 2001 From: zombieb Date: Mon, 16 Feb 2026 12:19:45 -0500 Subject: [PATCH] Initial commit --- .gitignore | 61 +++++++++++++++++++++ Core/Dictionary.cs | 0 Core/Message.cs | 18 +++++++ Core/Plugin.cs | 24 +++++++++ Core/Socket.cs | 25 +++++++++ Patches/EventPatch.cs | 41 +++++++++++++++ Patches/OperationPatch.cs | 108 ++++++++++++++++++++++++++++++++++++++ PhotonLogger.csproj | 51 ++++++++++++++++++ PhotonLogger.sln | 25 +++++++++ Plugin.cs | 22 ++++++++ 10 files changed, 375 insertions(+) create mode 100644 .gitignore create mode 100644 Core/Dictionary.cs create mode 100644 Core/Message.cs create mode 100644 Core/Plugin.cs create mode 100644 Core/Socket.cs create mode 100644 Patches/EventPatch.cs create mode 100644 Patches/OperationPatch.cs create mode 100644 PhotonLogger.csproj create mode 100644 PhotonLogger.sln create mode 100644 Plugin.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..624d0f7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +## A streamlined .gitignore for modern .NET projects +## including temporary files, build results, and +## files generated by popular .NET tools. If you are +## developing with Visual Studio, the VS .gitignore +## https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +## has more thorough IDE-specific entries. +## +## Get latest from https://github.com/github/gitignore/blob/main/Dotnet.gitignore + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg + +# dotenv environment variables file +.env + +# Others +~$* +*~ +CodeCoverage/ + +# MSBuild Binary and Structured Log +*.binlog + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Root +.vs +Managed \ No newline at end of file diff --git a/Core/Dictionary.cs b/Core/Dictionary.cs new file mode 100644 index 0000000..e69de29 diff --git a/Core/Message.cs b/Core/Message.cs new file mode 100644 index 0000000..f3c0ae4 --- /dev/null +++ b/Core/Message.cs @@ -0,0 +1,18 @@ +using System; + +namespace PhotonLogger.Core; + +public enum MessageType +{ + Event, + OperationRequest, + OperationResponse +} + +[Serializable] +public class Message +{ + public long Time { get; set; } + public MessageType Type { get; set; } + public object Data { get; set; } +} \ No newline at end of file diff --git a/Core/Plugin.cs b/Core/Plugin.cs new file mode 100644 index 0000000..34a5cfd --- /dev/null +++ b/Core/Plugin.cs @@ -0,0 +1,24 @@ +using BepInEx.Logging; +using HarmonyLib; + +namespace PhotonLogger.Core; + +public static class LoggerPlugin +{ + public static ManualLogSource Log = Logger.CreateLogSource("PhotonLogger"); + + public static Harmony harmony = new("dev.proxnet.photon.logger"); + + public static void Load() + { + harmony.PatchAll(); + SocketProvider.Instance.Connect(); + } + + public static void Unload() + { + harmony.UnpatchSelf(); + SocketProvider.Instance.Close(); + Log.LogInfo("Unloading"); + } +} \ No newline at end of file diff --git a/Core/Socket.cs b/Core/Socket.cs new file mode 100644 index 0000000..f584cbd --- /dev/null +++ b/Core/Socket.cs @@ -0,0 +1,25 @@ +using WebSocketSharp; + +namespace PhotonLogger.Core; + +public class SocketProvider +{ + public static readonly SocketProvider Instance = new(); + + private readonly WebSocket socket = new("wss://photonlogger.proxnet.dev"); + + public void Write(string msg) + { + socket.Send(msg); + } + + public void Connect() + { + socket.Connect(); + } + + public void Close() + { + socket.Close(); + } +} \ No newline at end of file diff --git a/Patches/EventPatch.cs b/Patches/EventPatch.cs new file mode 100644 index 0000000..5311c1c --- /dev/null +++ b/Patches/EventPatch.cs @@ -0,0 +1,41 @@ +using ExitGames.Client.Photon; +using HarmonyLib; +using Newtonsoft.Json; +using Photon.Realtime; +using PhotonLogger.Core; +using System; +using System.Collections; +using System.IO; +using System.Reflection; + +[HarmonyPatch] +public class OnEventPatch +{ + [Serializable] + public class SerializableEventData + { + public byte Code { get; set; } + public NonAllocDictionary Parameters { get; set; } + } + + static MethodInfo TargetMethod() => typeof(LoadBalancingClient).GetRuntimeMethod("OnEvent", [ typeof(EventData) ]); + + static void Postfix(ref EventData photonEvent) + { + var newMsg = new Message + { + Time = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), + Type = MessageType.Event, + Data = new SerializableEventData + { + Code = photonEvent.Code, + Parameters = photonEvent.Parameters.paramDict + } + }; + + SocketProvider.Instance.Write(JsonConvert.SerializeObject(newMsg, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + })); + } +} \ No newline at end of file diff --git a/Patches/OperationPatch.cs b/Patches/OperationPatch.cs new file mode 100644 index 0000000..fde8b3b --- /dev/null +++ b/Patches/OperationPatch.cs @@ -0,0 +1,108 @@ +using ExitGames.Client.Photon; +using ExitGames.Client.Photon.StructWrapping; +using HarmonyLib; +using Newtonsoft.Json; +using Photon.Realtime; +using PhotonLogger.Core; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using static UnityEngine.UIElements.UIR.Implementation.UIRStylePainter; + +namespace PhotonLogger.Patches; + +[Serializable] +internal class SerializableOperationResponse +{ + public byte OperationCode { get; set; } + public short ReturnCode { get; set; } + public string DebugMessage { get; set; } + public NonAllocDictionary Parameters { get; set; } +} + +[HarmonyPatch] +public class OperationResponsePatch +{ + static MethodInfo TargetMethod() => AccessTools.Method(typeof(LoadBalancingClient), nameof(LoadBalancingClient.OnOperationResponse)); + + static void Postfix(ref OperationResponse operationResponse) + { + var newMsg = new Message + { + Time = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), + Type = MessageType.OperationResponse, + Data = new SerializableOperationResponse + { + OperationCode = operationResponse.OperationCode, + ReturnCode = operationResponse.ReturnCode, + DebugMessage = operationResponse.DebugMessage, + Parameters = operationResponse.Parameters.paramDict + } + }; + + SocketProvider.Instance.Write(JsonConvert.SerializeObject(newMsg, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + })); + } +} + +[Serializable] +internal class SerializableOperationRequest +{ + public byte OperationCode { get; set; } + public Dictionary Parameters { get; set; } +} + +[HarmonyPatch] +public class OperationRequestDictPatch +{ + static MethodInfo TargetMethod() => typeof(PhotonPeer).GetRuntimeMethod("SendOperation", [ typeof(byte), typeof(Dictionary), typeof(SendOptions) ]); + + static void Postfix(ref byte operationCode, ref Dictionary operationParameters) + { + var newMsg = new Message + { + Time = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), + Type = MessageType.OperationRequest, + Data = new SerializableOperationRequest + { + OperationCode = operationCode, + Parameters = operationParameters + } + }; + + SocketProvider.Instance.Write(JsonConvert.SerializeObject(newMsg, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + })); + } +} + +[HarmonyPatch] +public class OperationRequestParamDictPatch +{ + static MethodInfo TargetMethod() => typeof(PhotonPeer).GetRuntimeMethod("SendOperation", [ typeof(byte), typeof(ParameterDictionary), typeof(SendOptions) ]); + + static void Postfix(ref byte operationCode, ref ParameterDictionary operationParameters) + { + var newMsg = new Message + { + Time = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), + Type = MessageType.OperationRequest, + Data = new SerializableOperationRequest + { + OperationCode = operationCode, + Parameters = new Dictionary(operationParameters.paramDict) + } + }; + + SocketProvider.Instance.Write(JsonConvert.SerializeObject(newMsg, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + })); + } +} \ No newline at end of file diff --git a/PhotonLogger.csproj b/PhotonLogger.csproj new file mode 100644 index 0000000..8d1c21f --- /dev/null +++ b/PhotonLogger.csproj @@ -0,0 +1,51 @@ + + + + net46 + PhotonLogger + 1.0.0 + true + latest + + https://api.nuget.org/v3/index.json; + https://nuget.bepinex.dev/v3/index.json; + https://nuget.samboy.dev/v3/index.json + + PhotonLogger + + + + + + + + + + + + + + + + Managed\netstandard.dll + + + Managed\Photon3Unity3D.dll + + + Managed\PhotonChat.dll + + + Managed\PhotonRealtime.dll + + + Managed\PhotonUnityNetworking.dll + + + Managed\PhotonUnityNetworking.Utilities.dll + + + Managed\websocket-sharp.dll + + + diff --git a/PhotonLogger.sln b/PhotonLogger.sln new file mode 100644 index 0000000..2830689 --- /dev/null +++ b/PhotonLogger.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.2.11430.68 d18.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotonLogger", "PhotonLogger.csproj", "{E0AA83DA-CAD1-2C72-F6E6-EA3B0250E6C4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E0AA83DA-CAD1-2C72-F6E6-EA3B0250E6C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E0AA83DA-CAD1-2C72-F6E6-EA3B0250E6C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E0AA83DA-CAD1-2C72-F6E6-EA3B0250E6C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E0AA83DA-CAD1-2C72-F6E6-EA3B0250E6C4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {56915C5F-6396-4D63-B89C-0DD2C586C221} + EndGlobalSection +EndGlobal diff --git a/Plugin.cs b/Plugin.cs new file mode 100644 index 0000000..bba8143 --- /dev/null +++ b/Plugin.cs @@ -0,0 +1,22 @@ +using BepInEx; +using BepInEx.Unity.Mono; +using PhotonLogger.Core; + +namespace PhotonLogger; + +[BepInPlugin("dev.proxnet.photon.logger", "PhotonLogger", "0.1.0")] +#pragma warning disable BepInEx002 // Classes with BepInPlugin attribute must inherit from BaseUnityPlugin +public class MonoPlugin : BaseUnityPlugin +#pragma warning restore BepInEx002 // Classes with BepInPlugin attribute must inherit from BaseUnityPlugin +{ + public void Awake() + { + LoggerPlugin.Log.LogInfo($"Plugin Initialized"); + LoggerPlugin.Load(); + } + + public void OnDestroy() + { + LoggerPlugin.Unload(); + } +} \ No newline at end of file