- Alternative method to get server ip
- Config option to disable update check
- Improved live bans check
- Added new permission `@css/showip` to show ip in `css_who` and `css_players` commands
This commit is contained in:
Dawid Bepierszcz
2024-06-17 11:08:46 +02:00
parent 00facafdcb
commit 985b1ae61f
8 changed files with 158 additions and 50 deletions

View File

@@ -37,7 +37,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)"); public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)"; public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
public override string ModuleAuthor => "daffyy & Dliix66"; public override string ModuleAuthor => "daffyy & Dliix66";
public override string ModuleVersion => "1.4.5a"; public override string ModuleVersion => "1.4.6a";
public CS2_SimpleAdminConfig Config { get; set; } = new(); public CS2_SimpleAdminConfig Config { get; set; } = new();
@@ -119,7 +119,8 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
DiscordWebhookClientPenalty = new DiscordWebhookClient(Config.Discord.DiscordPenaltyWebhook); DiscordWebhookClientPenalty = new DiscordWebhookClient(Config.Discord.DiscordPenaltyWebhook);
PluginInfo.ShowAd(ModuleVersion); PluginInfo.ShowAd(ModuleVersion);
_ = PluginInfo.CheckVersion(ModuleVersion, _logger); if (Config.EnableUpdateCheck)
Task.Run(async () => await PluginInfo.CheckVersion(ModuleVersion, _logger));
} }
private static TargetResult? GetTarget(CommandInfo command) private static TargetResult? GetTarget(CommandInfo command)

View File

@@ -10,9 +10,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.239" /> <PackageReference Include="CounterStrikeSharp.API" Version="1.0.243" />
<PackageReference Include="Dapper" Version="2.1.35" /> <PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="Discord.Net.Webhook" Version="3.14.1" /> <PackageReference Include="Discord.Net.Webhook" Version="3.15.0" />
<PackageReference Include="MySqlConnector" Version="2.3.7" /> <PackageReference Include="MySqlConnector" Version="2.3.7" />
<PackageReference Include="Newtonsoft.Json" Version="*" /> <PackageReference Include="Newtonsoft.Json" Version="*" />
</ItemGroup> </ItemGroup>

View File

@@ -415,7 +415,7 @@ namespace CS2_SimpleAdmin
printMethod($"• SteamID2: \"{player.SteamID}\""); printMethod($"• SteamID2: \"{player.SteamID}\"");
printMethod($"• Community link: \"{new SteamID(player.SteamID).ToCommunityUrl()}\""); printMethod($"• Community link: \"{new SteamID(player.SteamID).ToCommunityUrl()}\"");
} }
if (playerInfo.IpAddress != null) if (playerInfo.IpAddress != null && AdminManager.PlayerHasPermissions(caller, "@css/showip"))
printMethod($"• IP Address: \"{playerInfo.IpAddress}\""); printMethod($"• IP Address: \"{playerInfo.IpAddress}\"");
printMethod($"• Ping: \"{player.Ping}\""); printMethod($"• Ping: \"{player.Ping}\"");
if (player.SteamID.ToString().Length == 17) if (player.SteamID.ToString().Length == 17)
@@ -453,7 +453,7 @@ namespace CS2_SimpleAdmin
playersToTarget.ForEach(player => playersToTarget.ForEach(player =>
{ {
caller.PrintToConsole( caller.PrintToConsole(
$"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); $"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{(AdminManager.PlayerHasPermissions(caller, "@css/showip") ? player.IpAddress?.Split(":")[0] : "Unknown")}\" SteamID64: \"{player.SteamID}\")");
}); });
caller.PrintToConsole($"--------- END PLAYER LIST ---------"); caller.PrintToConsole($"--------- END PLAYER LIST ---------");
} }
@@ -475,18 +475,18 @@ namespace CS2_SimpleAdmin
return new return new
{ {
UserId = player.UserId, player.UserId,
Name = player.PlayerName, Name = player.PlayerName,
SteamId = player.SteamID.ToString(), SteamId = player.SteamID.ToString(),
IpAddress = player.IpAddress?.Split(":")[0] ?? "Unknown", IpAddress = AdminManager.PlayerHasPermissions(caller, "@css/showip") ? player.IpAddress?.Split(":")[0] ?? "Unknown" : "Unknown",
Ping = player.Ping, player.Ping,
IsAdmin = AdminManager.PlayerHasPermissions(player, "@css/ban") || AdminManager.PlayerHasPermissions(player, "@css/generic"), IsAdmin = AdminManager.PlayerHasPermissions(player, "@css/ban") || AdminManager.PlayerHasPermissions(player, "@css/generic"),
Stats = new Stats = new
{ {
Score = player.Score, player.Score,
Kills = matchStats?.Kills ?? 0, Kills = matchStats?.Kills ?? 0,
Deaths = matchStats?.Deaths ?? 0, Deaths = matchStats?.Deaths ?? 0,
MVPs = player.MVPs player.MVPs
} }
}; };
})); }));

