From adda9611c73163270cbfcd34d6617560f81d54b0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Apr 2018 18:49:13 -0400 Subject: add multiplayer sync events (#479) --- src/SMAPI/Events/MultiplayerEvents.cs | 58 ++++++++++++++++++++++++++++++ src/SMAPI/Framework/Events/EventManager.cs | 20 +++++++++++ src/SMAPI/Framework/SGame.cs | 1 + src/SMAPI/Framework/SMultiplayer.cs | 47 ++++++++++++++++++++++++ src/SMAPI/Program.cs | 1 + src/SMAPI/StardewModdingAPI.csproj | 2 ++ 6 files changed, 129 insertions(+) create mode 100644 src/SMAPI/Events/MultiplayerEvents.cs create mode 100644 src/SMAPI/Framework/SMultiplayer.cs (limited to 'src') diff --git a/src/SMAPI/Events/MultiplayerEvents.cs b/src/SMAPI/Events/MultiplayerEvents.cs new file mode 100644 index 00000000..f96ecba5 --- /dev/null +++ b/src/SMAPI/Events/MultiplayerEvents.cs @@ -0,0 +1,58 @@ +using System; +using StardewModdingAPI.Framework.Events; + +namespace StardewModdingAPI.Events +{ + /// Events raised during the multiplayer sync process. + public static class MultiplayerEvents + { + /********* + ** Properties + *********/ + /// The core event manager. + private static EventManager EventManager; + + + /********* + ** Events + *********/ + /// Raised before the game syncs changes from other players. + public static event EventHandler BeforeMainSync + { + add => MultiplayerEvents.EventManager.Multiplayer_BeforeMainSync.Add(value); + remove => MultiplayerEvents.EventManager.Multiplayer_BeforeMainSync.Remove(value); + } + + /// Raised after the game syncs changes from other players. + public static event EventHandler AfterMainSync + { + add => MultiplayerEvents.EventManager.Multiplayer_AfterMainSync.Add(value); + remove => MultiplayerEvents.EventManager.Multiplayer_AfterMainSync.Remove(value); + } + + /// Raised before the game broadcasts changes to other players. + public static event EventHandler BeforeMainBroadcast + { + add => MultiplayerEvents.EventManager.Multiplayer_BeforeMainBroadcast.Add(value); + remove => MultiplayerEvents.EventManager.Multiplayer_BeforeMainBroadcast.Remove(value); + } + + /// Raised after the game broadcasts changes to other players. + public static event EventHandler AfterMainBroadcast + { + add => MultiplayerEvents.EventManager.Multiplayer_AfterMainBroadcast.Add(value); + remove => MultiplayerEvents.EventManager.Multiplayer_AfterMainBroadcast.Remove(value); + } + + + /********* + ** Public methods + *********/ + /// Initialise the events. + /// The core event manager. + internal static void Init(EventManager eventManager) + { + MultiplayerEvents.EventManager = eventManager; + } + } +} diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs index d7c89a76..87ff760f 100644 --- a/src/SMAPI/Framework/Events/EventManager.cs +++ b/src/SMAPI/Framework/Events/EventManager.cs @@ -125,6 +125,21 @@ namespace StardewModdingAPI.Framework.Events /// Raised after a game menu is closed. public readonly ManagedEvent Menu_Closed; + /**** + ** MultiplayerEvents + ****/ + /// Raised before the game syncs changes from other players. + public readonly ManagedEvent Multiplayer_BeforeMainSync; + + /// Raised after the game syncs changes from other players. + public readonly ManagedEvent Multiplayer_AfterMainSync; + + /// Raised before the game broadcasts changes to other players. + public readonly ManagedEvent Multiplayer_BeforeMainBroadcast; + + /// Raised after the game broadcasts changes to other players. + public readonly ManagedEvent Multiplayer_AfterMainBroadcast; + /**** ** MineEvents ****/ @@ -228,6 +243,11 @@ namespace StardewModdingAPI.Framework.Events this.Menu_Changed = ManageEventOf(nameof(MenuEvents), nameof(MenuEvents.MenuChanged)); this.Menu_Closed = ManageEventOf(nameof(MenuEvents), nameof(MenuEvents.MenuClosed)); + this.Multiplayer_BeforeMainBroadcast = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.BeforeMainBroadcast)); + this.Multiplayer_AfterMainBroadcast = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.AfterMainBroadcast)); + this.Multiplayer_BeforeMainSync = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.BeforeMainSync)); + this.Multiplayer_AfterMainSync = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.AfterMainSync)); + this.Mine_LevelChanged = ManageEventOf(nameof(MineEvents), nameof(MineEvents.MineLevelChanged)); this.Player_InventoryChanged = ManageEventOf(nameof(PlayerEvents), nameof(PlayerEvents.InventoryChanged)); diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index 7ea83957..89bf18ef 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -155,6 +155,7 @@ namespace StardewModdingAPI.Framework if (this.ContentCore == null) // shouldn't happen since CreateContentManager is called first, but let's init here just in case this.ContentCore = new ContentCore(this.Content.ServiceProvider, this.Content.RootDirectory, Thread.CurrentThread.CurrentUICulture, this.Monitor, reflection); Game1.input = new SInputState(); + Game1.multiplayer = new SMultiplayer(monitor, eventManager); // init watchers Game1.locations = new ObservableCollection(); diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs new file mode 100644 index 00000000..687b1922 --- /dev/null +++ b/src/SMAPI/Framework/SMultiplayer.cs @@ -0,0 +1,47 @@ +using StardewModdingAPI.Framework.Events; +using StardewValley; + +namespace StardewModdingAPI.Framework +{ + /// SMAPI's implementation of the game's core multiplayer logic. + internal class SMultiplayer : Multiplayer + { + /********* + ** Properties + *********/ + /// Encapsulates monitoring and logging. + private readonly IMonitor Monitor; + + /// Manages SMAPI events. + private readonly EventManager EventManager; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// Encapsulates monitoring and logging. + /// Manages SMAPI events. + public SMultiplayer(IMonitor monitor, EventManager eventManager) + { + this.Monitor = monitor; + this.EventManager = eventManager; + } + + /// Handle sync messages from other players and perform other initial sync logic. + public override void UpdateEarly() + { + this.EventManager.Multiplayer_BeforeMainSync.Raise(); + base.UpdateEarly(); + this.EventManager.Multiplayer_AfterMainSync.Raise(); + } + + /// Broadcast sync messages to other players and perform other final sync logic. + public override void UpdateLate(bool forceSync = false) + { + this.EventManager.Multiplayer_BeforeMainBroadcast.Raise(); + base.UpdateLate(forceSync); + this.EventManager.Multiplayer_AfterMainBroadcast.Raise(); + } + } +} diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index dc9e5308..2325e79a 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -157,6 +157,7 @@ namespace StardewModdingAPI LocationEvents.Init(this.EventManager); MenuEvents.Init(this.EventManager); MineEvents.Init(this.EventManager); + MultiplayerEvents.Init(this.EventManager); PlayerEvents.Init(this.EventManager); SaveEvents.Init(this.EventManager); SpecialisedEvents.Init(this.EventManager); diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 560d7bf4..f6a16e5f 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -85,6 +85,7 @@ Properties\GlobalAssemblyInfo.cs + @@ -132,6 +133,7 @@ + -- cgit