106 lines
3.6 KiB
C#
106 lines
3.6 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Provides a proxy to the game's multiplayer-related functions.
|
|
/// </summary>
|
|
public class MultiplayerManager
|
|
{
|
|
public event Action<PlayerInfo> PlayerJoined;
|
|
public event Action<PlayerInfo> PlayerLeft;
|
|
public event Action<ChatItemInfo> ChatMessageReceived;
|
|
|
|
public MTObservableCollection<PlayerInfo> PlayersView { get; } = new MTObservableCollection<PlayerInfo>();
|
|
public MTObservableCollection<ChatItemInfo> ChatView { get; } = new MTObservableCollection<ChatItemInfo>();
|
|
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);
|
|
|
|
/// <summary>
|
|
/// Send a message in chat.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invoked when a client logs in and hits the respawn screen.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
}
|