Skip to content

Commit

Permalink
Merge pull request #13 from Jump-King-Multiplayer/feature/status-panel
Browse files Browse the repository at this point in the history
Implemented server status panel that shows total players in server and your group
  • Loading branch information
Skippeh authored Jan 16, 2022
2 parents 708e845 + 6fe0b9c commit 93da891
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 3 deletions.
4 changes: 4 additions & 0 deletions JKMP.Plugin.Multiplayer/Game/Entities/GameEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class GameEntity : BaseManagerEntity

private LocalPlayerListener plrListener = null!;
private Chat chatWidget = null!;
private StatusPanel statusPanel = null!;

private float timeSincePositionUpdate;
private const float PositionUpdateInterval = 30; // Send a position update every 30 seconds
Expand All @@ -43,6 +44,7 @@ protected override void OnFirstUpdate()
chatWidget = UIManager.AddWidget(new Chat());
localPlayer = EntityManager.instance.Find<PlayerEntity>();
localPlayer.AddComponents(new PlayerStateTransmitter(P2P), new AudioListenerComponent());
statusPanel = UIManager.AddWidget(new StatusPanel());

MatchmakingManager.Instance.Events.NearbyClientsReceived += OnNearbyClientsReceived;
}
Expand All @@ -55,6 +57,7 @@ protected override void OnDestroy()
plrListener.Dispose();
P2P.Dispose();
UIManager.RemoveWidget(chatWidget);
UIManager.RemoveWidget(statusPanel);
}

private void OnNearbyClientsReceived(ICollection<ulong> steamIds)
Expand All @@ -78,6 +81,7 @@ protected override void Update(float delta)
P2P.Update(delta);
Sound.Update(delta);
chatWidget.Update(delta);
statusPanel.Update(delta);
}
}
}
70 changes: 70 additions & 0 deletions JKMP.Plugin.Multiplayer/Game/UI/Widgets/StatusPanel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using JKMP.Plugin.Multiplayer.Matchmaking;
using JKMP.Plugin.Multiplayer.Networking;
using JumpKing.PauseMenu;
using Matchmaking.Client.EventData;
using Myra.Graphics2D.UI;

namespace JKMP.Plugin.Multiplayer.Game.UI.Widgets
{
public class StatusPanel : ResourceWidget<StatusPanel>
{
public string TotalPlayers
{
get => totalPlayers.Text;
set => totalPlayers.Text = value;
}

public string GroupPlayers
{
get => groupPlayers.Text;
set => groupPlayers.Text = value;
}

public bool Connected
{
get => connected;
set
{
if (value == connected)
return;

connected = value;

connectedContainer.Visible = connected;
disconnectedContainer.Visible = !connected;
}
}

private readonly Label totalPlayers;
private readonly Label groupPlayers;
private readonly Widget connectedContainer;
private readonly Widget disconnectedContainer;
private bool connected;

public StatusPanel() : base("UI/Status/StatusPanel.xmmp")
{
totalPlayers = EnsureWidgetById<Label>("TotalPlayers");
groupPlayers = EnsureWidgetById<Label>("GroupPlayers");
connectedContainer = EnsureWidgetById<Widget>("ConnectedContainer");
disconnectedContainer = EnsureWidgetById<Widget>("DisconnectedContainer");

connectedContainer.Visible = false;

AcceptsKeyboardFocus = false;

MatchmakingManager.Instance.Events.ServerStatusUpdateReceived += OnServerStatusReceived;
}

private void OnServerStatusReceived(ServerStatus status)
{
TotalPlayers = status.TotalPlayers.ToString();
GroupPlayers = status.GroupPlayers.ToString();
}

public void Update(float delta)
{
Visible = PauseManager.instance.IsPaused;
Connected = MatchmakingManager.Instance.IsConnected;
}
}
}
14 changes: 14 additions & 0 deletions Matchmaking.Client/EventData/ServerStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Matchmaking.Client.EventData
{
public class ServerStatus
{
public uint TotalPlayers { get; set; }
public uint GroupPlayers { get; set; }

public ServerStatus(uint totalPlayers, uint groupPlayers)
{
TotalPlayers = totalPlayers;
GroupPlayers = groupPlayers;
}
}
}
10 changes: 10 additions & 0 deletions Matchmaking.Client/Events.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Matchmaking.Client.Chat;
using Matchmaking.Client.EventData;
using Matchmaking.Client.Messages;

namespace Matchmaking.Client
Expand All @@ -25,5 +26,14 @@ internal void OnChatMessageReceived(ChatMessage message)
{
ChatMessageReceived?.Invoke(message);
}

