Skip to content

Commit ad67a68

Browse files
authored
update lobby server with fixes
1 parent e447a0e commit ad67a68

File tree

6 files changed

+76
-8
lines changed

6 files changed

+76
-8
lines changed

Shared/LobbyClient/DedicatedServer.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class DedicatedServer : IDisposable
2222
public static EventHandler<SpringBattleContext> AnyDedicatedExited;
2323

2424
private readonly SpringPaths paths;
25-
private readonly Timer timer = new Timer(20000);
25+
private readonly Timer timer = new Timer(1000);
2626

2727
private Dictionary<string, HashSet<byte> > gamePrivateMessages = new Dictionary<string, HashSet<byte> >();
2828

@@ -514,8 +514,7 @@ private void timer_Elapsed(object sender, ElapsedEventArgs e)
514514
try
515515
{
516516
var timeSinceStart = DateTime.UtcNow.Subtract(Context.StartTime).TotalSeconds;
517-
const int timeToWait = 160; // force start after 180s
518-
const int timeToWarn = 100; // warn people after 120s
517+
const int timeToWait = 160; // force start after this many seconds
519518

520519
if (Context.IsHosting && IsRunning && (Context.IngameStartTime == null))
521520
{
@@ -524,7 +523,10 @@ private void timer_Elapsed(object sender, ElapsedEventArgs e)
524523
Context.IsTimeoutForceStarted = true;
525524
ForceStart();
526525
}
527-
else if (timeSinceStart > timeToWarn) SayGame($"Game will be force started in {Math.Max(20, timeToWait - Math.Round(timeSinceStart))} seconds");
526+
else
527+
{
528+
talker.SendText($"/luarules pregame_timer_seconds {Convert.ToInt32(timeToWait - timeSinceStart)}");
529+
}
528530
}
529531
}
530532
catch (Exception ex)

Shared/LobbyClient/Spring.SpringBattleContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public class SpringBattleContext
4747

4848
public BattlePlayerResult GetOrAddPlayer(string name)
4949
{
50+
if (string.IsNullOrEmpty(name)) return null; // we don't want to add null players
51+
5052
var ret = ActualPlayers.FirstOrDefault(y => y.Name == name);
5153
if (ret == null)
5254
{

Shared/PlasmaShared/GlobalConst.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ public static void OverrideContentServiceClient(IContentServiceClient client)
266266
}
267267

268268

269-
public static string UnitSyncEngine = "unitsync";
269+
public static string UnitSyncEngine = "105.1.1-1485-g78f9a2c";
270270

271271
public static int SteamContributionJarID = 2;
272272
public static Dictionary<ulong, int> DlcToKudos = new Dictionary<ulong, int>() { { 842950, 100 }, { 842951, 250 }, { 842952, 500 } };

Zero-K.info/Controllers/TourneyController.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.ComponentModel.DataAnnotations;
34
using System.Linq;
45
using System.Web;
56
using System.Web.Mvc;
@@ -17,7 +18,9 @@ public class TourneyModel
1718
public List<int> Team1Ids { get; set; } = new List<int>();
1819
public List<int> Team2Ids { get; set; } = new List<int>();
1920
public string Title { get; set; }
20-
public string ModoptString { get; set; }
21+
22+
[DisplayFormat(ConvertEmptyStringToNull = false)]
23+
public string ModoptString { get; set; } = "";
2124
}
2225

2326
// GET: Tourney

ZkLobbyServer/ServerBattle.cs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Collections.Generic;
34
using System.Diagnostics;
45
using System.Linq;
@@ -70,6 +71,12 @@ public class ServerBattle : Battle
7071

7172
public CommandPoll ActivePoll { get; private set; }
7273

