From 77a7a0fe58186e49e24c41f47a2a33661afbc81c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 14 Nov 2018 00:35:36 -0500 Subject: rework multiplayer code to allow for upcoming Galaxy client overrides (#480) --- src/SMAPI/Framework/Networking/SLidgrenClient.cs | 19 ++++++------- src/SMAPI/Framework/SMultiplayer.cs | 34 +++++++++++++----------- 2 files changed, 29 insertions(+), 24 deletions(-) (limited to 'src/SMAPI/Framework') diff --git a/src/SMAPI/Framework/Networking/SLidgrenClient.cs b/src/SMAPI/Framework/Networking/SLidgrenClient.cs index c05e6b76..02d9d68f 100644 --- a/src/SMAPI/Framework/Networking/SLidgrenClient.cs +++ b/src/SMAPI/Framework/Networking/SLidgrenClient.cs @@ -9,20 +9,21 @@ namespace StardewModdingAPI.Framework.Networking /********* ** Properties *********/ - /// A callback to raise when receiving a message. This receives the client instance, incoming message, and a callback to run the default logic. - private readonly Action OnProcessingMessage; + /// A callback to raise when receiving a message. This receives the incoming message, a method to send an arbitrary message, and a callback to run the default logic. + private readonly Action, Action> OnProcessingMessage; + + /// A callback to raise when sending a message. This receives the outgoing message, a method to send an arbitrary message, and a callback to resume the default logic. + private readonly Action, Action> OnSendingMessage; - /// A callback to raise when sending a message. This receives the client instance, outgoing message, and a callback to run the default logic. - private readonly Action OnSendingMessage; /********* ** Public methods *********/ /// Construct an instance. /// The remote address being connected. - /// A callback to raise when receiving a message. This receives the client instance, incoming message, and a callback to run the default logic. - /// A callback to raise when sending a message. This receives the client instance, outgoing message, and a callback to run the default logic. - public SLidgrenClient(string address, Action onProcessingMessage, Action onSendingMessage) + /// A callback to raise when receiving a message. This receives the incoming message, a method to send an arbitrary message, and a callback to run the default logic. + /// A callback to raise when sending a message. This receives the outgoing message, a method to send an arbitrary message, and a callback to resume the default logic. + public SLidgrenClient(string address, Action, Action> onProcessingMessage, Action, Action> onSendingMessage) : base(address) { this.OnProcessingMessage = onProcessingMessage; @@ -32,7 +33,7 @@ namespace StardewModdingAPI.Framework.Networking /// Send a message to the connected peer. public override void sendMessage(OutgoingMessage message) { - this.OnSendingMessage(this, message, () => base.sendMessage(message)); + this.OnSendingMessage(message, base.sendMessage, () => base.sendMessage(message)); } @@ -43,7 +44,7 @@ namespace StardewModdingAPI.Framework.Networking /// The message to process. protected override void processIncomingMessage(IncomingMessage message) { - this.OnProcessingMessage(this, message, () => base.processIncomingMessage(message)); + this.OnProcessingMessage(message, base.sendMessage, () => base.processIncomingMessage(message)); } } } diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs index 843cd1fb..6ce7596d 100644 --- a/src/SMAPI/Framework/SMultiplayer.cs +++ b/src/SMAPI/Framework/SMultiplayer.cs @@ -105,13 +105,17 @@ namespace StardewModdingAPI.Framework /// The client to initialise. public override Client InitClient(Client client) { - if (client is LidgrenClient) + switch (client) { - string address = this.Reflection.GetField(client, "address").GetValue(); - return new SLidgrenClient(address, this.OnClientProcessingMessage, this.OnClientSendingMessage); - } + case LidgrenClient _: + { + string address = this.Reflection.GetField(client, "address").GetValue(); + return new SLidgrenClient(address, this.OnClientProcessingMessage, this.OnClientSendingMessage); + } - return client; + default: + return client; + } } /// Initialise a server before the game connects to an incoming player. @@ -133,10 +137,10 @@ namespace StardewModdingAPI.Framework } /// A callback raised when sending a message as a farmhand. - /// The client sending the message. /// The message being sent. - /// Send the underlying message. - protected void OnClientSendingMessage(SLidgrenClient client, OutgoingMessage message, Action resume) + /// Send an arbitrary message through the client. + /// Resume sending the underlying message. + protected void OnClientSendingMessage(OutgoingMessage message, Action sendMessage, Action resume) { if (this.Monitor.IsVerbose) this.Monitor.Log($"CLIENT SEND {(MessageType)message.MessageType} {message.FarmerID}", LogLevel.Trace); @@ -145,7 +149,7 @@ namespace StardewModdingAPI.Framework { // sync mod context (step 1) case (byte)MessageType.PlayerIntroduction: - client.sendMessage((byte)MessageType.ModContext, this.GetContextSyncMessageFields()); + sendMessage(new OutgoingMessage((byte)MessageType.ModContext, Game1.player.UniqueMultiplayerID, this.GetContextSyncMessageFields())); resume(); break; @@ -235,11 +239,11 @@ namespace StardewModdingAPI.Framework } /// Process an incoming network message as a farmhand. - /// The client instance that received the connection. /// The message to process. - /// Process the message using the game's default logic. + /// Send an arbitrary message through the client. + /// Resume processing the message using the game's default logic. /// Returns whether the message was handled. - public void OnClientProcessingMessage(SLidgrenClient client, IncomingMessage message, Action resume) + public void OnClientProcessingMessage(IncomingMessage message, Action sendMessage, Action resume) { if (this.Monitor.IsVerbose) this.Monitor.Log($"CLIENT RECV {(MessageType)message.MessageType} {message.FarmerID}", LogLevel.Trace); @@ -254,7 +258,7 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Received context for {(model?.IsHost == true ? "host" : "farmhand")} {message.FarmerID} running {(model != null ? $"SMAPI {model.ApiVersion} with {model.Mods.Length} mods" : "vanilla")}.", LogLevel.Trace); // store peer - MultiplayerPeer peer = new MultiplayerPeer(message.FarmerID, model, client.sendMessage, isHost: model?.IsHost ?? this.HostPeer == null); + MultiplayerPeer peer = new MultiplayerPeer(message.FarmerID, model, sendMessage, isHost: model?.IsHost ?? this.HostPeer == null); if (peer.IsHost && this.HostPeer != null) { this.Monitor.Log($"Rejected mod context from host player {peer.PlayerID}: already received host data from {(peer.PlayerID == this.HostPeer.PlayerID ? "that player" : $"player {peer.PlayerID}")}.", LogLevel.Error); @@ -271,7 +275,7 @@ namespace StardewModdingAPI.Framework if (!this.Peers.ContainsKey(message.FarmerID) && this.HostPeer == null) { this.Monitor.Log($"Received connection for vanilla host {message.FarmerID}.", LogLevel.Trace); - this.AddPeer(new MultiplayerPeer(message.FarmerID, null, client.sendMessage, isHost: true), canBeHost: false); + this.AddPeer(new MultiplayerPeer(message.FarmerID, null, sendMessage, isHost: true), canBeHost: false); } resume(); break; @@ -283,7 +287,7 @@ namespace StardewModdingAPI.Framework // store peer if (!this.Peers.TryGetValue(message.FarmerID, out MultiplayerPeer peer)) { - peer = new MultiplayerPeer(message.FarmerID, null, client.sendMessage, isHost: this.HostPeer == null); + peer = new MultiplayerPeer(message.FarmerID, null, sendMessage, isHost: this.HostPeer == null); this.Monitor.Log($"Received connection for vanilla {(peer.IsHost ? "host" : "farmhand")} {message.FarmerID}.", LogLevel.Trace); this.AddPeer(peer, canBeHost: true); } -- cgit