summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/Events
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-11-03 01:29:01 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-11-03 01:29:01 -0400
commit02a46bf13f29ce0dd8ac2f422113083c59dae42d (patch)
tree134a670897ab4fb9b76485b022b19f0cb1167df3 /src/SMAPI/Framework/Events
parent6f23aaf2954f7eeb93b7cc5aad2d3f9b237883f3 (diff)
downloadSMAPI-02a46bf13f29ce0dd8ac2f422113083c59dae42d.tar.gz
SMAPI-02a46bf13f29ce0dd8ac2f422113083c59dae42d.tar.bz2
SMAPI-02a46bf13f29ce0dd8ac2f422113083c59dae42d.zip
add APIs to send/receive messages in multiplayer (#480)
Diffstat (limited to 'src/SMAPI/Framework/Events')
-rw-r--r--src/SMAPI/Framework/Events/EventManager.cs8
-rw-r--r--src/SMAPI/Framework/Events/ManagedEvent.cs24
-rw-r--r--src/SMAPI/Framework/Events/ManagedEventBase.cs12
-rw-r--r--src/SMAPI/Framework/Events/ModEvents.cs4
-rw-r--r--src/SMAPI/Framework/Events/ModMultiplayerEvents.cs29
5 files changed, 76 insertions, 1 deletions
diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs
index 31b0346a..519cf48a 100644
--- a/src/SMAPI/Framework/Events/EventManager.cs
+++ b/src/SMAPI/Framework/Events/EventManager.cs
@@ -99,6 +99,12 @@ namespace StardewModdingAPI.Framework.Events
public readonly ManagedEvent<MouseWheelScrolledEventArgs> MouseWheelScrolled;
/****
+ ** Multiplayer
+ ****/
+ /// <summary>Raised after a mod message is received over the network.</summary>
+ public readonly ManagedEvent<ModMessageReceivedEventArgs> ModMessageReceived;
+
+ /****
** Player
****/
/// <summary>Raised after items are added or removed to a player's inventory.</summary>
@@ -374,6 +380,8 @@ namespace StardewModdingAPI.Framework.Events
this.CursorMoved = ManageEventOf<CursorMovedEventArgs>(nameof(IModEvents.Input), nameof(IInputEvents.CursorMoved));
this.MouseWheelScrolled = ManageEventOf<MouseWheelScrolledEventArgs>(nameof(IModEvents.Input), nameof(IInputEvents.MouseWheelScrolled));
+ this.ModMessageReceived = ManageEventOf<ModMessageReceivedEventArgs>(nameof(IModEvents.Multiplayer), nameof(IMultiplayerEvents.ModMessageReceived));
+
this.InventoryChanged = ManageEventOf<InventoryChangedEventArgs>(nameof(IModEvents.Player), nameof(IPlayerEvents.InventoryChanged));
this.LevelChanged = ManageEventOf<LevelChangedEventArgs>(nameof(IModEvents.Player), nameof(IPlayerEvents.LevelChanged));
this.Warped = ManageEventOf<WarpedEventArgs>(nameof(IModEvents.Player), nameof(IPlayerEvents.Warped));
diff --git a/src/SMAPI/Framework/Events/ManagedEvent.cs b/src/SMAPI/Framework/Events/ManagedEvent.cs
index c1ebf6c7..65f6e38e 100644
--- a/src/SMAPI/Framework/Events/ManagedEvent.cs
+++ b/src/SMAPI/Framework/Events/ManagedEvent.cs
@@ -67,6 +67,30 @@ namespace StardewModdingAPI.Framework.Events
}
}
}
+
+ /// <summary>Raise the event and notify all handlers.</summary>
+ /// <param name="args">The event arguments to pass.</param>
+ /// <param name="match">A lambda which returns true if the event should be raised for the given mod.</param>
+ public void RaiseForMods(TEventArgs args, Func<IModMetadata, bool> match)
+ {
+ if (this.Event == null)
+ return;
+
+ foreach (EventHandler<TEventArgs> handler in this.CachedInvocationList)
+ {
+ if (match(this.GetSourceMod(handler)))
+ {
+ try
+ {
+ handler.Invoke(null, args);
+ }
+ catch (Exception ex)
+ {
+ this.LogError(handler, ex);
+ }
+ }
+ }
+ }
}
/// <summary>An event wrapper which intercepts and logs errors in handler code.</summary>
diff --git a/src/SMAPI/Framework/Events/ManagedEventBase.cs b/src/SMAPI/Framework/Events/ManagedEventBase.cs
index f3a278dc..defd903a 100644
--- a/src/SMAPI/Framework/Events/ManagedEventBase.cs
+++ b/src/SMAPI/Framework/Events/ManagedEventBase.cs
@@ -69,12 +69,22 @@ namespace StardewModdingAPI.Framework.Events
this.SourceMods.Remove(handler);
}
+ /// <summary>Get the mod which registered the given event handler, if available.</summary>
+ /// <param name="handler">The event handler.</param>
+ protected IModMetadata GetSourceMod(TEventHandler handler)
+ {
+ return this.SourceMods.TryGetValue(handler, out IModMetadata mod)
+ ? mod
+ : null;
+ }
+
/// <summary>Log an exception from an event handler.</summary>
/// <param name="handler">The event handler instance.</param>
/// <param name="ex">The exception that was raised.</param>
protected void LogError(TEventHandler handler, Exception ex)
{
- if (this.SourceMods.TryGetValue(handler, out IModMetadata mod))
+ IModMetadata mod = this.GetSourceMod(handler);
+ if (mod != null)
mod.LogAsMod($"This mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error);
else
this.Monitor.Log($"A mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error);
diff --git a/src/SMAPI/Framework/Events/ModEvents.cs b/src/SMAPI/Framework/Events/ModEvents.cs
index 7a318e8b..8ad3936c 100644
--- a/src/SMAPI/Framework/Events/ModEvents.cs
+++ b/src/SMAPI/Framework/Events/ModEvents.cs
@@ -17,6 +17,9 @@ namespace StardewModdingAPI.Framework.Events
/// <summary>Events raised when the player provides input using a controller, keyboard, or mouse.</summary>
public IInputEvents Input { get; }
+ /// <summary>Events raised for multiplayer messages and connections.</summary>
+ public IMultiplayerEvents Multiplayer { get; }
+
/// <summary>Events raised when the player data changes.</summary>
public IPlayerEvents Player { get; }
@@ -38,6 +41,7 @@ namespace StardewModdingAPI.Framework.Events
this.Display = new ModDisplayEvents(mod, eventManager);
this.GameLoop = new ModGameLoopEvents(mod, eventManager);
this.Input = new ModInputEvents(mod, eventManager);
+ this.Multiplayer = new ModMultiplayerEvents(mod, eventManager);
this.Player = new ModPlayerEvents(mod, eventManager);
this.World = new ModWorldEvents(mod, eventManager);
this.Specialised = new ModSpecialisedEvents(mod, eventManager);
diff --git a/src/SMAPI/Framework/Events/ModMultiplayerEvents.cs b/src/SMAPI/Framework/Events/ModMultiplayerEvents.cs
new file mode 100644
index 00000000..a830a54a
--- /dev/null
+++ b/src/SMAPI/Framework/Events/ModMultiplayerEvents.cs
@@ -0,0 +1,29 @@
+using System;
+using StardewModdingAPI.Events;
+
+namespace StardewModdingAPI.Framework.Events
+{
+ /// <summary>Events raised for multiplayer messages and connections.</summary>
+ internal class ModMultiplayerEvents : ModEventsBase, IMultiplayerEvents
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>Raised after a mod message is received over the network.</summary>
+ public event EventHandler<ModMessageReceivedEventArgs> ModMessageReceived
+ {
+ add => this.EventManager.ModMessageReceived.Add(value);
+ remove => this.EventManager.ModMessageReceived.Remove(value);
+ }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="mod">The mod which uses this instance.</param>
+ /// <param name="eventManager">The underlying event manager.</param>
+ internal ModMultiplayerEvents(IModMetadata mod, EventManager eventManager)
+ : base(mod, eventManager) { }
+ }
+}