Ready Indicator in the lobby (#1771)
* Ready Indicator in the lobby * Use SessionID instead of Name * Don't show ready state when game is already running * Make Ready List not selectable * -Remove disconnected sessions from Ready -Fix showing ReadyStatus when staying in lobby
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Client.Interfaces;
|
||||
using Content.Client.State;
|
||||
using Content.Client.UserInterface;
|
||||
@@ -8,6 +9,7 @@ using Robust.Client.Interfaces.Graphics;
|
||||
using Robust.Client.Interfaces.State;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -27,9 +29,11 @@ namespace Content.Client.GameTicking
|
||||
[ViewVariables] public string ServerInfoBlob { get; private set; }
|
||||
[ViewVariables] public DateTime StartTime { get; private set; }
|
||||
[ViewVariables] public bool Paused { get; private set; }
|
||||
[ViewVariables] public Dictionary<NetSessionId, bool> Ready { get; private set; }
|
||||
|
||||
public event Action InfoBlobUpdated;
|
||||
public event Action LobbyStatusUpdated;
|
||||
public event Action LobbyReadyUpdated;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
@@ -40,12 +44,14 @@ namespace Content.Client.GameTicking
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyStatus>(nameof(MsgTickerLobbyStatus), LobbyStatus);
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyInfo>(nameof(MsgTickerLobbyInfo), LobbyInfo);
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyCountdown>(nameof(MsgTickerLobbyCountdown), LobbyCountdown);
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyReady>(nameof(MsgTickerLobbyReady), LobbyReady);
|
||||
_netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage), RoundEnd);
|
||||
_netManager.RegisterNetMessage<MsgRequestWindowAttention>(nameof(MsgRequestWindowAttention), msg =>
|
||||
{
|
||||
IoCManager.Resolve<IClyde>().RequestWindowAttention();
|
||||
});
|
||||
|
||||
Ready = new Dictionary<NetSessionId, bool>();
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
@@ -62,6 +68,8 @@ namespace Content.Client.GameTicking
|
||||
IsGameStarted = message.IsRoundStarted;
|
||||
AreWeReady = message.YouAreReady;
|
||||
Paused = message.Paused;
|
||||
if (IsGameStarted)
|
||||
Ready.Clear();
|
||||
|
||||
LobbyStatusUpdated?.Invoke();
|
||||
}
|
||||
@@ -84,9 +92,18 @@ namespace Content.Client.GameTicking
|
||||
Paused = message.Paused;
|
||||
}
|
||||
|
||||
private void LobbyReady(MsgTickerLobbyReady message)
|
||||
{
|
||||
// Merge the Dictionaries
|
||||
foreach (var p in message.PlayerReady)
|
||||
{
|
||||
Ready[p.Key] = p.Value;
|
||||
}
|
||||
LobbyReadyUpdated?.Invoke();
|
||||
}
|
||||
|
||||
private void RoundEnd(MsgRoundEndMessage message)
|
||||
{
|
||||
|
||||
//This is not ideal at all, but I don't see an immediately better fit anywhere else.
|
||||
var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.RoundDuration, message.AllPlayersEndInfo);
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Robust.Shared.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Client.Interfaces
|
||||
{
|
||||
@@ -9,9 +11,11 @@ namespace Content.Client.Interfaces
|
||||
bool AreWeReady { get; }
|
||||
DateTime StartTime { get; }
|
||||
bool Paused { get; }
|
||||
Dictionary<NetSessionId, bool> Ready { get; }
|
||||
|
||||
void Initialize();
|
||||
event Action InfoBlobUpdated;
|
||||
event Action LobbyStatusUpdated;
|
||||
event Action LobbyReadyUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,8 @@ namespace Content.Client.State
|
||||
|
||||
_playerManager.PlayerListUpdated += PlayerManagerOnPlayerListUpdated;
|
||||
_clientGameTicker.InfoBlobUpdated += UpdateLobbyUi;
|
||||
_clientGameTicker.LobbyStatusUpdated += UpdateLobbyUi;
|
||||
_clientGameTicker.LobbyStatusUpdated += LobbyStatusUpdated;
|
||||
_clientGameTicker.LobbyReadyUpdated += LobbyReadyUpdated;
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
@@ -149,7 +150,25 @@ namespace Content.Client.State
|
||||
_lobby.StartTime.Text = Loc.GetString("Round Starts In: {0}", text);
|
||||
}
|
||||
|
||||
private void PlayerManagerOnPlayerListUpdated(object sender, EventArgs e) => UpdatePlayerList();
|
||||
private void PlayerManagerOnPlayerListUpdated(object sender, EventArgs e)
|
||||
{
|
||||
// Remove disconnected sessions from the Ready Dict
|
||||
foreach (var p in _clientGameTicker.Ready)
|
||||
{
|
||||
if (!_playerManager.SessionsDict.TryGetValue(p.Key, out _))
|
||||
{
|
||||
_clientGameTicker.Ready.Remove(p.Key);
|
||||
}
|
||||
}
|
||||
UpdatePlayerList();
|
||||
}
|
||||
private void LobbyReadyUpdated() => UpdatePlayerList();
|
||||
|
||||
private void LobbyStatusUpdated()
|
||||
{
|
||||
UpdatePlayerList();
|
||||
UpdateLobbyUi();
|
||||
}
|
||||
|
||||
private void UpdateLobbyUi()
|
||||
{
|
||||
@@ -178,10 +197,24 @@ namespace Content.Client.State
|
||||
private void UpdatePlayerList()
|
||||
{
|
||||
_lobby.OnlinePlayerItemList.Clear();
|
||||
_lobby.PlayerReadyList.Clear();
|
||||
|
||||
foreach (var session in _playerManager.Sessions.OrderBy(s => s.Name))
|
||||
{
|
||||
_lobby.OnlinePlayerItemList.AddItem(session.Name);
|
||||
|
||||
var readyState = "";
|
||||
// Don't show ready state if we're ingame
|
||||
if (!_clientGameTicker.IsGameStarted)
|
||||
{
|
||||
var ready = false;
|
||||
if (session.SessionId == _playerManager.LocalPlayer.SessionId)
|
||||
ready = _clientGameTicker.AreWeReady;
|
||||
else
|
||||
_clientGameTicker.Ready.TryGetValue(session.SessionId, out ready);
|
||||
readyState = ready ? Loc.GetString("Ready") : Loc.GetString("Not Ready");
|
||||
}
|
||||
_lobby.PlayerReadyList.AddItem(readyState, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,6 +226,7 @@ namespace Content.Client.State
|
||||
}
|
||||
|
||||
_console.ProcessCommand($"toggleready {newReady}");
|
||||
UpdatePlayerList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Client.Chat;
|
||||
using Content.Client.Chat;
|
||||
using Content.Client.Interfaces;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Content.Client.Utility;
|
||||
@@ -22,6 +22,7 @@ namespace Content.Client.UserInterface
|
||||
public Button LeaveButton { get; }
|
||||
public ChatBox Chat { get; }
|
||||
public ItemList OnlinePlayerItemList { get; }
|
||||
public ItemList PlayerReadyList { get; }
|
||||
public ServerInfo ServerInfo { get; }
|
||||
public LobbyCharacterPreviewPanel CharacterPreview { get; }
|
||||
|
||||
@@ -219,7 +220,25 @@ namespace Content.Client.UserInterface
|
||||
MarginBottomOverride = 3,
|
||||
Children =
|
||||
{
|
||||
(OnlinePlayerItemList = new ItemList())
|
||||
new HBoxContainer
|
||||
{
|
||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||
CustomMinimumSize = (50,50),
|
||||
Children =
|
||||
{
|
||||
(OnlinePlayerItemList = new ItemList
|
||||
{
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||
}),
|
||||
(PlayerReadyList = new ItemList
|
||||
{
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||
SizeFlagsStretchRatio = 0.2f
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new NanoHeading
|
||||
|
||||
@@ -49,6 +49,7 @@ using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
@@ -138,6 +139,7 @@ namespace Content.Server.GameTicking
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyStatus>(nameof(MsgTickerLobbyStatus));
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyInfo>(nameof(MsgTickerLobbyInfo));
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyCountdown>(nameof(MsgTickerLobbyCountdown));
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyReady>(nameof(MsgTickerLobbyReady));
|
||||
_netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage));
|
||||
_netManager.RegisterNetMessage<MsgRequestWindowAttention>(nameof(MsgRequestWindowAttention));
|
||||
|
||||
@@ -381,6 +383,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
_playersInLobby[player] = ready;
|
||||
_netManager.ServerSendMessage(_getStatusMsg(player), player.ConnectedClient);
|
||||
_netManager.ServerSendToAll(GetReadySingle(player, ready));
|
||||
}
|
||||
|
||||
public T AddGameRule<T>() where T : GameRule, new()
|
||||
@@ -871,6 +874,7 @@ namespace Content.Server.GameTicking
|
||||
_netManager.ServerSendMessage(_netManager.CreateNetMessage<MsgTickerJoinLobby>(), session.ConnectedClient);
|
||||
_netManager.ServerSendMessage(_getStatusMsg(session), session.ConnectedClient);
|
||||
_netManager.ServerSendMessage(GetInfoMsg(), session.ConnectedClient);
|
||||
_netManager.ServerSendMessage(GetReadyStatus(), session.ConnectedClient);
|
||||
}
|
||||
|
||||
private void _playerJoinGame(IPlayerSession session)
|
||||
@@ -882,6 +886,26 @@ namespace Content.Server.GameTicking
|
||||
_netManager.ServerSendMessage(_netManager.CreateNetMessage<MsgTickerJoinGame>(), session.ConnectedClient);
|
||||
}
|
||||
|
||||
private MsgTickerLobbyReady GetReadyStatus()
|
||||
{
|
||||
var msg = _netManager.CreateNetMessage<MsgTickerLobbyReady>();
|
||||
msg.PlayerReady = new Dictionary<NetSessionId, bool>();
|
||||
foreach (var player in _playersInLobby.Keys)
|
||||
{
|
||||
_playersInLobby.TryGetValue(player, out var ready);
|
||||
msg.PlayerReady.Add(player.SessionId, ready);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
private MsgTickerLobbyReady GetReadySingle(IPlayerSession player, bool ready)
|
||||
{
|
||||
var msg = _netManager.CreateNetMessage<MsgTickerLobbyReady>();
|
||||
msg.PlayerReady = new Dictionary<NetSessionId, bool>();
|
||||
msg.PlayerReady.Add(player.SessionId, ready);
|
||||
return msg;
|
||||
}
|
||||
|
||||
private MsgTickerLobbyStatus _getStatusMsg(IPlayerSession session)
|
||||
{
|
||||
_playersInLobby.TryGetValue(session, out var ready);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
namespace Content.Shared
|
||||
@@ -152,6 +155,57 @@ namespace Content.Shared
|
||||
}
|
||||
}
|
||||
|
||||
protected class MsgTickerLobbyReady : NetMessage
|
||||
{
|
||||
#region REQUIRED
|
||||
|
||||
public const MsgGroups GROUP = MsgGroups.Command;
|
||||
public const string NAME = nameof(MsgTickerLobbyReady);
|
||||
public MsgTickerLobbyReady(INetChannel channel) : base(NAME, GROUP) { }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The Players Ready (SessionID:ready)
|
||||
/// </summary>
|
||||
public Dictionary<NetSessionId, bool> PlayerReady { get; set; }
|
||||
|
||||
public override void ReadFromBuffer(NetIncomingMessage buffer)
|
||||
{
|
||||
PlayerReady = new Dictionary<NetSessionId, bool>();
|
||||
var length = buffer.ReadInt32();
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
var serializer = IoCManager.Resolve<IRobustSerializer>();
|
||||
var byteLength = buffer.ReadVariableInt32();
|
||||
NetSessionId sessionID;
|
||||
using (var stream = buffer.ReadAsStream(byteLength))
|
||||
{
|
||||
serializer.DeserializeDirect(stream, out sessionID);
|
||||
}
|
||||
var ready = buffer.ReadBoolean();
|
||||
PlayerReady.Add(sessionID, ready);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteToBuffer(NetOutgoingMessage buffer)
|
||||
{
|
||||
var serializer = IoCManager.Resolve<IRobustSerializer>();
|
||||
buffer.Write(PlayerReady.Count);
|
||||
foreach (var p in PlayerReady)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
serializer.SerializeDirect(stream, p.Key);
|
||||
buffer.WriteVariableInt32((int) stream.Length);
|
||||
stream.TryGetBuffer(out var segment);
|
||||
buffer.Write(segment);
|
||||
}
|
||||
buffer.Write(p.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct RoundEndPlayerInfo
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user