using System; using System.Collections.Generic; using System.Linq; using StardewValley.Network; namespace StardewModdingAPI.Framework.Networking { /// Metadata about a connected player. internal class MultiplayerPeer : IMultiplayerPeer { /********* ** Fields *********/ /// A method which sends a message to the peer. private readonly Action SendMessageImpl; /********* ** Accessors *********/ /// The player's unique ID. public long PlayerID { get; } /// Whether this is a connection to the host player. public bool IsHost { get; } /// Whether the player has SMAPI installed. public bool HasSmapi => this.ApiVersion != null; /// The player's OS platform, if is true. public GamePlatform? Platform { get; } /// The installed version of Stardew Valley, if is true. public ISemanticVersion GameVersion { get; } /// The installed version of SMAPI, if is true. public ISemanticVersion ApiVersion { get; } /// The installed mods, if is true. public IEnumerable Mods { get; } /********* ** Public methods *********/ /// Construct an instance. /// The player's unique ID. /// The metadata to copy. /// A method which sends a message to the peer. /// Whether this is a connection to the host player. public MultiplayerPeer(long playerID, RemoteContextModel model, Action sendMessage, bool isHost) { this.PlayerID = playerID; this.IsHost = isHost; if (model != null) { this.Platform = model.Platform; this.GameVersion = model.GameVersion; this.ApiVersion = model.ApiVersion; this.Mods = model.Mods.Select(mod => new MultiplayerPeerMod(mod)).ToArray(); } this.SendMessageImpl = sendMessage; } /// Get metadata for a mod installed by the player. /// The unique mod ID. /// Returns the mod info, or null if the player doesn't have that mod. public IMultiplayerPeerMod GetMod(string id) { if (string.IsNullOrWhiteSpace(id) || this.Mods == null || !this.Mods.Any()) return null; id = id.Trim(); return this.Mods.FirstOrDefault(mod => mod.ID != null && mod.ID.Equals(id, StringComparison.InvariantCultureIgnoreCase)); } /// Send a message to the given peer, bypassing the game's normal validation to allow messages before the connection is approved. /// The message to send. public void SendMessage(OutgoingMessage message) { this.SendMessageImpl(message); } } }