View File

@@ -102,6 +102,7 @@ namespace CS2_SimpleAdmin
new AdminFlag { Name = "Ban", Flag = "@css/ban" }, new AdminFlag { Name = "Ban", Flag = "@css/ban" },
new AdminFlag { Name = "Perm Ban", Flag = "@css/permban" }, new AdminFlag { Name = "Perm Ban", Flag = "@css/permban" },
new AdminFlag { Name = "Unban", Flag = "@css/unban" }, new AdminFlag { Name = "Unban", Flag = "@css/unban" },
new AdminFlag { Name = "Show IP", Flag = "@css/showip" },
new AdminFlag { Name = "Cvar", Flag = "@css/cvar" }, new AdminFlag { Name = "Cvar", Flag = "@css/cvar" },
new AdminFlag { Name = "Rcon", Flag = "@css/rcon" }, new AdminFlag { Name = "Rcon", Flag = "@css/rcon" },
new AdminFlag { Name = "Root (all flags)", Flag = "@css/root" } new AdminFlag { Name = "Root (all flags)", Flag = "@css/root" }
@@ -110,7 +111,7 @@ namespace CS2_SimpleAdmin
public class CS2_SimpleAdminConfig : BasePluginConfig public class CS2_SimpleAdminConfig : BasePluginConfig
{ {
[JsonPropertyName("ConfigVersion")] public override int Version { get; set; } = 14; [JsonPropertyName("ConfigVersion")] public override int Version { get; set; } = 15;
[JsonPropertyName("DatabaseHost")] [JsonPropertyName("DatabaseHost")]
public string DatabaseHost { get; set; } = ""; public string DatabaseHost { get; set; } = "";
@@ -130,6 +131,9 @@ namespace CS2_SimpleAdmin
[JsonPropertyName("EnableMetrics")] [JsonPropertyName("EnableMetrics")]
public bool EnableMetrics { get; set; } = true; public bool EnableMetrics { get; set; } = true;
[JsonPropertyName("EnableUpdateCheck")]
public bool EnableUpdateCheck { get; set; } = true;
[JsonPropertyName("ReloadAdminsEveryMapChange")] [JsonPropertyName("ReloadAdminsEveryMapChange")]
public bool ReloadAdminsEveryMapChange { get; set; } = false; public bool ReloadAdminsEveryMapChange { get; set; } = false;
@@ -149,7 +153,7 @@ namespace CS2_SimpleAdmin
public int TimeMode { get; set; } = 1; public int TimeMode { get; set; } = 1;
[JsonPropertyName("MaxBanDuration")] [JsonPropertyName("MaxBanDuration")]
public int MaxBanDuration { get; set; } = 60 * 24 * 7; // 7 days public int MaxBanDuration { get; set; } = 60 * 24 * 7;
[JsonPropertyName("MultiServerMode")] [JsonPropertyName("MultiServerMode")]
public bool MultiServerMode { get; set; } = true; public bool MultiServerMode { get; set; } = true;

View File

@@ -15,8 +15,6 @@ public partial class CS2_SimpleAdmin
private void RegisterEvents() private void RegisterEvents()
{ {
RegisterListener<Listeners.OnMapStart>(OnMapStart); RegisterListener<Listeners.OnMapStart>(OnMapStart);
//RegisterListener<Listeners.OnClientConnected>(OnClientConnected);
//RegisterListener<Listeners.OnClientDisconnect>(OnClientDisconnect);
AddCommandListener("say", OnCommandSay); AddCommandListener("say", OnCommandSay);
AddCommandListener("say_team", OnCommandTeamSay); AddCommandListener("say_team", OnCommandTeamSay);
} }
@@ -209,7 +207,7 @@ public partial class CS2_SimpleAdmin
return HookResult.Continue; return HookResult.Continue;
if (info.GetArg(1).StartsWith($"/") if (info.GetArg(1).StartsWith($"/")
|| info.GetArg(1).StartsWith($"!")) || info.GetArg(1).StartsWith($"!"))
return HookResult.Continue; return HookResult.Continue;
if (info.GetArg(1).Length == 0) if (info.GetArg(1).Length == 0)
@@ -223,11 +221,11 @@ public partial class CS2_SimpleAdmin
public HookResult OnCommandTeamSay(CCSPlayerController? player, CommandInfo info) public HookResult OnCommandTeamSay(CCSPlayerController? player, CommandInfo info)
{ {
if (player is null || !player.IsValid || player.IsBot || player.IsHLTV ) if (player is null || !player.IsValid || player.IsBot || player.IsHLTV)
return HookResult.Continue; return HookResult.Continue;
if (info.GetArg(1).StartsWith($"/") if (info.GetArg(1).StartsWith($"/")
|| info.GetArg(1).StartsWith($"!")) || info.GetArg(1).StartsWith($"!"))
return HookResult.Continue; return HookResult.Continue;
if (info.GetArg(1).Length == 0) if (info.GetArg(1).Length == 0)
@@ -279,13 +277,15 @@ public partial class CS2_SimpleAdmin
_database = new Database.Database(_dbConnectionString); _database = new Database.Database(_dbConnectionString);
AddTimer(2.0f, () => AddTimer(2.5f, () =>
{ {
var ipAddress = ConVar.Find("ip")?.StringValue; var ipAddress = ConVar.Find("ip")?.StringValue;
if (string.IsNullOrEmpty(ipAddress) || ipAddress.StartsWith("0.0.0")) if (string.IsNullOrEmpty(ipAddress) || ipAddress.StartsWith("0.0.0"))
{ {
ipAddress = Helper.GetServerIp();
Logger.LogError("Unable to get server ip, Check that you have added the correct start parameter \"-ip <ip>\""); Logger.LogError("Unable to get server ip, Check that you have added the correct start parameter \"-ip <ip>\"");
Logger.LogError($"Using alternative method... Server IP {ipAddress}");
} }
var address = $"{ipAddress}:{ConVar.Find("hostport")?.GetPrimitiveValue<int>()}"; var address = $"{ipAddress}:{ConVar.Find("hostport")?.GetPrimitiveValue<int>()}";
@@ -341,7 +341,7 @@ public partial class CS2_SimpleAdmin
} }
} }
}); });
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); });
AddTimer(61.0f, () => AddTimer(61.0f, () =>
{ {

View File

@@ -12,6 +12,7 @@ using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -23,17 +24,20 @@ namespace CS2_SimpleAdmin
private static readonly string AssemblyName = Assembly.GetExecutingAssembly().GetName().Name ?? ""; private static readonly string AssemblyName = Assembly.GetExecutingAssembly().GetName().Name ?? "";
private static readonly string CfgPath = $"{Server.GameDirectory}/csgo/addons/counterstrikesharp/configs/plugins/{AssemblyName}/{AssemblyName}.json"; private static readonly string CfgPath = $"{Server.GameDirectory}/csgo/addons/counterstrikesharp/configs/plugins/{AssemblyName}/{AssemblyName}.json";
public delegate nint CNetworkSystem_UpdatePublicIp(nint a1);
public static CNetworkSystem_UpdatePublicIp? _networkSystemUpdatePublicIp;
internal static CS2_SimpleAdminConfig? Config { get; set; } internal static CS2_SimpleAdminConfig? Config { get; set; }
public static bool IsDebugBuild public static bool IsDebugBuild
{ {
get get
{ {
#if DEBUG #if DEBUG
return true; return true;
#else #else
return false; return false;
#endif #endif
} }
} }
@@ -60,7 +64,7 @@ namespace CS2_SimpleAdmin
public static List<CCSPlayerController> GetValidPlayers() public static List<CCSPlayerController> GetValidPlayers()
{ {
return Utilities.GetPlayers().FindAll(p => p is return Utilities.GetPlayers().FindAll(p => p is
{ IsBot: false, IsHLTV: false }); { IsBot: false, IsHLTV: false });
} }
public static IEnumerable<CCSPlayerController?> GetValidPlayersWithBots() public static IEnumerable<CCSPlayerController?> GetValidPlayersWithBots()
@@ -310,6 +314,33 @@ namespace CS2_SimpleAdmin
return message; return message;
} }
public static string GetServerIp()
{
var network_system = NativeAPI.GetValveInterface(0, "NetworkSystemVersion001");
unsafe
{
if (_networkSystemUpdatePublicIp == null)
{
var funcPtr = *(nint*)(*(nint*)(network_system) + 256);
_networkSystemUpdatePublicIp = Marshal.GetDelegateForFunctionPointer<CNetworkSystem_UpdatePublicIp>(funcPtr);
}
/*
struct netadr_t
{
uint32_t type
uint8_t ip[4]
uint16_t port
}
*/
// + 4 to skip type, because the size of uint32_t is 4 bytes
var ipBytes = (byte*)(_networkSystemUpdatePublicIp(network_system) + 4);
// port is always 0, use the one from convar "hostport"
return $"{ipBytes[0]}.{ipBytes[1]}.{ipBytes[2]}.{ipBytes[3]}";
}
}
public static void UpdateConfig<T>(T config) where T : BasePluginConfig, new() public static void UpdateConfig<T>(T config) where T : BasePluginConfig, new()
{ {
// get newest config version // get newest config version

View File

@@ -1,7 +1,9 @@
using CounterStrikeSharp.API; using System.Text;
using CounterStrikeSharp.API;
using Dapper; using Dapper;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MySqlConnector; using MySqlConnector;
using Serilog.Core;
namespace CS2_SimpleAdmin; namespace CS2_SimpleAdmin;
@@ -256,6 +258,7 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
catch { } catch { }
} }
/*
public async Task CheckOnlinePlayers(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players) public async Task CheckOnlinePlayers(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players)
{ {
try try
@@ -294,6 +297,75 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
} }
catch { } catch { }
} }
*/
public async Task CheckOnlinePlayers(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players)
{
try
{
await using var connection = await database.GetConnectionAsync();
bool checkIpBans = config.BanType > 0;
var filteredPlayers = players.Where(p => p.UserId.HasValue).ToList();
var steamIds = filteredPlayers.Select(p => p.SteamID).Distinct().ToList();
var ipAddresses = filteredPlayers
.Where(p => !string.IsNullOrEmpty(p.IpAddress))
.Select(p => p.IpAddress)
.Distinct()
.ToList();
var sql = new StringBuilder();
sql.Append("SELECT `player_steamid`, `player_ip` FROM `sa_bans` WHERE `status` = 'ACTIVE' ");
if (config.MultiServerMode)
{
sql.Append("AND (player_steamid IN @SteamIDs ");
if (checkIpBans && ipAddresses.Count != 0)
{
sql.Append("OR player_ip IN @IpAddresses");
}
sql.Append(')');
}
else
{
sql.Append("AND server_id = @ServerId AND (player_steamid IN @SteamIDs ");
if (checkIpBans && ipAddresses.Count != 0)
{
sql.Append("OR player_ip IN @IpAddresses");
}
sql.Append(')');
}
var bannedPlayers = await connection.QueryAsync<(ulong PlayerSteamID, string PlayerIP)>(
sql.ToString(),
new
{
SteamIDs = steamIds,
IpAddresses = checkIpBans ? ipAddresses : [],
ServerId = CS2_SimpleAdmin.ServerId
});
var valueTuples = bannedPlayers.ToList();
var bannedSteamIds = valueTuples.Select(b => b.PlayerSteamID).ToHashSet();
var bannedIps = valueTuples.Select(b => b.PlayerIP).ToHashSet();
foreach (var player in filteredPlayers.Where(player => bannedSteamIds.Contains(player.SteamID) ||
(checkIpBans && bannedIps.Contains(player.IpAddress ?? ""))))
{
if (!player.UserId.HasValue) continue;
await Server.NextFrameAsync(() =>
{
Helper.KickPlayer(player.UserId.Value, "Banned");
});
}
}
catch (Exception ex)
{
CS2_SimpleAdmin._logger?.LogError($"Error checking online players: {ex.Message}");
}
}
public async Task ExpireOldBans() public async Task ExpireOldBans()
{ {

View File

@@ -1 +1 @@
1.4.5a 1.4.6a