mirror of
https://github.com/daffyyyy/CS2-SimpleAdmin.git
synced 2026-02-18 18:49:23 +00:00
1.4.4a
- MultiServerMode fix - New feature `TimeMode`
This commit is contained in:
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -22,9 +22,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.x
|
||||||
- name: Restore
|
- name: Restore
|
||||||
@@ -38,9 +38,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.x
|
||||||
- name: Restore
|
- name: Restore
|
||||||
@@ -55,13 +55,13 @@ jobs:
|
|||||||
${{ env.OUTPUT_PATH }}/Microsoft.DotNet.PlatformAbstractions.dll \
|
${{ env.OUTPUT_PATH }}/Microsoft.DotNet.PlatformAbstractions.dll \
|
||||||
${{ env.OUTPUT_PATH }}/Microsoft.Extensions.DependencyModel.dll \
|
${{ env.OUTPUT_PATH }}/Microsoft.Extensions.DependencyModel.dll \
|
||||||
- name: Zip
|
- name: Zip
|
||||||
uses: thedoctor0/zip-release@0.7.5
|
uses: thedoctor0/zip-release@0.7.6
|
||||||
with:
|
with:
|
||||||
type: 'zip'
|
type: 'zip'
|
||||||
filename: '${{ env.PROJECT_NAME }}.zip'
|
filename: '${{ env.PROJECT_NAME }}.zip'
|
||||||
path: ${{ env.OUTPUT_PATH }}
|
path: ${{ env.OUTPUT_PATH }}
|
||||||
- name: CS2-SimpleAdmin
|
- name: CS2-SimpleAdmin
|
||||||
uses: ncipollo/release-action@v1.12.0
|
uses: ncipollo/release-action@v1.14.0
|
||||||
with:
|
with:
|
||||||
artifacts: "${{ env.PROJECT_NAME }}.zip"
|
artifacts: "${{ env.PROJECT_NAME }}.zip"
|
||||||
name: "Build ${{ env.BUILD_NUMBER }}"
|
name: "Build ${{ env.BUILD_NUMBER }}"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ using System.Collections.Concurrent;
|
|||||||
|
|
||||||
namespace CS2_SimpleAdmin;
|
namespace CS2_SimpleAdmin;
|
||||||
|
|
||||||
[MinimumApiVersion(220)]
|
[MinimumApiVersion(225)]
|
||||||
public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdminConfig>
|
public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdminConfig>
|
||||||
{
|
{
|
||||||
public static CS2_SimpleAdmin Instance { get; private set; } = new();
|
public static CS2_SimpleAdmin Instance { get; private set; } = new();
|
||||||
@@ -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.3d";
|
public override string ModuleVersion => "1.4.4a";
|
||||||
|
|
||||||
public CS2_SimpleAdminConfig Config { get; set; } = new();
|
public CS2_SimpleAdminConfig Config { get; set; } = new();
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.225" />
|
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.228" />
|
||||||
<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.14.1" />
|
||||||
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
||||||
|
|||||||
@@ -142,6 +142,9 @@ namespace CS2_SimpleAdmin
|
|||||||
[JsonPropertyName("BanType")]
|
[JsonPropertyName("BanType")]
|
||||||
public int BanType { get; set; } = 1;
|
public int BanType { get; set; } = 1;
|
||||||
|
|
||||||
|
[JsonPropertyName("TimeMode")]
|
||||||
|
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; // 7 days
|
||||||
[JsonPropertyName("MultiServerMode")]
|
[JsonPropertyName("MultiServerMode")]
|
||||||
|
|||||||
16
Events.cs
16
Events.cs
@@ -148,7 +148,6 @@ public partial class CS2_SimpleAdmin
|
|||||||
string muteType = mute.type;
|
string muteType = mute.type;
|
||||||
DateTime ends = mute.ends;
|
DateTime ends = mute.ends;
|
||||||
int duration = mute.duration;
|
int duration = mute.duration;
|
||||||
|
|
||||||
switch (muteType)
|
switch (muteType)
|
||||||
{
|
{
|
||||||
// Apply mute penalty based on mute type
|
// Apply mute penalty based on mute type
|
||||||
@@ -275,7 +274,7 @@ public partial class CS2_SimpleAdmin
|
|||||||
{
|
{
|
||||||
var ipAddress = ConVar.Find("ip")?.StringValue;
|
var ipAddress = ConVar.Find("ip")?.StringValue;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(ipAddress))
|
if (string.IsNullOrEmpty(ipAddress) || ipAddress.StartsWith("0.0.0"))
|
||||||
{
|
{
|
||||||
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>\"");
|
||||||
}
|
}
|
||||||
@@ -352,8 +351,8 @@ public partial class CS2_SimpleAdmin
|
|||||||
|
|
||||||
var players = Helper.GetValidPlayers();
|
var players = Helper.GetValidPlayers();
|
||||||
var onlinePlayers = players
|
var onlinePlayers = players
|
||||||
.Where(player => player.IpAddress != null && player.SteamID.ToString().Length == 17)
|
.Where(player => player.IpAddress != null)
|
||||||
.Select(player => (player.IpAddress, player.SteamID, player.UserId))
|
.Select(player => (player.IpAddress, player.SteamID, player.UserId, player.Slot))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
@@ -363,18 +362,25 @@ public partial class CS2_SimpleAdmin
|
|||||||
MuteManager muteManager = new(_database);
|
MuteManager muteManager = new(_database);
|
||||||
|
|
||||||
await banManager.ExpireOldBans();
|
await banManager.ExpireOldBans();
|
||||||
await muteManager.ExpireOldMutes();
|
|
||||||
await adminManager.DeleteOldAdmins();
|
await adminManager.DeleteOldAdmins();
|
||||||
|
|
||||||
BannedPlayers.Clear();
|
BannedPlayers.Clear();
|
||||||
|
|
||||||
if (onlinePlayers.Count > 0)
|
if (onlinePlayers.Count > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await banManager.CheckOnlinePlayers(onlinePlayers);
|
await banManager.CheckOnlinePlayers(onlinePlayers);
|
||||||
|
if (Config.TimeMode == 0)
|
||||||
|
{
|
||||||
|
await muteManager.CheckOnlineModeMutes(onlinePlayers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await muteManager.ExpireOldMutes();
|
||||||
|
|
||||||
await Server.NextFrameAsync(() =>
|
await Server.NextFrameAsync(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -165,8 +165,8 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
|
|||||||
var sql = "";
|
var sql = "";
|
||||||
|
|
||||||
sql = config.MultiServerMode
|
sql = config.MultiServerMode
|
||||||
? "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND server_id = @serverid"
|
? "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP)"
|
||||||
: "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP)";
|
: "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND server_id = @serverid";
|
||||||
|
|
||||||
int banCount;
|
int banCount;
|
||||||
|
|
||||||
@@ -210,16 +210,10 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
|
|||||||
{
|
{
|
||||||
await using var connection = await database.GetConnectionAsync();
|
await using var connection = await database.GetConnectionAsync();
|
||||||
|
|
||||||
string sqlRetrieveBans;
|
var sqlRetrieveBans = config.MultiServerMode
|
||||||
if (config.MultiServerMode)
|
? "SELECT id FROM sa_bans WHERE (player_steamid = @pattern OR player_name = @pattern OR player_ip = @pattern) AND status = 'ACTIVE'"
|
||||||
{
|
: "SELECT id FROM sa_bans WHERE (player_steamid = @pattern OR player_name = @pattern OR player_ip = @pattern) AND status = 'ACTIVE' AND server_id = @serverid";
|
||||||
sqlRetrieveBans = "SELECT id FROM sa_bans WHERE (player_steamid = @pattern OR player_name = @pattern OR player_ip = @pattern) AND status = 'ACTIVE' " +
|
|
||||||
"AND server_id = @serverid";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sqlRetrieveBans = "SELECT id FROM sa_bans WHERE (player_steamid = @pattern OR player_name = @pattern OR player_ip = @pattern) AND status = 'ACTIVE'";
|
|
||||||
}
|
|
||||||
var bans = await connection.QueryAsync(sqlRetrieveBans, new { pattern = playerPattern, serverid = CS2_SimpleAdmin.ServerId });
|
var bans = await connection.QueryAsync(sqlRetrieveBans, new { pattern = playerPattern, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
|
|
||||||
var bansList = bans as dynamic[] ?? bans.ToArray();
|
var bansList = bans as dynamic[] ?? bans.ToArray();
|
||||||
@@ -262,25 +256,18 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CheckOnlinePlayers(List<(string? IpAddress, ulong SteamID, int? UserId)> players)
|
public async Task CheckOnlinePlayers(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var connection = await database.GetConnectionAsync();
|
await using var connection = await database.GetConnectionAsync();
|
||||||
string sql;
|
|
||||||
bool checkIpBans = config.BanType > 0;
|
bool checkIpBans = config.BanType > 0;
|
||||||
|
|
||||||
if (config.MultiServerMode)
|
var sql = config.MultiServerMode
|
||||||
{
|
? "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND status = 'ACTIVE'"
|
||||||
sql = "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND status = 'ACTIVE' AND" +
|
: "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND status = 'ACTIVE' AND server_id = @serverid";
|
||||||
" server_id = @serverid";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sql = "SELECT COUNT(*) FROM sa_bans WHERE (player_steamid = @PlayerSteamID OR player_ip = @PlayerIP) AND status = 'ACTIVE'";
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var (IpAddress, SteamID, UserId) in players)
|
foreach (var (IpAddress, SteamID, UserId, Slot) in players)
|
||||||
{
|
{
|
||||||
if (!UserId.HasValue) continue;
|
if (!UserId.HasValue) continue;
|
||||||
|
|
||||||
@@ -336,7 +323,6 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
|
|||||||
`duration` > 0
|
`duration` > 0
|
||||||
AND
|
AND
|
||||||
ends <= @currentTime
|
ends <= @currentTime
|
||||||
AND server_id = @serverid
|
|
||||||
""" : """
|
""" : """
|
||||||
|
|
||||||
UPDATE sa_bans
|
UPDATE sa_bans
|
||||||
@@ -348,6 +334,7 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
|
|||||||
`duration` > 0
|
`duration` > 0
|
||||||
AND
|
AND
|
||||||
ends <= @currentTime
|
ends <= @currentTime
|
||||||
|
AND server_id = @serverid
|
||||||
""";
|
""";
|
||||||
|
|
||||||
await connection.ExecuteAsync(sql, new { currentTime, serverid = CS2_SimpleAdmin.ServerId });
|
await connection.ExecuteAsync(sql, new { currentTime, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
@@ -364,7 +351,6 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
|
|||||||
status = 'ACTIVE'
|
status = 'ACTIVE'
|
||||||
AND
|
AND
|
||||||
ends <= @ipBansTime
|
ends <= @ipBansTime
|
||||||
AND server_id = @serverid
|
|
||||||
""" : """
|
""" : """
|
||||||
|
|
||||||
UPDATE sa_bans
|
UPDATE sa_bans
|
||||||
@@ -374,6 +360,7 @@ internal class BanManager(Database.Database database, CS2_SimpleAdminConfig conf
|
|||||||
status = 'ACTIVE'
|
status = 'ACTIVE'
|
||||||
AND
|
AND
|
||||||
ends <= @ipBansTime
|
ends <= @ipBansTime
|
||||||
|
AND server_id = @serverid
|
||||||
""";
|
""";
|
||||||
|
|
||||||
await connection.ExecuteAsync(sql, new { ipBansTime, CS2_SimpleAdmin.ServerId });
|
await connection.ExecuteAsync(sql, new { ipBansTime, CS2_SimpleAdmin.ServerId });
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dapper;
|
using CounterStrikeSharp.API.Core;
|
||||||
|
using Dapper;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CS2_SimpleAdmin;
|
namespace CS2_SimpleAdmin;
|
||||||
@@ -96,16 +97,20 @@ internal class MuteManager(Database.Database database)
|
|||||||
{
|
{
|
||||||
await using var connection = await database.GetConnectionAsync();
|
await using var connection = await database.GetConnectionAsync();
|
||||||
var currentTime = DateTime.UtcNow.ToLocalTime();
|
var currentTime = DateTime.UtcNow.ToLocalTime();
|
||||||
string sql;
|
var sql = "";
|
||||||
|
|
||||||
if (CS2_SimpleAdmin.Instance.Config.MultiServerMode)
|
if (CS2_SimpleAdmin.Instance.Config.MultiServerMode)
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime) " +
|
sql = CS2_SimpleAdmin.Instance.Config.TimeMode == 1
|
||||||
"AND server_id = @serverid";
|
? "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)"
|
||||||
|
: "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR duration > COALESCE(passed, 0))";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime)";
|
sql = CS2_SimpleAdmin.Instance.Config.TimeMode == 1
|
||||||
|
? "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR ends > @CurrentTime) AND server_id = @serverid"
|
||||||
|
: "SELECT * FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND status = 'ACTIVE' AND (duration = 0 OR duration > COALESCE(passed, 0)) AND server_id = @serverid";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var parameters = new { PlayerSteamID = steamId, CurrentTime = currentTime, serverid = CS2_SimpleAdmin.ServerId };
|
var parameters = new { PlayerSteamID = steamId, CurrentTime = currentTime, serverid = CS2_SimpleAdmin.ServerId };
|
||||||
@@ -125,8 +130,8 @@ internal class MuteManager(Database.Database database)
|
|||||||
await using var connection = await database.GetConnectionAsync();
|
await using var connection = await database.GetConnectionAsync();
|
||||||
|
|
||||||
var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode
|
var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode
|
||||||
? "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND server_id = @serverid"
|
? "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID"
|
||||||
: "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID";
|
: "SELECT COUNT(*) FROM sa_mutes WHERE player_steamid = @PlayerSteamID AND server_id = @serverid";
|
||||||
|
|
||||||
var muteCount = await connection.ExecuteScalarAsync<int>(sql, new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId });
|
var muteCount = await connection.ExecuteScalarAsync<int>(sql, new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
return muteCount;
|
return muteCount;
|
||||||
@@ -137,6 +142,56 @@ internal class MuteManager(Database.Database database)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task CheckOnlineModeMutes(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int batchSize = 10;
|
||||||
|
await using var connection = await database.GetConnectionAsync();
|
||||||
|
|
||||||
|
var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode
|
||||||
|
? "UPDATE `sa_mutes` SET passed = COALESCE(passed, 0) + 1 WHERE (player_steamid = @PlayerSteamID) AND duration > 0 AND status = 'ACTIVE'"
|
||||||
|
: "UPDATE `sa_mutes` SET passed = COALESCE(passed, 0) + 1 WHERE (player_steamid = @PlayerSteamID) AND duration > 0 AND status = 'ACTIVE' AND server_id = @serverid";
|
||||||
|
/*
|
||||||
|
foreach (var (IpAddress, SteamID, UserId, Slot) in players)
|
||||||
|
{
|
||||||
|
await connection.ExecuteAsync(sql,
|
||||||
|
new { PlayerSteamID = SteamID, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
|
}*/
|
||||||
|
|
||||||
|
for (var i = 0; i < players.Count; i += batchSize)
|
||||||
|
{
|
||||||
|
var batch = players.Skip(i).Take(batchSize);
|
||||||
|
var parametersList = new List<object>();
|
||||||
|
|
||||||
|
foreach (var (IpAddress, SteamID, UserId, Slot) in batch)
|
||||||
|
{
|
||||||
|
parametersList.Add(new { PlayerSteamID = SteamID, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
|
}
|
||||||
|
|
||||||
|
await connection.ExecuteAsync(sql, parametersList);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode
|
||||||
|
? "SELECT * FROM `sa_mutes` WHERE player_steamid = @PlayerSteamID AND passed >= duration AND duration > 0 AND status = 'ACTIVE'"
|
||||||
|
: "SELECT * FROM `sa_mutes` WHERE player_steamid = @PlayerSteamID AND passed >= duration AND duration > 0 AND status = 'ACTIVE' AND server_id = @serverid";
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var (IpAddress, SteamID, UserId, Slot) in players)
|
||||||
|
{
|
||||||
|
var muteRecords = await connection.QueryAsync(sql, new { PlayerSteamID = SteamID, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
|
|
||||||
|
foreach (var muteRecord in muteRecords)
|
||||||
|
{
|
||||||
|
DateTime endDateTime = muteRecord.ends;
|
||||||
|
PlayerPenaltyManager.RemovePenaltiesByDateTime(Slot, endDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
public async Task UnmutePlayer(string playerPattern, string adminSteamId, string reason, int type = 0)
|
public async Task UnmutePlayer(string playerPattern, string adminSteamId, string reason, int type = 0)
|
||||||
{
|
{
|
||||||
if (playerPattern.Length <= 1)
|
if (playerPattern.Length <= 1)
|
||||||
@@ -160,12 +215,12 @@ internal class MuteManager(Database.Database database)
|
|||||||
if (CS2_SimpleAdmin.Instance.Config.MultiServerMode)
|
if (CS2_SimpleAdmin.Instance.Config.MultiServerMode)
|
||||||
{
|
{
|
||||||
sqlRetrieveMutes = "SELECT id FROM sa_mutes WHERE (player_steamid = @pattern OR player_name = @pattern) AND " +
|
sqlRetrieveMutes = "SELECT id FROM sa_mutes WHERE (player_steamid = @pattern OR player_name = @pattern) AND " +
|
||||||
"type = @muteType AND status = 'ACTIVE' AND server_id = @serverid";
|
"type = @muteType AND status = 'ACTIVE'";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sqlRetrieveMutes = "SELECT id FROM sa_mutes WHERE (player_steamid = @pattern OR player_name = @pattern) AND " +
|
sqlRetrieveMutes = "SELECT id FROM sa_mutes WHERE (player_steamid = @pattern OR player_name = @pattern) AND " +
|
||||||
"type = @muteType AND status = 'ACTIVE'";
|
"type = @muteType AND status = 'ACTIVE' AND server_id = @serverid";
|
||||||
}
|
}
|
||||||
|
|
||||||
var mutes = await connection.QueryAsync(sqlRetrieveMutes, new { pattern = playerPattern, muteType, serverid = CS2_SimpleAdmin.ServerId });
|
var mutes = await connection.QueryAsync(sqlRetrieveMutes, new { pattern = playerPattern, muteType, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
@@ -212,10 +267,20 @@ internal class MuteManager(Database.Database database)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var connection = await database.GetConnectionAsync();
|
await using var connection = await database.GetConnectionAsync();
|
||||||
|
var sql = "";
|
||||||
|
|
||||||
var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode
|
if (CS2_SimpleAdmin.Instance.Config.MultiServerMode)
|
||||||
|
{
|
||||||
|
sql = CS2_SimpleAdmin.Instance.Config.TimeMode == 1
|
||||||
|
? "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime"
|
||||||
|
: "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND `passed` >= `duration`";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql = CS2_SimpleAdmin.Instance.Config.TimeMode == 1
|
||||||
? "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime AND server_id = @serverid"
|
? "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime AND server_id = @serverid"
|
||||||
: "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND ends <= @CurrentTime";
|
: "UPDATE sa_mutes SET status = 'EXPIRED' WHERE status = 'ACTIVE' AND `duration` > 0 AND `passed` >= `duration` AND server_id = @serverid";
|
||||||
|
}
|
||||||
|
|
||||||
await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.UtcNow.ToLocalTime(), serverid = CS2_SimpleAdmin.ServerId });
|
await connection.ExecuteAsync(sql, new { CurrentTime = DateTime.UtcNow.ToLocalTime(), serverid = CS2_SimpleAdmin.ServerId });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ public enum PenaltyType
|
|||||||
|
|
||||||
public class PlayerPenaltyManager
|
public class PlayerPenaltyManager
|
||||||
{
|
{
|
||||||
private static readonly ConcurrentDictionary<int, Dictionary<PenaltyType, List<(DateTime EndDateTime, int Duration)>>> Penalties =
|
private static readonly ConcurrentDictionary<int, Dictionary<PenaltyType, List<(DateTime EndDateTime, int Duration, bool Passed)>>> Penalties =
|
||||||
new();
|
new();
|
||||||
|
|
||||||
// Add a penalty for a player
|
// Add a penalty for a player
|
||||||
public static void AddPenalty(int slot, PenaltyType penaltyType, DateTime endDateTime, int durationSeconds)
|
public static void AddPenalty(int slot, PenaltyType penaltyType, DateTime endDateTime, int durationInMinutes)
|
||||||
{
|
{
|
||||||
Penalties.AddOrUpdate(slot,
|
Penalties.AddOrUpdate(slot,
|
||||||
(_) =>
|
(_) =>
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<PenaltyType, List<(DateTime, int)>>
|
var dict = new Dictionary<PenaltyType, List<(DateTime, int, bool)>>
|
||||||
{
|
{
|
||||||
[penaltyType] = [(endDateTime, durationSeconds)]
|
[penaltyType] = [(endDateTime, durationInMinutes, false)]
|
||||||
};
|
};
|
||||||
return dict;
|
return dict;
|
||||||
},
|
},
|
||||||
@@ -30,11 +30,11 @@ public class PlayerPenaltyManager
|
|||||||
{
|
{
|
||||||
if (!existingDict.TryGetValue(penaltyType, out var value))
|
if (!existingDict.TryGetValue(penaltyType, out var value))
|
||||||
{
|
{
|
||||||
value = new List<(DateTime, int)>();
|
value = new List<(DateTime, int, bool)>();
|
||||||
existingDict[penaltyType] = value;
|
existingDict[penaltyType] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.Add((endDateTime, durationSeconds));
|
value.Add((endDateTime, durationInMinutes, false));
|
||||||
return existingDict;
|
return existingDict;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -47,13 +47,16 @@ public class PlayerPenaltyManager
|
|||||||
!penaltyDict.TryGetValue(penaltyType, out var penaltiesList)) return false;
|
!penaltyDict.TryGetValue(penaltyType, out var penaltiesList)) return false;
|
||||||
//Console.WriteLine($"Found penalties for player with slot {slot} and penalty type {penaltyType}");
|
//Console.WriteLine($"Found penalties for player with slot {slot} and penalty type {penaltyType}");
|
||||||
|
|
||||||
|
if (CS2_SimpleAdmin.Instance.Config.TimeMode == 0)
|
||||||
|
return penaltiesList.Count != 0;
|
||||||
|
|
||||||
var now = DateTime.UtcNow.ToLocalTime();
|
var now = DateTime.UtcNow.ToLocalTime();
|
||||||
|
|
||||||
// Check if any active penalties exist
|
// Check if any active penalties exist
|
||||||
foreach (var penalty in penaltiesList.ToList())
|
foreach (var penalty in penaltiesList.ToList())
|
||||||
{
|
{
|
||||||
// Check if the penalty is still active
|
// Check if the penalty is still active
|
||||||
if (penalty.Duration > 0 && now >= penalty.EndDateTime.AddSeconds(penalty.Duration))
|
if (penalty.Duration > 0 && now >= penalty.EndDateTime)
|
||||||
{
|
{
|
||||||
//Console.WriteLine($"Removing expired penalty for player with slot {slot} and penalty type {penaltyType}");
|
//Console.WriteLine($"Removing expired penalty for player with slot {slot} and penalty type {penaltyType}");
|
||||||
penaltiesList.Remove(penalty); // Remove expired penalty
|
penaltiesList.Remove(penalty); // Remove expired penalty
|
||||||
@@ -80,7 +83,7 @@ public class PlayerPenaltyManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the end datetime and duration of penalties for a player and penalty type
|
// Get the end datetime and duration of penalties for a player and penalty type
|
||||||
public static List<(DateTime EndDateTime, int Duration)> GetPlayerPenalties(int slot, PenaltyType penaltyType)
|
public static List<(DateTime EndDateTime, int Duration, bool Passed)> GetPlayerPenalties(int slot, PenaltyType penaltyType)
|
||||||
{
|
{
|
||||||
if (Penalties.TryGetValue(slot, out var penaltyDict) &&
|
if (Penalties.TryGetValue(slot, out var penaltyDict) &&
|
||||||
penaltyDict.TryGetValue(penaltyType, out var penaltiesList))
|
penaltyDict.TryGetValue(penaltyType, out var penaltiesList))
|
||||||
@@ -113,26 +116,64 @@ public class PlayerPenaltyManager
|
|||||||
// Remove all penalties of a selected type from a specific player
|
// Remove all penalties of a selected type from a specific player
|
||||||
public static void RemovePenaltiesByType(int slot, PenaltyType penaltyType)
|
public static void RemovePenaltiesByType(int slot, PenaltyType penaltyType)
|
||||||
{
|
{
|
||||||
if (Penalties.TryGetValue(slot, out Dictionary<PenaltyType, List<(DateTime EndDateTime, int Duration)>>? penaltyDict) &&
|
if (Penalties.TryGetValue(slot, out var penaltyDict) &&
|
||||||
penaltyDict.ContainsKey(penaltyType))
|
penaltyDict.ContainsKey(penaltyType))
|
||||||
{
|
{
|
||||||
penaltyDict.Remove(penaltyType);
|
penaltyDict.Remove(penaltyType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void RemovePenaltiesByDateTime(int slot, DateTime dateTime)
|
||||||
|
{
|
||||||
|
if (!Penalties.TryGetValue(slot, out var penaltyDict)) return;
|
||||||
|
|
||||||
|
foreach (var penaltiesList in penaltyDict.Values)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < penaltiesList.Count; i++)
|
||||||
|
{
|
||||||
|
if (penaltiesList[i].EndDateTime != dateTime) continue;
|
||||||
|
// Create a copy of the penalty
|
||||||
|
var penalty = penaltiesList[i];
|
||||||
|
|
||||||
|
// Update the end datetime of the copied penalty to the current datetime
|
||||||
|
penalty.Passed = true;
|
||||||
|
|
||||||
|
// Replace the original penalty with the modified one
|
||||||
|
penaltiesList[i] = penalty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove all expired penalties for all players and penalty types
|
// Remove all expired penalties for all players and penalty types
|
||||||
public static void RemoveExpiredPenalties()
|
public static void RemoveExpiredPenalties()
|
||||||
{
|
{
|
||||||
var now = DateTime.UtcNow.ToLocalTime();
|
if (CS2_SimpleAdmin.Instance.Config.TimeMode == 0)
|
||||||
foreach (var kvp in Penalties.ToList()) // Use ToList to avoid modification while iterating
|
{
|
||||||
|
foreach (var (playerSlot, penaltyDict) in Penalties.ToList()) // Use ToList to avoid modification while iterating
|
||||||
{
|
{
|
||||||
var playerSlot = kvp.Key;
|
|
||||||
var penaltyDict = kvp.Value;
|
|
||||||
|
|
||||||
// Remove expired penalties for the player
|
// Remove expired penalties for the player
|
||||||
foreach (var penaltiesList in penaltyDict.Values)
|
foreach (var penaltiesList in penaltyDict.Values)
|
||||||
{
|
{
|
||||||
penaltiesList.RemoveAll(p => p.Duration > 0 && now >= p.EndDateTime.AddSeconds(p.Duration).ToLocalTime());
|
penaltiesList.RemoveAll(p => p is { Duration: > 0, Passed: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove player slot if no penalties left
|
||||||
|
if (penaltyDict.Count == 0)
|
||||||
|
{
|
||||||
|
Penalties.TryRemove(playerSlot, out _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = DateTime.UtcNow.ToLocalTime();
|
||||||
|
foreach (var (playerSlot, penaltyDict) in Penalties.ToList()) // Use ToList to avoid modification while iterating
|
||||||
|
{
|
||||||
|
// Remove expired penalties for the player
|
||||||
|
foreach (var penaltiesList in penaltyDict.Values)
|
||||||
|
{
|
||||||
|
penaltiesList.RemoveAll(p => p.Duration > 0 && now >= p.EndDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove player slot if no penalties left
|
// Remove player slot if no penalties left
|
||||||
|
|||||||
Reference in New Issue
Block a user