diff --git a/Piston/Piston.csproj b/Piston/Piston.csproj
index 1ec8ac5..cece99f 100644
--- a/Piston/Piston.csproj
+++ b/Piston/Piston.csproj
@@ -114,6 +114,7 @@
+
diff --git a/PistonAPI/IEnvironmentInfo.cs b/PistonAPI/IEnvironmentInfo.cs
new file mode 100644
index 0000000..4a227fa
--- /dev/null
+++ b/PistonAPI/IEnvironmentInfo.cs
@@ -0,0 +1,13 @@
+namespace PistonAPI
+{
+ public interface IEnvironmentInfo
+ {
+ EnvironmentType Type { get; }
+ }
+
+ public enum EnvironmentType
+ {
+ DedicatedServer,
+ GameClient
+ }
+}
\ No newline at end of file
diff --git a/PistonAPI/IServerControls.cs b/PistonAPI/IServerControls.cs
new file mode 100644
index 0000000..a07ae50
--- /dev/null
+++ b/PistonAPI/IServerControls.cs
@@ -0,0 +1,10 @@
+using System.Windows.Controls;
+
+namespace PistonAPI
+{
+ public interface IServerControls
+ {
+ bool AddGUITab(string name, UserControl control);
+ bool RemoveGUITab(string name);
+ }
+}
\ No newline at end of file
diff --git a/PistonAPI/PistonAPI.cs b/PistonAPI/PistonAPI.cs
index d25bed9..4d558f8 100644
--- a/PistonAPI/PistonAPI.cs
+++ b/PistonAPI/PistonAPI.cs
@@ -3,11 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows.Controls;
namespace PistonAPI
{
public static class PistonAPI
{
-
+ public static IServerControls ServerControls { get; }
+ public static IEnvironmentInfo EnvironmentInfo { get; }
}
}
diff --git a/PistonAPI/PistonAPI.csproj b/PistonAPI/PistonAPI.csproj
index 3b74a12..f43e935 100644
--- a/PistonAPI/PistonAPI.csproj
+++ b/PistonAPI/PistonAPI.csproj
@@ -49,6 +49,8 @@
MinimumRecommendedRules.ruleset
+
+
@@ -62,7 +64,9 @@
+
+
diff --git a/PistonServer/ChatControl.xaml.cs b/PistonServer/ChatControl.xaml.cs
index 2942407..f8434a8 100644
--- a/PistonServer/ChatControl.xaml.cs
+++ b/PistonServer/ChatControl.xaml.cs
@@ -17,6 +17,7 @@ using Piston;
using Sandbox;
using Sandbox.Engine.Multiplayer;
using Sandbox.Game.World;
+using SteamSDK;
namespace PistonServer
{
@@ -29,34 +30,45 @@ namespace PistonServer
public ChatControl()
{
InitializeComponent();
+ ServerManager.Static.SessionReady += InitChatHandler;
}
- public void MessageReceived(ulong steamId, string message, SteamSDK.ChatEntryTypeEnum chatType)
+ public void InitChatHandler()
+ {
+ MyMultiplayer.Static.ChatMessageReceived += MessageReceived;
+ }
+
+ public void MessageReceived(ulong steamId, string message, ChatEntryTypeEnum chatType)
{
//Messages sent from server loop back around.
if (steamId == MyMultiplayer.Static.ServerId)
return;
- var name = MySession.Static.Players.TryGetPlayerBySteamId(steamId)?.DisplayName ?? "";
+ var name = MyMultiplayer.Static.GetMemberName(steamId);
Dispatcher.Invoke(() => AddMessage(name, message), DispatcherPriority.Normal);
}
public void AddMessage(string sender, string message)
{
Chat.Text += $"{DateTime.Now.ToLongTimeString()} | {sender}: {message}\n";
+ Program.UserInterface.Players.RefreshNames();
+ }
+
+ public void SendMessage(string message)
+ {
+ MyMultiplayer.Static.SendChatMessage(message);
+ Dispatcher.Invoke(() => AddMessage("Server", message));
}
private void SendButton_Click(object sender, RoutedEventArgs e)
{
OnMessageEntered();
-
}
private void OnMessageEntered()
{
var text = Message.Text;
- AddMessage("Server", text);
- MySandboxGame.Static.Invoke(() => MyMultiplayer.Static.SendChatMessage(text));
+ SendMessage(text);
MessageEntered?.Invoke(Message.Text);
Message.Text = "";
}
diff --git a/PistonServer/MainWindow.xaml b/PistonServer/MainWindow.xaml
index b5b0f73..69e6342 100644
--- a/PistonServer/MainWindow.xaml
+++ b/PistonServer/MainWindow.xaml
@@ -19,7 +19,7 @@
-
+
diff --git a/PistonServer/MainWindow.xaml.cs b/PistonServer/MainWindow.xaml.cs
index 4e521b6..c204c8b 100644
--- a/PistonServer/MainWindow.xaml.cs
+++ b/PistonServer/MainWindow.xaml.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -73,5 +74,10 @@ namespace PistonServer
uiUpdate.Stop();
ServerManager.Static.StopServer();
}
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ ServerManager.Static.StopServer();
+ }
}
}
diff --git a/PistonServer/PlayersControl.xaml b/PistonServer/PlayersControl.xaml
index 31843bd..c6453f9 100644
--- a/PistonServer/PlayersControl.xaml
+++ b/PistonServer/PlayersControl.xaml
@@ -7,8 +7,8 @@
mc:Ignorable="d">
-
-
+
+
diff --git a/PistonServer/PlayersControl.xaml.cs b/PistonServer/PlayersControl.xaml.cs
index f6750bd..8cd80d2 100644
--- a/PistonServer/PlayersControl.xaml.cs
+++ b/PistonServer/PlayersControl.xaml.cs
@@ -12,6 +12,12 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
+using Piston;
+using Sandbox;
+using Sandbox.Engine.Multiplayer;
+using Sandbox.Game.Multiplayer;
+using Sandbox.Game.World;
+using SteamSDK;
namespace PistonServer
{
@@ -23,6 +29,86 @@ namespace PistonServer
public PlayersControl()
{
InitializeComponent();
+ ServerManager.Static.SessionReady += Static_SessionReady;
+ }
+
+ public void RefreshNames()
+ {
+ Dispatcher.Invoke(() =>
+ {
+ foreach (var player in PlayerList.Items)
+ {
+ var p = (PlayerItem)player;
+ p.Name = MyMultiplayer.Static.GetMemberName(p.SteamId);
+ }
+
+ PlayerList.Items.Refresh();
+ });
+ }
+
+ private void Static_SessionReady()
+ {
+ MyMultiplayer.Static.ClientKicked += OnClientKicked;
+ MyMultiplayer.Static.ClientLeft += OnClientLeft;
+ MySession.Static.Players.PlayerRequesting += OnPlayerRequesting;
+ }
+
+ ///
+ /// Invoked when a client logs in and hits the respawn screen.
+ ///
+ private void OnPlayerRequesting(PlayerRequestArgs args)
+ {
+ var steamId = args.PlayerId.SteamId;
+ var player = new PlayerItem { Name = MyMultiplayer.Static.GetMemberName(steamId), SteamId = steamId };
+ Program.UserInterface.Chat.SendMessage($"{player.Name} connected.");
+ Dispatcher.Invoke(() => PlayerList.Items.Add(player));
+ }
+ private void OnClientKicked(ulong steamId)
+ {
+ OnClientLeft(steamId, ChatMemberStateChangeEnum.Kicked);
+ }
+
+ private void OnClientLeft(ulong steamId, ChatMemberStateChangeEnum stateChange)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ var player = PlayerList.Items.Cast().FirstOrDefault(x => x.SteamId == steamId);
+
+ if (player == null)
+ return;
+
+ Program.UserInterface.Chat.SendMessage($"{player.Name} {stateChange.ToString().ToLower()}.");
+ PlayerList.Items.Remove(player);
+ });
+ }
+
+ public class PlayerItem
+ {
+ public ulong SteamId;
+ public string Name;
+
+ public override string ToString()
+ {
+ return $"{Name} ({SteamId})";
+ }
+ }
+
+ private void KickButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (PlayerList.SelectedItem == null)
+ return;
+
+ var player = (PlayerItem)PlayerList.SelectedItem;
+ MyMultiplayer.Static.KickClient(player.SteamId);
+ }
+
+ private void BanButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (PlayerList.SelectedItem == null)
+ return;
+
+ var player = (PlayerItem)PlayerList.SelectedItem;
+ MyMultiplayer.Static.BanClient(player.SteamId, true);
}
}
}
diff --git a/PistonServer/ServerManager.cs b/PistonServer/ServerManager.cs
index 005e8d8..35b3b1d 100644
--- a/PistonServer/ServerManager.cs
+++ b/PistonServer/ServerManager.cs
@@ -21,6 +21,9 @@ namespace PistonServer
public Thread ServerThread { get; private set; }
public string[] RunArgs { get; set; } = new string[0];
+ public event Action SessionLoading;
+ public event Action SessionReady;
+
private readonly Assembly _dsAssembly;
private ServerManager()
@@ -38,12 +41,13 @@ namespace PistonServer
private void OnSessionLoading()
{
+ SessionLoading?.Invoke();
MySession.Static.OnReady += OnSessionReady;
}
private void OnSessionReady()
{
- MyMultiplayer.Static.ChatMessageReceived += Program.UserInterface.Chat.MessageReceived;
+ SessionReady?.Invoke();
}
///