public delegate void ServerStatusUpdateReceivedHandler(ServerStatus status);

public event ServerStatusUpdateReceivedHandler? ServerStatusUpdateReceived;

internal void OnServerStatusUpdateReceived(ServerStatus status)
{
ServerStatusUpdateReceived?.Invoke(status);
}
}
}
2 changes: 1 addition & 1 deletion Matchmaking.Client/MatchmakingClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Matchmaking.Client
{
public class MatchmakingClient
{
public const uint Version = 1;
public const uint Version = 2;

public string? Password { get; private set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public MatchmakingMessageProcessor()
{
RegisterHandler(new InformNearbyClientsHandler());
RegisterHandler(new OutgoingChatMessageHandler());
RegisterHandler(new ServerStatusUpdateHandler());
}
}
}
20 changes: 20 additions & 0 deletions Matchmaking.Client/Messages/Handlers/ServerStatusUpdateHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Threading.Tasks;
using Matchmaking.Client.EventData;
using Matchmaking.Client.Messages.Processing;
using Serilog;

namespace Matchmaking.Client.Messages.Handlers
{
internal class ServerStatusUpdateHandler : IMessageHandler<ServerStatusUpdate, Context>
{
private static readonly ILogger Logger = Log.ForContext<ServerStatusUpdateHandler>();

public Task HandleMessage(ServerStatusUpdate message, Context context)
{
Logger.Information("Received server status. Total players: {totalPlayers}, group players: {groupPlayers}", message.TotalPlayers, message.GroupPlayers);
context.MatchmakingClient.Events.OnServerStatusUpdateReceived(new ServerStatus(message.TotalPlayers, message.GroupPlayers));

return Task.CompletedTask;
}
}
}
22 changes: 22 additions & 0 deletions Matchmaking.Client/Messages/ServerStatusUpdate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.IO;

namespace Matchmaking.Client.Messages
{
internal class ServerStatusUpdate : Message
{
public uint TotalPlayers { get; set; }
public uint GroupPlayers { get; set; }

public override void Serialize(BinaryWriter writer)
{
throw new NotSupportedException();
}

public override void Deserialize(BinaryReader reader)
{
TotalPlayers = (uint)reader.ReadVarInt();
GroupPlayers = (uint)reader.ReadVarInt();
}
}
}
3 changes: 2 additions & 1 deletion Matchmaking.Client/Networking/MessageType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ internal enum MessageType
/// <summary>Incoming chat message from a client (to server)</summary>
IncomingChatMessage,
/// <summary>Outgoing chat message from server (to client)</summary>
OutgoingChatMessage
OutgoingChatMessage,
ServerStatusUpdate,
}
}
3 changes: 2 additions & 1 deletion Matchmaking.Client/Networking/MessagesCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ internal class MessagesCodec : CodecSink<Message>
{ MessageType.SetMatchmakingPassword, typeof(SetMatchmakingPassword) },
{ MessageType.InformNearbyClients, typeof(InformNearbyClients) },
{ MessageType.IncomingChatMessage, typeof(IncomingChatMessage) },
{ MessageType.OutgoingChatMessage, typeof(OutgoingChatMessage) }
{ MessageType.OutgoingChatMessage, typeof(OutgoingChatMessage) },
{ MessageType.ServerStatusUpdate, typeof(ServerStatusUpdate) }
};

private static readonly Dictionary<Type, MessageType> MessageTypesReversed = MessageTypes.ToDictionary(kv => kv.Value, kv => kv.Key);
Expand Down
15 changes: 15 additions & 0 deletions Resources/UI/Status/StatusPanel.xmmp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Panel Padding="20" Margin="10, 10, 0, 0" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#00000096">
<VerticalStackPanel Id="ConnectedContainer">
<HorizontalStackPanel>
<Label Text="Players online: " Font="Fonts/OpenSans-Bold.ttf:22" />
<Label Id="TotalPlayers" Text="..." Font="Fonts/OpenSans-Bold.ttf:22" />
</HorizontalStackPanel>
<HorizontalStackPanel>
<Label Text="Players in your group: " Font="Fonts/OpenSans-Bold.ttf:22" />
<Label Id="GroupPlayers" Text="..." Font="Fonts/OpenSans-Bold.ttf:22" />
</HorizontalStackPanel>
</VerticalStackPanel>
<VerticalStackPanel Id="DisconnectedContainer">
<Label Text="Reconnecting..." Font="Fonts/OpenSans-Bold.ttf:22" />
</VerticalStackPanel>
</Panel>

0 comments on commit 93da891

Please sign in to comment.