From b4a5b3829f0f738e5b7e05048068eaec9d2d01d1 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 4 Nov 2018 23:07:10 -0500 Subject: add PeerDisconnected event (#480) --- src/SMAPI/Events/ContextReceivedEventArgs.cs | 25 --------------------- src/SMAPI/Events/IMultiplayerEvents.cs | 7 ++++-- src/SMAPI/Events/PeerContextReceivedEventArgs.cs | 25 +++++++++++++++++++++ src/SMAPI/Events/PeerDisconnectedEventArgs.cs | 25 +++++++++++++++++++++ src/SMAPI/Framework/Events/EventManager.cs | 10 ++++++--- src/SMAPI/Framework/Events/ModMultiplayerEvents.cs | 15 +++++++++---- src/SMAPI/Framework/SMultiplayer.cs | 26 ++++++++++++++++------ src/SMAPI/StardewModdingAPI.csproj | 3 ++- 8 files changed, 94 insertions(+), 42 deletions(-) delete mode 100644 src/SMAPI/Events/ContextReceivedEventArgs.cs create mode 100644 src/SMAPI/Events/PeerContextReceivedEventArgs.cs create mode 100644 src/SMAPI/Events/PeerDisconnectedEventArgs.cs (limited to 'src') diff --git a/src/SMAPI/Events/ContextReceivedEventArgs.cs b/src/SMAPI/Events/ContextReceivedEventArgs.cs deleted file mode 100644 index c715cf1c..00000000 --- a/src/SMAPI/Events/ContextReceivedEventArgs.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -namespace StardewModdingAPI.Events -{ - /// Event arguments for an event. - public class ContextReceivedEventArgs : EventArgs - { - /********* - ** Accessors - *********/ - /// The player whose metadata was received. - public IMultiplayerPeer Peer { get; } - - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The player to whom a connection is being established. - internal ContextReceivedEventArgs(IMultiplayerPeer peer) - { - this.Peer = peer; - } - } -} diff --git a/src/SMAPI/Events/IMultiplayerEvents.cs b/src/SMAPI/Events/IMultiplayerEvents.cs index 91e0789c..4a31f48e 100644 --- a/src/SMAPI/Events/IMultiplayerEvents.cs +++ b/src/SMAPI/Events/IMultiplayerEvents.cs @@ -5,10 +5,13 @@ namespace StardewModdingAPI.Events /// Events raised for multiplayer messages and connections. public interface IMultiplayerEvents { - /// Raised after the mod context for a player is received. This happens before the game approves the connection, so the player does not yet exist in the game. This is the earliest point where messages can be sent to the player via SMAPI. - event EventHandler ContextReceived; + /// Raised after the mod context for a peer is received. This happens before the game approves the connection, so the player doesn't yet exist in the game. This is the earliest point where messages can be sent to the peer via SMAPI. + event EventHandler PeerContextReceived; /// Raised after a mod message is received over the network. event EventHandler ModMessageReceived; + + /// Raised after the connection with a peer is severed. + event EventHandler PeerDisconnected; } } diff --git a/src/SMAPI/Events/PeerContextReceivedEventArgs.cs b/src/SMAPI/Events/PeerContextReceivedEventArgs.cs new file mode 100644 index 00000000..151a295c --- /dev/null +++ b/src/SMAPI/Events/PeerContextReceivedEventArgs.cs @@ -0,0 +1,25 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// Event arguments for an event. + public class PeerContextReceivedEventArgs : EventArgs + { + /********* + ** Accessors + *********/ + /// The peer whose metadata was received. + public IMultiplayerPeer Peer { get; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The peer whose metadata was received. + internal PeerContextReceivedEventArgs(IMultiplayerPeer peer) + { + this.Peer = peer; + } + } +} diff --git a/src/SMAPI/Events/PeerDisconnectedEventArgs.cs b/src/SMAPI/Events/PeerDisconnectedEventArgs.cs new file mode 100644 index 00000000..8517988a --- /dev/null +++ b/src/SMAPI/Events/PeerDisconnectedEventArgs.cs @@ -0,0 +1,25 @@ +using System; + +namespace StardewModdingAPI.Events +{ + /// Event arguments for an event. + public class PeerDisconnectedEventArgs : EventArgs + { + /********* + ** Accessors + *********/ + /// The peer who disconnected. + public IMultiplayerPeer Peer { get; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The peer who disconnected. + internal PeerDisconnectedEventArgs(IMultiplayerPeer peer) + { + this.Peer = peer; + } + } +} diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs index 63ac17ee..b9d1c453 100644 --- a/src/SMAPI/Framework/Events/EventManager.cs +++ b/src/SMAPI/Framework/Events/EventManager.cs @@ -101,12 +101,15 @@ namespace StardewModdingAPI.Framework.Events /**** ** Multiplayer ****/ - /// Raised after the mod context for a player is received. This happens before the game approves the connection, so the player does not yet exist in the game. This is the earliest point where messages can be sent to the player via SMAPI. - public readonly ManagedEvent ContextReceived; + /// Raised after the mod context for a peer is received. This happens before the game approves the connection, so the player doesn't yet exist in the game. This is the earliest point where messages can be sent to the peer via SMAPI. + public readonly ManagedEvent PeerContextReceived; /// Raised after a mod message is received over the network. public readonly ManagedEvent ModMessageReceived; + /// Raised after the connection with a peer is severed. + public readonly ManagedEvent PeerDisconnected; + /**** ** Player ****/ @@ -383,8 +386,9 @@ namespace StardewModdingAPI.Framework.Events this.CursorMoved = ManageEventOf(nameof(IModEvents.Input), nameof(IInputEvents.CursorMoved)); this.MouseWheelScrolled = ManageEventOf(nameof(IModEvents.Input), nameof(IInputEvents.MouseWheelScrolled)); - this.ContextReceived = ManageEventOf(nameof(IModEvents.Multiplayer), nameof(IMultiplayerEvents.ContextReceived)); + this.PeerContextReceived = ManageEventOf(nameof(IModEvents.Multiplayer), nameof(IMultiplayerEvents.PeerContextReceived)); this.ModMessageReceived = ManageEventOf(nameof(IModEvents.Multiplayer), nameof(IMultiplayerEvents.ModMessageReceived)); + this.PeerDisconnected = ManageEventOf(nameof(IModEvents.Multiplayer), nameof(IMultiplayerEvents.PeerDisconnected)); this.InventoryChanged = ManageEventOf(nameof(IModEvents.Player), nameof(IPlayerEvents.InventoryChanged)); this.LevelChanged = ManageEventOf(nameof(IModEvents.Player), nameof(IPlayerEvents.LevelChanged)); diff --git a/src/SMAPI/Framework/Events/ModMultiplayerEvents.cs b/src/SMAPI/Framework/Events/ModMultiplayerEvents.cs index 432a92d3..152c4e0c 100644 --- a/src/SMAPI/Framework/Events/ModMultiplayerEvents.cs +++ b/src/SMAPI/Framework/Events/ModMultiplayerEvents.cs @@ -9,6 +9,13 @@ namespace StardewModdingAPI.Framework.Events /********* ** Accessors *********/ + /// Raised after the mod context for a peer is received. This happens before the game approves the connection, so the player doesn't yet exist in the game. This is the earliest point where messages can be sent to the peer via SMAPI. + public event EventHandler PeerContextReceived + { + add => this.EventManager.PeerContextReceived.Add(value); + remove => this.EventManager.PeerContextReceived.Remove(value); + } + /// Raised after a mod message is received over the network. public event EventHandler ModMessageReceived { @@ -16,11 +23,11 @@ namespace StardewModdingAPI.Framework.Events remove => this.EventManager.ModMessageReceived.Remove(value); } - /// Raised after the mod context for a player is received. This happens before the game approves the connection, so the player does not yet exist in the game. This is the earliest point where messages can be sent to the player via SMAPI. - public event EventHandler ContextReceived + /// Raised after the connection with a peer is severed. + public event EventHandler PeerDisconnected { - add => this.EventManager.ContextReceived.Add(value); - remove => this.EventManager.ContextReceived.Remove(value); + add => this.EventManager.PeerDisconnected.Add(value); + remove => this.EventManager.PeerDisconnected.Remove(value); } diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs index 9f649639..2d0f8b9b 100644 --- a/src/SMAPI/Framework/SMultiplayer.cs +++ b/src/SMAPI/Framework/SMultiplayer.cs @@ -140,6 +140,9 @@ namespace StardewModdingAPI.Framework /// Send the underlying message. protected void OnServerSendingMessage(SLidgrenServer server, NetConnection connection, OutgoingMessage message, Action resume) { + if (this.VerboseLogging) + this.Monitor.Log($"SERVER SEND {(MessageType)message.MessageType} {message.FarmerID}", LogLevel.Trace); + resume(); } @@ -149,6 +152,9 @@ namespace StardewModdingAPI.Framework /// Send the underlying message. protected void OnClientSendingMessage(SLidgrenClient client, OutgoingMessage message, Action resume) { + if (this.VerboseLogging) + this.Monitor.Log($"CLIENT SEND {(MessageType)message.MessageType} {message.FarmerID}", LogLevel.Trace); + switch (message.MessageType) { // sync mod context (step 1) @@ -171,6 +177,8 @@ namespace StardewModdingAPI.Framework /// Process the message using the game's default logic. public void OnServerProcessingMessage(SLidgrenServer server, NetIncomingMessage rawMessage, IncomingMessage message, Action resume) { + if (this.VerboseLogging) + this.Monitor.Log($"SERVER RECV {(MessageType)message.MessageType} {message.FarmerID}", LogLevel.Trace); switch (message.MessageType) { @@ -213,7 +221,7 @@ namespace StardewModdingAPI.Framework } // raise event - this.EventManager.ContextReceived.Raise(new ContextReceivedEventArgs(newPeer)); + this.EventManager.PeerContextReceived.Raise(new PeerContextReceivedEventArgs(newPeer)); } break; @@ -248,8 +256,8 @@ namespace StardewModdingAPI.Framework /// Returns whether the message was handled. public void OnClientProcessingMessage(SLidgrenClient client, IncomingMessage message, Action resume) { - if (message.MessageType != Multiplayer.farmerDelta && message.MessageType != Multiplayer.locationDelta && message.MessageType != Multiplayer.teamDelta && message.MessageType != Multiplayer.worldDelta) - this.Monitor.Log($"CLIENT RECV {(MessageType)message.MessageType} {message.FarmerID}", LogLevel.Alert); + if (this.VerboseLogging) + this.Monitor.Log($"CLIENT RECV {(MessageType)message.MessageType} {message.FarmerID}", LogLevel.Trace); switch (message.MessageType) { @@ -315,8 +323,12 @@ namespace StardewModdingAPI.Framework { foreach (long playerID in this.DisconnectingFarmers) { - this.Monitor.Log($"Player quit: {playerID}", LogLevel.Trace); - this.Peers.Remove(playerID); + if (this.Peers.TryGetValue(playerID, out MultiplayerPeer peer)) + { + this.Monitor.Log($"Player quit: {playerID}", LogLevel.Trace); + this.Peers.Remove(playerID); + this.EventManager.PeerDisconnected.Raise(new PeerDisconnectedEventArgs(peer)); + } } base.removeDisconnectedFarmers(); @@ -397,7 +409,7 @@ namespace StardewModdingAPI.Framework /// Save a received peer. /// The peer to add. /// Whether to track the peer as the host if applicable. - /// Whether to raise the event. + /// Whether to raise the event. private void AddPeer(MultiplayerPeer peer, bool canBeHost, bool raiseEvent = true) { // store @@ -407,7 +419,7 @@ namespace StardewModdingAPI.Framework // raise event if (raiseEvent) - this.EventManager.ContextReceived.Raise(new ContextReceivedEventArgs(peer)); + this.EventManager.PeerContextReceived.Raise(new PeerContextReceivedEventArgs(peer)); } /// Read the metadata context for a player. diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 09ecddcd..8c12c1f9 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -85,7 +85,6 @@ - @@ -137,6 +136,8 @@ + + -- cgit