diff --git a/ServerBrowser/Games/GameExtension.cs b/ServerBrowser/Games/GameExtension.cs index 264d19c..a286a68 100644 --- a/ServerBrowser/Games/GameExtension.cs +++ b/ServerBrowser/Games/GameExtension.cs @@ -247,6 +247,11 @@ public virtual void Rcon(ServerRow row, int port, string password, string comman { return row?.ServerInfo?.MaxPlayers; } + + public virtual int? GetPrivateClients(ServerRow row) + { + return 0; + } } #endregion diff --git a/ServerBrowser/Games/QuakeLive.cs b/ServerBrowser/Games/QuakeLive.cs index 7b0c2e1..e10f32b 100644 --- a/ServerBrowser/Games/QuakeLive.cs +++ b/ServerBrowser/Games/QuakeLive.cs @@ -213,8 +213,9 @@ public override string GetCleanPlayerName(Player player) public override int? GetMaxClients(ServerRow row) { var cli = row.GetRule("sv_maxclients"); - if (!string.IsNullOrEmpty(cli)) - return int.Parse(cli); + int val; + if (!string.IsNullOrEmpty(cli) && int.TryParse(cli, out val)) + return val; // QL currently returns the sv_maxclients in MaxPlayers (instead of teamsize * 2) return row.ServerInfo?.MaxPlayers; @@ -242,6 +243,18 @@ public override string GetCleanPlayerName(Player player) } #endregion + #region GetPrivateClients() + public override int? GetPrivateClients(ServerRow row) + { + var cli = row.GetRule("sv_privateclients"); + int val; + if (!string.IsNullOrEmpty(cli) && int.TryParse(cli, out val)) + return val; + + return 0; + } + #endregion + #region Connect() public override bool Connect(ServerRow server, string password, bool spectate) diff --git a/ServerBrowser/Games/Toxikk.cs b/ServerBrowser/Games/Toxikk.cs index 4d54dc9..e37594d 100644 --- a/ServerBrowser/Games/Toxikk.cs +++ b/ServerBrowser/Games/Toxikk.cs @@ -112,8 +112,15 @@ public override object GetServerCellValue(ServerRow row, string fieldName) return row.GetRule(fieldName) == "1"; case "_gametype": var gt = row.ServerInfo.Description; - return gt == null ? null : gt.Contains("BloodLust") ? "BL" : gt.Contains("TeamGame") ? "SA" : gt.Contains("Cell") ? "CC" - : gt.Contains("TRGame") ? "TR" : gt.Contains("TAGame") ? "TA" : gt; + return gt == null ? null : + gt.Contains("BloodLust") ? "BL" : + gt.Contains("TeamGame") ? "SA" : + gt.Contains("Cell") ? "CC" : + gt.Contains("TRGame") ? "TR" : + gt.Contains("TAGame") ? "TA" : + gt.Contains("AreaDomination") ? "AD" : + gt =="STBGame" ? "SB" : + gt; case Mutators: var mods = (row.GetRule(fieldName) ?? "").ToLower(); var buff = new StringBuilder(); diff --git a/ServerBrowser/PlayerCountInfo.cs b/ServerBrowser/PlayerCountInfo.cs index c58ce76..ecb9f06 100644 --- a/ServerBrowser/PlayerCountInfo.cs +++ b/ServerBrowser/PlayerCountInfo.cs @@ -17,6 +17,7 @@ public class PlayerCountInfo : IComparable public int? TotalPlayers => RealPlayers + Bots; public int? MaxPlayers { get; private set; } public int? MaxClients { get; private set; } + public int? PrivateClients { get; private set; } public PlayerCountInfo(ServerRow row) { @@ -27,13 +28,14 @@ public PlayerCountInfo(ServerRow row) public void Update() { if (row.ServerInfo == null) - RealPlayers = Bots = MaxPlayers = MaxClients = null; + RealPlayers = Bots = MaxPlayers = MaxClients = PrivateClients = null; else { Bots = row.GameExtension.GetBotCount(row); MaxPlayers = row.GameExtension.GetMaxPlayers(row); MaxClients = row.GameExtension.GetMaxClients(row); RealPlayers = row.ServerInfo.Players; + PrivateClients = row.GameExtension.GetPrivateClients(row); // some games count bots as players, others don't if (RealPlayers >= Bots) @@ -95,9 +97,11 @@ public override string ToString() if (this.MaxPlayers > 0) { - sb.Append(" / ").Append(this.MaxPlayers); - if (this.MaxClients > this.MaxPlayers) - sb.Append('+').Append(this.MaxClients - this.MaxPlayers); + var privateInUse = Math.Max(0, (this.TotalPlayers - (this.MaxClients - this.PrivateClients)) ?? 0); + int max = Math.Min(this.MaxPlayers ?? 0, (this.MaxClients ?? 0) - (this.PrivateClients ?? 0) + privateInUse); + sb.Append(" / ").Append(max); + if (this.MaxClients - this.PrivateClients + privateInUse > max) + sb.Append('+').Append(this.MaxClients - this.PrivateClients + privateInUse - max); } return sb.ToString(); } diff --git a/ServerBrowser/ServerBrowserForm.cs b/ServerBrowser/ServerBrowserForm.cs index 8ab70fc..2f5cf26 100644 --- a/ServerBrowser/ServerBrowserForm.cs +++ b/ServerBrowser/ServerBrowserForm.cs @@ -30,7 +30,7 @@ namespace ServerBrowser { public partial class ServerBrowserForm : XtraForm { - private const string Version = "2.19"; + private const string Version = "2.20"; private const string DevExpressVersion = "v15.1"; private const string CustomDetailColumnPrefix = "ServerInfo."; private const string CustomRuleColumnPrefix = "custRule."; @@ -1037,6 +1037,8 @@ private void ConnectToGameServer(ServerRow row, bool spectate) this.queryLogic.Cancel(); this.timerReloadServers.Stop(); } + if (this.splashScreenManager1.IsSplashFormVisible) + this.splashScreenManager1.CloseWaitForm(); this.splashScreenManager1.ShowWaitForm(); this.splashScreenManager1.SetWaitFormCaption("Connecting to " + row.EndPoint); this.splashScreenManager1.SetWaitFormDescription(row.Name); diff --git a/ServerBrowser/ServerRow.cs b/ServerBrowser/ServerRow.cs index 149a099..545adc0 100644 --- a/ServerBrowser/ServerRow.cs +++ b/ServerBrowser/ServerRow.cs @@ -63,13 +63,13 @@ public int JoinStatus var maxPlayers = PlayerCount.MaxPlayers; if (maxPlayers == null) return -1; + if (players >= PlayerCount.MaxClients - PlayerCount.PrivateClients) + return 2; + if (players < maxPlayers) return 0; - var maxClients = PlayerCount.MaxClients; - if (maxClients != null && players < maxClients) - return 1; - return 2; + return 1; } } diff --git a/changelog.md b/changelog.md index ae9d00f..06af04b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,13 @@ +2.20 +--- +- Quake Live: player count and join-status now includes sv_privateClients in the calculations +- Toxikk: short game type names for AD (Area Domination) and SB (Score-the-Banshee) + 2.19 --- - Quake Live: open extraQL in the background instead of bringing it to front (requires extraQL 2.7 or later) - connect on double-click can now be disabled +- open "Connecting to ..." form no longer blocks reconnecting again 2.18 ---