74+
// Dictionary tracking cooldown for each user that fails a poll
75+
private readonly ConcurrentDictionary<string, DateTime> pollFailCooldowns = new ConcurrentDictionary<string, DateTime>();
76+
77+
// Returns the count of non-spectators in the current battle
78+
public int NonSpectatorPlayerCount => Users.Values.Count(x => x!= null && !x.IsSpectator);
79+
7380
public bool IsAutohost { get; private set; }
7481
public bool IsDefaultGame { get; private set; } = true;
7582
public bool IsCbalEnabled { get; private set; } = true;
@@ -174,7 +181,7 @@ public List<string> GetAllUserNames()
174181
{
175182
var ret = Users.Select(x => x.Key).ToList();
176183
if (spring.IsRunning) ret.AddRange(spring.Context.ActualPlayers.Select(x => x.Name));
177-
return ret.Distinct().ToList();
184+
return ret.Distinct().Where(x=>x!=null).ToList();
178185
}
179186

180187
public BattleCommand GetCommandByName(string name)
@@ -652,13 +659,48 @@ public async Task<bool> StartVote(Func<string, string> eligibilitySelector, List
652659
await Respond(creator, $"Please wait, another poll already in progress: {ActivePoll.Topic}");
653660
return false;
654661
}
662+
663+
// Check if the user is on cooldown due to a failed poll
664+
if (creator != null && IsOnPollCooldown(creator?.User, out var remain))
665+
{
666+
await Respond(creator, $"You cannot start a vote for {remain} seconds.");
667+
return false;
668+
}
669+
670+
655671
await poll.Setup(eligibilitySelector, options, creator, topic);
656672
ActivePoll = poll;
657673
pollTimer.Interval = timeout * 1000;
658674
pollTimer.Enabled = true;
659675
return true;
660676
}
661677

678+
679+
private bool IsUserModerator(string username)
680+
{
681+
if (Users.TryGetValue(username, out var ubs) && (ubs?.LobbyUser?.IsAdmin == true))
682+
return true;
683+
if (server.ConnectedUsers.TryGetValue(username, out var con) && (con?.User?.IsAdmin == true)) // command can be sent by someone not in the battle
684+
return true;
685+
return false;
686+
}
687+
688+
689+
private bool IsOnPollCooldown(string username, out int remainSeconds)
690+
{
691+
remainSeconds = 0;
692+
if (pollFailCooldowns.TryGetValue(username, out var blockedUntil))
693+
{
694+
var diff = blockedUntil - DateTime.UtcNow;
695+
if (diff.TotalSeconds > 0)
696+
{
697+
remainSeconds = (int)Math.Ceiling(diff.TotalSeconds);
698+
return true;
699+
}
700+
}
701+
return false;
702+
}
703+
662704

663705
public async void StopVote()
664706
{
@@ -669,7 +711,26 @@ public async void StopVote()
669711
if (ActivePoll != null) await ActivePoll.End(false);
670712
if (pollTimer != null) pollTimer.Enabled = false;
671713
ActivePoll = null;
714+
715+
// Let the poll announce results or do final DB logging
672716
await oldPoll?.PublishResult();
717+
718+
719+
// 1) Did the poll pass?
720+
bool pollPassed = oldPoll?.Outcome?.ChosenOption != null;
721+
722+
// 2) Who started this poll?
723+
string creatorName = oldPoll?.Creator?.User;
724+
725+
// 3) If poll failed and conditions are met => apply 30s cooldown
726+
if (!string.IsNullOrEmpty(creatorName) && // user is known
727+
!pollPassed // poll is a failure
728+
&& IsAutohost // only relevant in autohost
729+
&& NonSpectatorPlayerCount >= 10
730+
&& !IsUserModerator(creatorName))
731+
{
732+
pollFailCooldowns[creatorName] = DateTime.UtcNow.AddSeconds(30);
733+
}
673734
}
674735
catch (Exception ex)
675736
{

ZkLobbyServer/autohost/Commands/CmdKick.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private bool NotifyAdminChannel(ServerBattle battle, Say e, bool isActualKick)
9090
{
9191
gtype = string.Format("game on map {0}", battle.MapName);
9292
PlasmaShared.BattlePlayerResult res = battle.spring.Context.GetOrAddPlayer(target);
93-
isspec = res.IsSpectator;
93+
isspec = res?.IsSpectator == true;
9494
}
9595
else
9696
{

0 commit comments

Comments
 (0)