using System; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using Harmony; using Lidgren.Network; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Networking; using StardewModdingAPI.Framework.Patching; using StardewValley; using StardewValley.Network; namespace StardewModdingAPI.Patches { /// A Harmony patch to let SMAPI override methods. internal class LidgrenServerPatch : IHarmonyPatch { /********* ** Accessors *********/ /// A unique name for this patch. public string Name => $"{nameof(LidgrenServerPatch)}"; /********* ** Public methods *********/ /// Apply the Harmony patch. /// The Harmony instance. public void Apply(HarmonyInstance harmony) { // override parseDataMessageFromClient { MethodInfo method = AccessTools.Method(typeof(LidgrenServer), "parseDataMessageFromClient"); MethodInfo prefix = AccessTools.Method(this.GetType(), nameof(LidgrenServerPatch.Prefix_LidgrenServer_ParseDataMessageFromClient)); harmony.Patch(method, new HarmonyMethod(prefix), null); } // override sendMessage { MethodInfo method = typeof(LidgrenServer).GetMethod("sendMessage", BindingFlags.NonPublic | BindingFlags.Instance, null, new [] { typeof(NetConnection), typeof(OutgoingMessage) }, null); MethodInfo prefix = AccessTools.Method(this.GetType(), nameof(LidgrenServerPatch.Prefix_LidgrenServer_SendMessage)); harmony.Patch(method, new HarmonyMethod(prefix), null); } } /********* ** Private methods *********/ /// The method to call instead of the method. /// The instance being patched. /// The raw network message to parse. /// The private peers field on the instance. /// The private gameServer field on the instance. /// Returns whether to execute the original method. /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")] private static bool Prefix_LidgrenServer_ParseDataMessageFromClient(LidgrenServer __instance, NetIncomingMessage dataMsg, Bimap ___peers, IGameServer ___gameServer) { if (__instance is SLidgrenServer smapiServer) { smapiServer.ParseDataMessageFromClient(dataMsg); return false; } return true; } /// The method to call instead of the method. /// The instance being patched. /// The connection to which to send the message. /// The private peers field on the instance. /// The private gameServer field on the instance. /// Returns whether to execute the original method. /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")] private static bool Prefix_LidgrenServer_SendMessage(LidgrenServer __instance, NetConnection connection, OutgoingMessage message, Bimap ___peers, IGameServer ___gameServer) { if (__instance is SLidgrenServer smapiServer) { smapiServer.SendMessage(connection, message); return false; } return true; } } }