using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Data; using System.Windows.Threading; using Piston; using Piston.Server.ViewModels; using Sandbox.Engine.Multiplayer; using Sandbox.Game.Multiplayer; using Sandbox.Game.World; using SteamSDK; using VRage.Library.Collections; namespace Piston.Server { /// /// Provides a proxy to the game's multiplayer-related functions. /// public class MultiplayerManager { public event Action PlayerJoined; public event Action PlayerLeft; public event Action ChatMessageReceived; public MTObservableCollection PlayersView { get; } = new MTObservableCollection(); public MTObservableCollection ChatView { get; } = new MTObservableCollection(); public PlayerInfo LocalPlayer { get; private set; } internal MultiplayerManager(ServerManager serverManager) { serverManager.SessionLoaded += OnSessionLoaded; } public void KickPlayer(ulong steamId) => MyMultiplayer.Static.KickClient(steamId); public void BanPlayer(ulong steamId, bool banned = true) => MyMultiplayer.Static.BanClient(steamId, banned); /// /// Send a message in chat. /// public void SendMessage(string message) { MyMultiplayer.Static.SendChatMessage(message); ChatView.Add(new ChatItemInfo(LocalPlayer, message)); } private void OnSessionLoaded() { LocalPlayer = new PlayerInfo(MyMultiplayer.Static.ServerId) { Name = "Server", State = ConnectionState.Connected }; MyMultiplayer.Static.ChatMessageReceived += OnChatMessage; MyMultiplayer.Static.ClientKicked += OnClientKicked; MyMultiplayer.Static.ClientLeft += OnClientLeft; MySession.Static.Players.PlayerRequesting += OnPlayerRequesting; } private void OnChatMessage(ulong steamId, string message, ChatEntryTypeEnum chatType) { var player = PlayersView.FirstOrDefault(p => p.SteamId == steamId); if (player == null || player == LocalPlayer) return; var info = new ChatItemInfo(player, message); ChatView.Add(info); ChatMessageReceived?.Invoke(info); } /// /// Invoked when a client logs in and hits the respawn screen. /// private void OnPlayerRequesting(PlayerRequestArgs args) { var steamId = args.PlayerId.SteamId; var player = new PlayerInfo(steamId) {State = ConnectionState.Connected}; PlayersView.Add(player); PlayerJoined?.Invoke(player); } private void OnClientKicked(ulong steamId) { OnClientLeft(steamId, ChatMemberStateChangeEnum.Kicked); } private void OnClientLeft(ulong steamId, ChatMemberStateChangeEnum stateChange) { var player = PlayersView.FirstOrDefault(p => p.SteamId == steamId); if (player == null) return; player.State = (ConnectionState)stateChange; PlayersView.Remove(player); PlayerLeft?.Invoke(player); } } }