using System.Collections.Immutable;
+using System.Linq;
using System.Runtime.InteropServices;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
+using Content.Server.Chat.Managers;
using Content.Server.Database;
using Content.Server.GameTicking;
using Content.Server.Preferences.Managers;
using Content.Shared.Players.PlayTimeTracking;
using Robust.Server.Player;
using Robust.Shared.Configuration;
+using Robust.Shared.Enums;
using Robust.Shared.Network;
+using Robust.Shared.Player;
using Robust.Shared.Timing;
/*
[Dependency] private readonly ServerDbEntryManager _serverDbEntry = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly ILogManager _logManager = default!;
+ [Dependency] private readonly IChatManager _chatManager = default!;
private readonly Dictionary<NetUserId, TimeSpan> _temporaryBypasses = [];
private ISawmill _sawmill = default!;
_netMgr.Connecting += NetMgrOnConnecting;
_netMgr.AssignUserIdCallback = AssignUserIdCallback;
+ _plyMgr.PlayerStatusChanged += PlayerStatusChanged;
// Approval-based IP bans disabled because they don't play well with Happy Eyeballs.
// _netMgr.HandleApprovalCallback = HandleApproval;
}
}
}
+ private async void PlayerStatusChanged(object? sender, SessionStatusEventArgs args)
+ {
+ if (args.NewStatus == SessionStatus.Connected)
+ {
+ AdminAlertIfSharedConnection(args.Session);
+ }
+ }
+
+ private void AdminAlertIfSharedConnection(ICommonSession newSession)
+ {
+ var playerThreshold = _cfg.GetCVar(CCVars.AdminAlertMinPlayersSharingConnection);
+ if (playerThreshold < 0)
+ return;
+
+ var addr = newSession.Channel.RemoteEndPoint.Address;
+
+ var otherConnectionsFromAddress = _plyMgr.Sessions.Where(session =>
+ session.Status is SessionStatus.Connected or SessionStatus.InGame
+ && session.Channel.RemoteEndPoint.Address.Equals(addr)
+ && session.UserId != newSession.UserId)
+ .ToList();
+
+ var otherConnectionCount = otherConnectionsFromAddress.Count;
+ if (otherConnectionCount + 1 < playerThreshold) // Add one for the total, not just others, using the address
+ return;
+
+ var username = newSession.Name;
+ var otherUsernames = string.Join(", ",
+ otherConnectionsFromAddress.Select(session => session.Name));
+
+ _chatManager.SendAdminAlert(Loc.GetString("admin-alert-shared-connection",
+ ("player", username),
+ ("otherCount", otherConnectionCount),
+ ("otherList", otherUsernames)));
+ }
+
/*
* TODO: Jesus H Christ what is this utter mess of a function
* TODO: Break this apart into is constituent steps.
public static readonly CVarDef<bool> ServerBanErasePlayer =
CVarDef.Create("admin.server_ban_erase_player", false, CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);
+ /// <summary>
+ /// Minimum players sharing a connection required to create an alert. -1 to disable the alert.
+ /// </summary>
+ /// <remarks>
+ /// If you set this to 0 or 1 then it will alert on every connection, so probably don't do that.
+ /// </remarks>
+ public static readonly CVarDef<int> AdminAlertMinPlayersSharingConnection =
+ CVarDef.Create("admin.alert.min_players_sharing_connection", -1, CVar.SERVERONLY);
+
/// <summary>
/// Minimum explosion intensity to create an admin alert message. -1 to disable the alert.
/// </summary>