mirror of
https://github.com/daffyyyy/CS2-SimpleAdmin.git
synced 2026-09-27 20:17:04 +02:00
CSSPanel Support
This commit is contained in:
parent
d30ac80a36
commit
f01beebea9
21 changed files with 762 additions and 214 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -3,4 +3,5 @@ obj/
|
|||
.vs/
|
||||
.git
|
||||
.vscode/
|
||||
.idea/
|
||||
.idea/
|
||||
*.sln
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34309.116
|
||||
VisualStudioVersion = 17.5.002.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CS2-SimpleAdmin", "CS2-SimpleAdmin\CS2-SimpleAdmin.csproj", "{CC7C3B4D-26C9-4DE7-B4E1-0864350468D0}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CS2-SimpleAdmin", "CS2-SimpleAdmin\CS2-SimpleAdmin.csproj", "{10611B4A-49BC-4556-A000-C1F922C4979D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CS2-SimpleAdminApi", "CS2-SimpleAdminApi\CS2-SimpleAdminApi.csproj", "{8BEF0C35-7E4E-4BAF-B632-8584FAFCA922}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CS2-SimpleAdminApi", "CS2-SimpleAdminApi\CS2-SimpleAdminApi.csproj", "{2A46E7D8-A0AC-4EB2-BCEA-BBC9049A83DB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{264FAD58-0947-4A02-86C6-39FF99B8EA51}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CS2-SimpleAdmin_ExampleModule", "Modules\CS2-SimpleAdmin_ExampleModule\CS2-SimpleAdmin_ExampleModule.csproj", "{FD770842-F4CE-468A-A0DC-7A3A30A0CED6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
|
@ -13,19 +17,26 @@ Global
|
|||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CC7C3B4D-26C9-4DE7-B4E1-0864350468D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CC7C3B4D-26C9-4DE7-B4E1-0864350468D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CC7C3B4D-26C9-4DE7-B4E1-0864350468D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CC7C3B4D-26C9-4DE7-B4E1-0864350468D0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEF0C35-7E4E-4BAF-B632-8584FAFCA922}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8BEF0C35-7E4E-4BAF-B632-8584FAFCA922}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8BEF0C35-7E4E-4BAF-B632-8584FAFCA922}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEF0C35-7E4E-4BAF-B632-8584FAFCA922}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{10611B4A-49BC-4556-A000-C1F922C4979D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{10611B4A-49BC-4556-A000-C1F922C4979D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{10611B4A-49BC-4556-A000-C1F922C4979D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{10611B4A-49BC-4556-A000-C1F922C4979D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2A46E7D8-A0AC-4EB2-BCEA-BBC9049A83DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2A46E7D8-A0AC-4EB2-BCEA-BBC9049A83DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2A46E7D8-A0AC-4EB2-BCEA-BBC9049A83DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2A46E7D8-A0AC-4EB2-BCEA-BBC9049A83DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FD770842-F4CE-468A-A0DC-7A3A30A0CED6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FD770842-F4CE-468A-A0DC-7A3A30A0CED6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FD770842-F4CE-468A-A0DC-7A3A30A0CED6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FD770842-F4CE-468A-A0DC-7A3A30A0CED6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{FD770842-F4CE-468A-A0DC-7A3A30A0CED6} = {264FAD58-0947-4A02-86C6-39FF99B8EA51}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {86114444-059F-4DB8-9A55-E6D1BB76238D}
|
||||
SolutionGuid = {27D147C9-0BD5-467F-8602-83A82E4792D6}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
|||
Capabilities.RegisterPluginCapability(ICS2_SimpleAdminApi.PluginCapability, () => SimpleAdminApi);
|
||||
|
||||
new PlayerManager().CheckPlayersTimer();
|
||||
|
||||
ChatManager = new ChatManager();
|
||||
}
|
||||
|
||||
public override void OnAllPluginsLoaded(bool hotReload)
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
|
||||
// Execute ban command if necessary
|
||||
if (UnlockedCommands)
|
||||
if (UnlockedCommands && Config.BanIDBan)
|
||||
{
|
||||
Server.ExecuteCommand($"banid 1 {new SteamID(player.SteamID).SteamId3}");
|
||||
}
|
||||
|
|
@ -177,7 +177,7 @@ public partial class CS2_SimpleAdmin
|
|||
|
||||
Helper.LogCommand(caller, command);
|
||||
|
||||
if (UnlockedCommands)
|
||||
if (UnlockedCommands && Config.BanIDBan)
|
||||
Server.ExecuteCommand($"banid 1 {steamId.SteamId3}");
|
||||
|
||||
SimpleAdminApi?.OnPlayerPenaltiedAddedEvent(steamId, adminInfo, PenaltyType.Ban, reason, time);
|
||||
|
|
|
|||
|
|
@ -365,27 +365,29 @@ public partial class CS2_SimpleAdmin
|
|||
AdminManager.RemovePlayerAdminData(steamId);
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
if(!Config.IsCSSPanel)
|
||||
{
|
||||
await PermissionManager.CrateGroupsJsonFile();
|
||||
await PermissionManager.CreateAdminsJsonFile();
|
||||
|
||||
var adminsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/admins.json");
|
||||
var groupsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/groups.json");
|
||||
|
||||
await Server.NextFrameAsync(() =>
|
||||
Task.Run(async () =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(adminsFile))
|
||||
AddTimer(0.5f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
||||
if (!string.IsNullOrEmpty(groupsFile))
|
||||
AddTimer(1.0f, () => AdminManager.LoadAdminGroups(ModuleDirectory + "/data/groups.json"));
|
||||
if (!string.IsNullOrEmpty(adminsFile))
|
||||
AddTimer(1.5f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
||||
});
|
||||
});
|
||||
await PermissionManager.CreateGroupsJsonFile();
|
||||
await PermissionManager.CreateAdminsJsonFile();
|
||||
|
||||
//_ = _adminManager.GiveAllGroupsFlags();
|
||||
//_ = _adminManager.GiveAllFlags();
|
||||
var adminsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/admins.json");
|
||||
var groupsFile = await File.ReadAllTextAsync(Instance.ModuleDirectory + "/data/groups.json");
|
||||
|
||||
await Server.NextFrameAsync(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(adminsFile))
|
||||
AddTimer(0.5f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
||||
if (!string.IsNullOrEmpty(groupsFile))
|
||||
AddTimer(1.0f, () => AdminManager.LoadAdminGroups(ModuleDirectory + "/data/groups.json"));
|
||||
if (!string.IsNullOrEmpty(adminsFile))
|
||||
AddTimer(1.5f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
_ = PermissionManager.GiveAllFlags();
|
||||
}
|
||||
|
||||
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||
|
|
@ -761,6 +763,8 @@ public partial class CS2_SimpleAdmin
|
|||
var callerName = caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||
map = map.ToLower();
|
||||
|
||||
var wsMaps = Config.WorkshopMaps;
|
||||
|
||||
if (map.StartsWith("ws:"))
|
||||
{
|
||||
var issuedCommand = long.TryParse(map.Replace("ws:", ""), out var mapId)
|
||||
|
|
@ -776,14 +780,21 @@ public partial class CS2_SimpleAdmin
|
|||
{
|
||||
if (!Server.IsMapValid(map))
|
||||
{
|
||||
var msg = $"Map {map} not found.";
|
||||
if (command != null)
|
||||
command.ReplyToCommand(msg);
|
||||
else if (caller != null && caller.IsValid)
|
||||
caller.PrintToChat(msg);
|
||||
if(wsMaps.ContainsKey(map))
|
||||
{
|
||||
map = wsMaps.Where(m => m.Key == map).FirstOrDefault().Key;
|
||||
}
|
||||
else
|
||||
Server.PrintToConsole(msg);
|
||||
return;
|
||||
{
|
||||
var msg = $"Map {map} not found.";
|
||||
if (command != null)
|
||||
command.ReplyToCommand(msg);
|
||||
else if (caller != null && caller.IsValid)
|
||||
caller.PrintToChat(msg);
|
||||
else
|
||||
Server.PrintToConsole(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AddTimer(3.0f, () =>
|
||||
|
|
|
|||
|
|
@ -273,7 +273,8 @@ public partial class CS2_SimpleAdmin
|
|||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||
|
||||
// Set player's voice flags to muted
|
||||
player.VoiceFlags = VoiceFlags.Muted;
|
||||
if (!player.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
player.VoiceFlags |= VoiceFlags.Muted;
|
||||
|
||||
// Asynchronously handle mute logic
|
||||
Task.Run(async () =>
|
||||
|
|
@ -402,7 +403,8 @@ public partial class CS2_SimpleAdmin
|
|||
if (player != null && player.IsValid)
|
||||
{
|
||||
PlayerPenaltyManager.RemovePenaltiesByType(player.Slot, PenaltyType.Mute);
|
||||
player.VoiceFlags = VoiceFlags.Normal;
|
||||
if (player.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
player.VoiceFlags &= ~VoiceFlags.Muted;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -421,7 +423,8 @@ public partial class CS2_SimpleAdmin
|
|||
if (namePlayer != null && namePlayer.IsValid)
|
||||
{
|
||||
PlayerPenaltyManager.RemovePenaltiesByType(namePlayer.Slot, PenaltyType.Mute);
|
||||
namePlayer.VoiceFlags = VoiceFlags.Normal;
|
||||
if (namePlayer.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
namePlayer.VoiceFlags &= ~VoiceFlags.Muted;
|
||||
|
||||
if (namePlayer.UserId.HasValue && PlayersInfo[namePlayer.UserId.Value].TotalMutes > 0)
|
||||
PlayersInfo[namePlayer.UserId.Value].TotalMutes--;
|
||||
|
|
@ -491,6 +494,10 @@ public partial class CS2_SimpleAdmin
|
|||
var playerInfo = PlayersInfo[player.UserId.Value];
|
||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||
|
||||
// Set player's voice flags to muted
|
||||
if (!player.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
player.VoiceFlags |= VoiceFlags.Muted;
|
||||
|
||||
// Asynchronously handle silence logic
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -620,7 +627,8 @@ public partial class CS2_SimpleAdmin
|
|||
PlayerPenaltyManager.RemovePenaltiesByType(player.Slot, PenaltyType.Silence);
|
||||
|
||||
// Reset voice flags to normal
|
||||
player.VoiceFlags = VoiceFlags.Normal;
|
||||
if (player.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
player.VoiceFlags &= ~VoiceFlags.Muted;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -641,7 +649,8 @@ public partial class CS2_SimpleAdmin
|
|||
PlayerPenaltyManager.RemovePenaltiesByType(namePlayer.Slot, PenaltyType.Silence);
|
||||
|
||||
// Reset voice flags to normal
|
||||
namePlayer.VoiceFlags = VoiceFlags.Normal;
|
||||
if (namePlayer.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
namePlayer.VoiceFlags &= ~VoiceFlags.Muted;
|
||||
|
||||
if (namePlayer.UserId.HasValue && PlayersInfo[namePlayer.UserId.Value].TotalSilences > 0)
|
||||
PlayersInfo[namePlayer.UserId.Value].TotalSilences--;
|
||||
|
|
|
|||
136
CS2-SimpleAdmin/Commands/panelcommands.cs
Normal file
136
CS2-SimpleAdmin/Commands/panelcommands.cs
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Core.Translations;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Cvars;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Menu;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using CS2_SimpleAdmin.Managers;
|
||||
using CS2_SimpleAdmin.Menus;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
public partial class CS2_SimpleAdmin
|
||||
{
|
||||
[ConsoleCommand("css_panel_say", "Say to all players from the panel.")]
|
||||
[CommandHelper(1, "<message>")]
|
||||
[RequiresPermissions("@css/root")]
|
||||
public void OnPanelSayCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (!Config.IsCSSPanel) return;
|
||||
if (command.GetCommandString[command.GetCommandString.IndexOf(' ')..].Length == 0) return;
|
||||
|
||||
byte[] utf8BytesString = Encoding.UTF8.GetBytes(command.GetCommandString[command.GetCommandString.IndexOf(' ')..]);
|
||||
string utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||
|
||||
foreach (CCSPlayerController player in Utilities.GetPlayers().Where(p => !p.IsBot && !p.IsHLTV))
|
||||
{
|
||||
player.PrintToChat(StringExtensions.ReplaceColorTags(utf8String));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the server info and a list of players to the console
|
||||
*/
|
||||
[ConsoleCommand("css_query")]
|
||||
[CommandHelper(whoCanExecute: CommandUsage.SERVER_ONLY)]
|
||||
[RequiresPermissions("@css/root")]
|
||||
public void OnQueryCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
if (!Config.IsCSSPanel) return;
|
||||
|
||||
List<CCSPlayerController> playersToTarget = Utilities.GetPlayers().Where(player => caller!.CanTarget(player) && !player.IsHLTV).ToList();
|
||||
|
||||
string Map = Server.MapName;
|
||||
int Players = playersToTarget.Count;
|
||||
int MaxPlayers = Server.MaxPlayers;
|
||||
string[] Maps;
|
||||
|
||||
MaxPlayers = ConVar.Find("sv_visiblemaxplayers")?.GetPrimitiveValue<int>() ?? -1;
|
||||
MaxPlayers = MaxPlayers <= -1 ? Server.MaxPlayers : MaxPlayers;
|
||||
|
||||
try
|
||||
{
|
||||
Maps = Server.GetMapList();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Maps = Array.Empty<string>(); // return an empty array
|
||||
}
|
||||
|
||||
var server = new
|
||||
{
|
||||
map = Map,
|
||||
p = Players,
|
||||
mP = MaxPlayers,
|
||||
// maps = Maps,
|
||||
pr = ModuleVersion
|
||||
};
|
||||
|
||||
List<Task<object>> playerTasks = playersToTarget
|
||||
.FindAll(player => !player.IsBot && !player.IsHLTV && player.PlayerName != "")
|
||||
.Select(player =>
|
||||
{
|
||||
string deaths = player.ActionTrackingServices!.MatchStats.Deaths.ToString();
|
||||
string headshots = player.ActionTrackingServices!.MatchStats.HeadShotKills.ToString();
|
||||
string assists = player.ActionTrackingServices!.MatchStats.Assists.ToString();
|
||||
string damage = player.ActionTrackingServices!.MatchStats.Damage.ToString();
|
||||
string kills = player.ActionTrackingServices!.MatchStats.Kills.ToString();
|
||||
string time = player.ActionTrackingServices!.MatchStats.LiveTime.ToString();
|
||||
var user = new
|
||||
{
|
||||
id = player.UserId,
|
||||
// playerName = player.PlayerName,
|
||||
// ipAddress = player.IpAddress?.Split(":")[0],
|
||||
// accountId = player.AuthorizedSteamID?.AccountId.ToString(),
|
||||
// steamId2 = player.AuthorizedSteamID?.SteamId2,
|
||||
// steamId3 = player.AuthorizedSteamID?.SteamId3,
|
||||
s64 = player.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
// ping = player.Ping,
|
||||
t = player.Team,
|
||||
// clanName = player.ClanName,
|
||||
k = kills,
|
||||
d = deaths,
|
||||
// assists,
|
||||
// headshots,
|
||||
// damage,
|
||||
s = player.Score,
|
||||
// roundScore = player.RoundScore,
|
||||
// roundsWon = player.RoundsWon,
|
||||
// mvps = player.MVPs,
|
||||
// time, // ? Fix this, it's not the time the player has been connected
|
||||
// avatar = player.AuthorizedSteamID != null ? await GetProfilePictureAsync(player.AuthorizedSteamID.SteamId64.ToString(), true) : ""
|
||||
};
|
||||
return Task.FromResult((object)user);
|
||||
}).ToList();
|
||||
|
||||
List<object> players = new List<object>();
|
||||
try
|
||||
{
|
||||
players = Task.WhenAll(playerTasks).Result.ToList();
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
foreach (var innerEx in ex.InnerExceptions)
|
||||
{
|
||||
Logger.LogError(innerEx, "Error while querying players");
|
||||
}
|
||||
}
|
||||
|
||||
string jsonString = JsonConvert.SerializeObject(
|
||||
new
|
||||
{
|
||||
server,
|
||||
players
|
||||
}
|
||||
);
|
||||
|
||||
Server.PrintToConsole(jsonString);
|
||||
}
|
||||
}
|
||||
|
|
@ -307,7 +307,6 @@ public partial class CS2_SimpleAdmin
|
|||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_gravity")]
|
||||
[RequiresPermissions("@css/slay")]
|
||||
[CommandHelper(minArgs: 1, usage: "<#userid or name> <gravity>", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnGravityCommand(CCSPlayerController? caller, CommandInfo command)
|
||||
|
|
|
|||
|
|
@ -91,6 +91,21 @@ public class Discord
|
|||
];
|
||||
}
|
||||
|
||||
public class ChatLog
|
||||
{
|
||||
[JsonPropertyName("ChatLog_Enable")]
|
||||
public bool ChatLog_Enable { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("ChatLog_ExcludeMessageContains")]
|
||||
public string ExcludeMessageContains { get; set; } = "!./";
|
||||
|
||||
[JsonPropertyName("ChatLog_ExcludeMessageContainsLessThanXLetters")]
|
||||
public int ExcludeMessageContainsLessThanXLetters { get; set; } = 0;
|
||||
|
||||
[JsonPropertyName("ChatLog_ExcludeMessageDuplicate")]
|
||||
public bool ExcludeMessageDuplicate { get; set; } = false;
|
||||
}
|
||||
|
||||
public class CustomServerCommandData
|
||||
{
|
||||
[JsonPropertyName("Flag")]
|
||||
|
|
@ -273,4 +288,16 @@ public class CS2_SimpleAdminConfig : BasePluginConfig
|
|||
|
||||
[JsonPropertyName("MenuConfig")]
|
||||
public MenuConfig MenuConfigs { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("ChatLog")]
|
||||
public ChatLog ChatLog { get; set; } = new ChatLog();
|
||||
|
||||
[JsonPropertyName("Statistics_Enable")]
|
||||
public bool Statistics_Enable { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("IsCSSPanel")]
|
||||
public bool IsCSSPanel { get; set; } = false;
|
||||
|
||||
[JsonPropertyName("BanIDBan")]
|
||||
public bool BanIDBan { get; set; } = true;
|
||||
}
|
||||
|
|
@ -45,6 +45,36 @@ CREATE TABLE IF NOT EXISTS `sa_servers` (
|
|||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`hostname` varchar(128) NOT NULL,
|
||||
`address` varchar(64) NOT NULL,
|
||||
`rcon` varchar(64) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `address` (`address`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sa_chatlogs` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`serverId` varchar(64) NOT NULL,
|
||||
`playerSteam64` varchar(64) NOT NULL,
|
||||
`playerName` varchar(64) NOT NULL,
|
||||
`message` TEXT,
|
||||
`team` BOOLEAN NOT NULL,
|
||||
`created` timestamp NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sa_statistics` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`serverId` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`playerId` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`playerName` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`playerIP` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`connectDate` timestamp DEFAULT CURRENT_TIMESTAMP,
|
||||
`connectTime` INT(20) NOT NULL,
|
||||
`disconnectDate` timestamp NULL DEFAULT NULL,
|
||||
`disconnectTime` INT(20) NULL DEFAULT NULL,
|
||||
`duration` INT(20) NULL DEFAULT NULL,
|
||||
`kills` INT(10) NULL DEFAULT NULL,
|
||||
`flags` TEXT COLLATE 'utf8mb4_general_ci',
|
||||
`map` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `playerId` (`playerId`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
30
CS2-SimpleAdmin/Database/Migrations/011_CSSPanelSupport.sql
Normal file
30
CS2-SimpleAdmin/Database/Migrations/011_CSSPanelSupport.sql
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
ALTER TABLE `sa_servers` ADD `rcon` varchar(64) NOT NULL AFTER `address`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sa_chatlogs` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`serverId` varchar(64) NOT NULL,
|
||||
`playerSteam64` varchar(64) NOT NULL,
|
||||
`playerName` varchar(64) NOT NULL,
|
||||
`message` TEXT,
|
||||
`team` BOOLEAN NOT NULL,
|
||||
`created` timestamp NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sa_statistics` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`serverId` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`playerId` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`playerName` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`playerIP` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`connectDate` timestamp DEFAULT CURRENT_TIMESTAMP,
|
||||
`connectTime` INT(20) NOT NULL,
|
||||
`disconnectDate` timestamp NULL DEFAULT NULL,
|
||||
`disconnectTime` INT(20) NULL DEFAULT NULL,
|
||||
`duration` INT(20) NULL DEFAULT NULL,
|
||||
`kills` INT(10) NULL DEFAULT NULL,
|
||||
`flags` TEXT COLLATE 'utf8mb4_general_ci',
|
||||
`map` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `playerId` (`playerId`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
|
@ -117,7 +117,13 @@ public partial class CS2_SimpleAdmin
|
|||
if (player == null || !player.IsValid || player.IsBot)
|
||||
return HookResult.Continue;
|
||||
|
||||
new PlayerManager().LoadPlayerData(player);
|
||||
AddTimer(1.25f, () =>
|
||||
{
|
||||
if(player == null || !player.IsValid)
|
||||
return;
|
||||
|
||||
new PlayerManager().LoadPlayerData(player);
|
||||
});
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
|
@ -164,7 +170,8 @@ public partial class CS2_SimpleAdmin
|
|||
if (!command.Contains("say"))
|
||||
return HookResult.Continue;
|
||||
|
||||
if (info.GetArg(1).StartsWith($"/")
|
||||
if (string.IsNullOrWhiteSpace(info.GetArg(1))
|
||||
|| info.GetArg(1).StartsWith($"/")
|
||||
|| info.GetArg(1).StartsWith($"!"))
|
||||
return HookResult.Continue;
|
||||
|
||||
|
|
@ -180,6 +187,36 @@ public partial class CS2_SimpleAdmin
|
|||
player.ExecuteClientCommandFromServer($"css_say {info.GetArg(1).Remove(0, 1)}");
|
||||
return HookResult.Stop;
|
||||
}
|
||||
|
||||
if ((command == "say" || command == "say_team") && Config.IsCSSPanel)
|
||||
{
|
||||
var message = info.GetArg(1);
|
||||
|
||||
string trimmedMessage1 = message.TrimStart();
|
||||
string trimmedMessage = trimmedMessage1.TrimEnd();
|
||||
|
||||
//Console.WriteLine($"{IsStringValid(trimmedMessage)} | {Config.ChatLog.ExcludeMessageContainsLessThanXLetters} | {CountLetters(trimmedMessage)}");
|
||||
|
||||
if (IsStringValid(trimmedMessage) && (Config.ChatLog.ExcludeMessageContainsLessThanXLetters <= 0 || CountLetters(trimmedMessage) > Config.ChatLog.ExcludeMessageContainsLessThanXLetters))
|
||||
{
|
||||
var vplayername = player.PlayerName;
|
||||
var steamId64 = (player.AuthorizedSteamID != null) ? player.AuthorizedSteamID.SteamId64.ToString() : "InvalidSteamID";
|
||||
|
||||
secondMessage = firstMessage;
|
||||
firstMessage = trimmedMessage;
|
||||
|
||||
if (!Config.ChatLog.ExcludeMessageDuplicate || secondMessage != firstMessage)
|
||||
{
|
||||
// Add to db
|
||||
ChatManager.AddChatMessageDB(
|
||||
steamId64,
|
||||
vplayername,
|
||||
trimmedMessage,
|
||||
command.Contains("say_team")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (command != "say_team" || !info.GetArg(1).StartsWith($"@")) return HookResult.Continue;
|
||||
|
||||
|
|
|
|||
130
CS2-SimpleAdmin/Events_Statistics.cs
Normal file
130
CS2-SimpleAdmin/Events_Statistics.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using CS2_SimpleAdmin.Managers;
|
||||
using CS2_SimpleAdmin.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using Dapper;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
||||
public partial class CS2_SimpleAdmin
|
||||
{
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerConnectStatistics(EventPlayerConnectFull @event, GameEventInfo info)
|
||||
{
|
||||
if (!Config.IsCSSPanel) return HookResult.Continue;
|
||||
if (Config.Statistics_Enable == false) return HookResult.Continue;
|
||||
|
||||
CCSPlayerController? player = @event.Userid;
|
||||
|
||||
if (player == null || string.IsNullOrEmpty(player.IpAddress) || player.IpAddress.Contains("127.0.0.1")
|
||||
|| player.IsBot || player.IsHLTV || !player.UserId.HasValue || player.AuthorizedSteamID == null)
|
||||
{
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
|
||||
if (Database == null) return HookResult.Continue;
|
||||
|
||||
SteamID authorizedSteamID = player.AuthorizedSteamID!;
|
||||
string ipAddress = player.IpAddress!.Split(":")[0];
|
||||
string playerId = authorizedSteamID.SteamId64.ToString();
|
||||
string playerName = player.PlayerName;
|
||||
|
||||
// Unix timestamp
|
||||
long Time = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
|
||||
string Map = Server.MapName;
|
||||
|
||||
if (ServerId == null)
|
||||
return HookResult.Continue;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var connection = await Database.GetConnectionAsync();
|
||||
|
||||
string sql = "INSERT INTO `sa_statistics` (`serverId`, `playerId`, `playerName`, `playerIP`, `connectTime`, `flags`, `map`) " +
|
||||
"VALUES (@serverId, @playerId, @playerName, @playerIP, @connectTime, @flags, @map)";
|
||||
|
||||
List<string> adminFlags = await PermissionManager.GetAdminFlagsAsString(playerId);
|
||||
|
||||
await connection.ExecuteAsync(sql, new
|
||||
{
|
||||
serverId = ServerId,
|
||||
playerId,
|
||||
playerName,
|
||||
playerIP = ipAddress,
|
||||
connectTime = Time,
|
||||
flags = adminFlags.Count > 0 ? string.Join(",", adminFlags) : null,
|
||||
map = Map
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"An error occurred in OnPlayerConnect: {ex.Message}");
|
||||
}
|
||||
});
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
[GameEventHandler]
|
||||
public HookResult OnClientDisconnectStatistics(EventPlayerDisconnect @event, GameEventInfo info)
|
||||
{
|
||||
if (!Config.IsCSSPanel) return HookResult.Continue;
|
||||
if (Config.Statistics_Enable == false) return HookResult.Continue;
|
||||
|
||||
CCSPlayerController? player = @event.Userid;
|
||||
|
||||
if (player == null || string.IsNullOrEmpty(player.IpAddress) || player.IpAddress.Contains("127.0.0.1")
|
||||
|| player.IsBot || player.IsHLTV || !player.UserId.HasValue || player.AuthorizedSteamID == null)
|
||||
return HookResult.Continue;
|
||||
|
||||
if (Database == null) return HookResult.Continue;
|
||||
|
||||
SteamID authorizedSteamID = player.AuthorizedSteamID!;
|
||||
string ipAddress = player.IpAddress!.Split(":")[0];
|
||||
string playerId = authorizedSteamID.SteamId64.ToString();
|
||||
string playerName = player.PlayerName;
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
// Unix timestamp
|
||||
long Time = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
string kills = player.ActionTrackingServices!.MatchStats.Kills.ToString();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var connection = await Database.GetConnectionAsync();
|
||||
|
||||
string sql = "UPDATE `sa_statistics` SET `disconnectTime` = @disconnectTime, `disconnectDate` = @disconnectDate, `kills` = @kills, `duration` = @disconnectTime - `connectTime` " +
|
||||
"WHERE `playerId` = @playerId AND `disconnectTime` IS NULL";
|
||||
|
||||
await connection.ExecuteAsync(sql, new
|
||||
{
|
||||
disconnectTime = Time,
|
||||
disconnectDate = now,
|
||||
kills,
|
||||
playerId,
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"An error occurred in OnClientDisconnectStatistics: {ex.Message}");
|
||||
}
|
||||
});
|
||||
|
||||
return HookResult.Continue;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,33 @@ using CS2_SimpleAdmin.Managers;
|
|||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
||||
public partial class CS2_SimpleAdmin
|
||||
{
|
||||
bool IsStringValid(string input)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(input) && (string.IsNullOrEmpty(Config.ChatLog.ExcludeMessageContains) || !input.Any(c => Config.ChatLog.ExcludeMessageContains.Contains(c))) && !char.IsWhiteSpace(input.Last()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int CountLetters(string input)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (char c in input)
|
||||
{
|
||||
if (char.IsLetter(c))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Helper
|
||||
{
|
||||
private static readonly string AssemblyName = Assembly.GetExecutingAssembly().GetName().Name ?? "";
|
||||
|
|
|
|||
40
CS2-SimpleAdmin/Managers/ChatManager.cs
Normal file
40
CS2-SimpleAdmin/Managers/ChatManager.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using Dapper;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CS2_SimpleAdmin.Managers;
|
||||
|
||||
public class ChatManager
|
||||
{
|
||||
public void AddChatMessageDB(string playerSteam64, string playerName, string message, bool? team)
|
||||
{
|
||||
if (CS2_SimpleAdmin.Database == null) return;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
|
||||
|
||||
var sql = "INSERT INTO `sa_chatlogs` (`playerSteam64`, `playerName`, `message`, `team`, `created`, `serverId`) " +
|
||||
"VALUES (@playerSteam64, @playerName, @message, @team, @created, @serverId)";
|
||||
int? serverId = CS2_SimpleAdmin.ServerId;
|
||||
if (serverId == null)
|
||||
return;
|
||||
DateTime now = DateTime.Now;
|
||||
await connection.ExecuteAsync(sql, new
|
||||
{
|
||||
playerSteam64,
|
||||
playerName,
|
||||
message,
|
||||
team = team ?? null,
|
||||
created = now,
|
||||
serverid = serverId
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CS2_SimpleAdmin._logger?.LogError(e.Message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using Dapper;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -14,22 +15,77 @@ public class PermissionManager(Database.Database? database)
|
|||
//public static readonly ConcurrentDictionary<string, ConcurrentBag<string>> _adminCache = new ConcurrentDictionary<string, ConcurrentBag<string>>();
|
||||
public static readonly ConcurrentDictionary<SteamID, DateTime?> AdminCache = new();
|
||||
|
||||
/*
|
||||
public async Task<List<(List<string>, int)>> GetAdminFlags(string steamId)
|
||||
// Get the relevant server groups from the sa_servers_groups table by searching if the serverId is in the servers set column
|
||||
public async Task<List<string>> GetServerGroups()
|
||||
{
|
||||
DateTime now = Time.ActualDateTime();
|
||||
if (database == null) return [];
|
||||
|
||||
await using MySqlConnection connection = await database.GetConnectionAsync();
|
||||
|
||||
await using MySqlConnection connection = await _database.GetConnectionAsync();
|
||||
string sql = "SELECT id FROM sa_servers_groups WHERE FIND_IN_SET(@ServerId, servers)";
|
||||
List<dynamic>? serverGroups = (await connection.QueryAsync(sql, new { ServerId = CS2_SimpleAdmin.ServerId }))?.ToList();
|
||||
|
||||
if (serverGroups == null)
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
List<string> serverGroupsList = new List<string>();
|
||||
|
||||
foreach (dynamic serverGroup in serverGroups)
|
||||
{
|
||||
if (serverGroup is not IDictionary<string, object> serverGroupDict)
|
||||
{
|
||||
Console.WriteLine("[GetServerGroups] Failed to parse server group.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!serverGroupDict.TryGetValue("id", out var idObj))
|
||||
{
|
||||
Console.WriteLine("[GetServerGroups] Failed to get server group id.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (idObj is not string id)
|
||||
{
|
||||
// Convert to string and add it to the list
|
||||
// Console.WriteLine("[GetServerGroups] Failed to parse server group id.");
|
||||
serverGroupsList.Add(idObj.ToString()!);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
serverGroupsList.Add(id);
|
||||
}
|
||||
|
||||
Console.WriteLine($"[GetServerGroups] Server Groups List: {string.Join(", ", serverGroupsList)}");
|
||||
return serverGroupsList;
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetAdminFlagsAsString(string steamId)
|
||||
{
|
||||
if (database == null) return [];
|
||||
|
||||
DateTime now = DateTime.UtcNow.ToLocalTime();
|
||||
|
||||
await using MySqlConnection connection = await database.GetConnectionAsync();
|
||||
|
||||
// string sql = "SELECT flags, immunity, ends FROM sa_admins WHERE player_steamid = @PlayerSteamID AND (ends IS NULL OR ends > @CurrentTime) AND (server_id IS NULL OR FIND_IN_SET(@serverid, server_id) > 0)";
|
||||
// string sql = "SELECT player_steamid, flags, immunity, ends FROM sa_admins WHERE (ends IS NULL OR ends > @CurrentTime) AND (server_id IS NULL OR FIND_IN_SET(@serverid, server_id) > 0)";
|
||||
List<string> serverGroups = await GetServerGroups();
|
||||
string serverGroupsCondition = string.Join(" OR ", serverGroups.Select(g => $"FIND_IN_SET({g}, servers_groups) > 0"));
|
||||
|
||||
string GroupCheck = serverGroups.Count > 0 ? $"AND (((server_id IS NULL AND servers_groups IS NULL) OR FIND_IN_SET(@serverid, server_id) > 0) OR (servers_groups IS NULL OR {serverGroupsCondition}))" : "AND ((server_id IS NULL AND servers_groups IS NULL) OR FIND_IN_SET(@serverid, server_id) > 0)";
|
||||
string sql = $"SELECT flags, immunity, ends FROM sa_admins WHERE player_steamid = @PlayerSteamID AND (ends IS NULL OR ends > @CurrentTime) {GroupCheck}";
|
||||
|
||||
string sql = "SELECT flags, immunity, ends FROM sa_admins WHERE player_steamid = @PlayerSteamID AND (ends IS NULL OR ends > @CurrentTime) AND (server_id IS NULL OR server_id = @serverid)";
|
||||
List<dynamic>? activeFlags = (await connection.QueryAsync(sql, new { PlayerSteamID = steamId, CurrentTime = now, serverid = CS2_SimpleAdmin.ServerId }))?.ToList();
|
||||
|
||||
if (activeFlags == null)
|
||||
{
|
||||
return new List<(List<string>, int)>();
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
List<(List<string>, int)> filteredFlagsWithImmunity = [];
|
||||
List<string> flagsList = new List<string>();
|
||||
|
||||
foreach (dynamic flags in activeFlags)
|
||||
{
|
||||
|
|
@ -38,26 +94,160 @@ public class PermissionManager(Database.Database? database)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!flagsDict.TryGetValue("flags", out var flagsValueObj) || !flagsDict.TryGetValue("immunity", out var immunityValueObj))
|
||||
if (!flagsDict.TryGetValue("flags", out var flagsValueObj))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(flagsValueObj is string flagsValue) || !int.TryParse(immunityValueObj.ToString(), out var immunityValue))
|
||||
if (!(flagsValueObj is string flagsValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Console.WriteLine($"Flags: {flagsValue}, Immunity: {immunityValue}");
|
||||
// If flags start with '#', fetch flags from sa_admins_groups
|
||||
if (flagsValue.StartsWith("#"))
|
||||
{
|
||||
string groupSql = "SELECT flags FROM sa_admins_groups WHERE id = @GroupId";
|
||||
var group = await connection.QueryFirstOrDefaultAsync(groupSql, new { GroupId = flagsValue });
|
||||
|
||||
filteredFlagsWithImmunity.Add((flagsValue.Split(',').ToList(), immunityValue));
|
||||
if (group != null)
|
||||
{
|
||||
flagsValue = group.flags;
|
||||
}
|
||||
}
|
||||
|
||||
flagsList.AddRange(flagsValue.Split(','));
|
||||
}
|
||||
|
||||
return filteredFlagsWithImmunity;
|
||||
return flagsList;
|
||||
}
|
||||
*/
|
||||
|
||||
private async Task<List<(string, string, List<string>, int, DateTime?)>> GetAllPlayersFlags()
|
||||
public async Task<List<(string, List<string>, int, DateTime?)>> GetAllPlayersFlags()
|
||||
{
|
||||
if (database == null) return [];
|
||||
|
||||
DateTime now = DateTime.UtcNow.ToLocalTime();
|
||||
|
||||
try
|
||||
{
|
||||
await using MySqlConnection connection = await database.GetConnectionAsync();
|
||||
|
||||
// string sql = "SELECT player_steamid, flags, immunity, ends FROM sa_admins WHERE (ends IS NULL OR ends > @CurrentTime) AND (server_id IS NULL OR FIND_IN_SET(@serverid, server_id) > 0)";
|
||||
List<string> serverGroups = await GetServerGroups();
|
||||
string serverGroupsCondition = string.Join(" OR ", serverGroups.Select(g => $"FIND_IN_SET({g}, servers_groups) > 0"));
|
||||
|
||||
string GroupCheck = serverGroups.Count > 0 ? $"AND (((server_id IS NULL AND servers_groups IS NULL) OR FIND_IN_SET(@serverid, server_id) > 0) OR (servers_groups IS NULL OR {serverGroupsCondition}))" : "AND ((server_id IS NULL AND servers_groups IS NULL) OR FIND_IN_SET(@serverid, server_id) > 0)";
|
||||
string sql = $"SELECT player_steamid, flags, immunity, ends FROM sa_admins WHERE (ends IS NULL OR ends > @CurrentTime) {GroupCheck}";
|
||||
|
||||
List<dynamic>? activeFlags = (await connection.QueryAsync(sql, new { CurrentTime = now, serverid = CS2_SimpleAdmin.ServerId }))?.ToList();
|
||||
|
||||
if (activeFlags == null)
|
||||
{
|
||||
return new List<(string, List<string>, int, DateTime?)>();
|
||||
}
|
||||
|
||||
List<(string, List<string>, int, DateTime?)> filteredFlagsWithImmunity = new List<(string, List<string>, int, DateTime?)>();
|
||||
|
||||
foreach (dynamic flags in activeFlags)
|
||||
{
|
||||
if (flags is not IDictionary<string, object> flagsDict)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!flagsDict.TryGetValue("player_steamid", out var steamIdObj) ||
|
||||
!flagsDict.TryGetValue("flags", out var flagsValueObj) ||
|
||||
!flagsDict.TryGetValue("immunity", out var immunityValueObj) ||
|
||||
!flagsDict.TryGetValue("ends", out var endsObj))
|
||||
{
|
||||
//Console.WriteLine("One or more required keys are missing.");
|
||||
continue;
|
||||
}
|
||||
|
||||
DateTime? ends = null;
|
||||
|
||||
if (endsObj != null) // Check if "ends" is not null
|
||||
{
|
||||
if (!DateTime.TryParse(endsObj.ToString(), out var parsedEnds))
|
||||
{
|
||||
//Console.WriteLine("Failed to parse 'ends' value.");
|
||||
continue;
|
||||
}
|
||||
|
||||
ends = parsedEnds;
|
||||
}
|
||||
|
||||
if (!(steamIdObj is string steamId) ||
|
||||
!(flagsValueObj is string flagsValue) ||
|
||||
!int.TryParse(immunityValueObj.ToString(), out var immunityValue))
|
||||
{
|
||||
//Console.WriteLine("Failed to parse one or more values.");
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (flagsValue.StartsWith("#"))
|
||||
{
|
||||
string groupSql = "SELECT flags, immunity FROM sa_admins_groups WHERE id = @GroupId";
|
||||
var group = await connection.QueryFirstOrDefaultAsync(groupSql, new { GroupId = flagsValue });
|
||||
|
||||
if (group != null)
|
||||
{
|
||||
flagsValue = group.flags;
|
||||
if (int.TryParse(group.immunity.ToString(), out int immunityGroupValue))
|
||||
{
|
||||
filteredFlagsWithImmunity.Add((steamId, flagsValue.Split(',').ToList(), immunityGroupValue, ends));
|
||||
// Console.WriteLine($"Flags Check (Group): SteamId {steamId} Flags: {flagsValue}, Immunity: {immunityValue}");
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Failed to parse immunity: {group.immunity}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filteredFlagsWithImmunity.Add((steamId, flagsValue.Split(',').ToList(), immunityValue, ends));
|
||||
}
|
||||
|
||||
return filteredFlagsWithImmunity;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Error: {e.Message}");
|
||||
return new List<(string, List<string>, int, DateTime?)>();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task GiveAllFlags()
|
||||
{
|
||||
List<(string, List<string>, int, DateTime?)> allPlayers = await GetAllPlayersFlags();
|
||||
|
||||
foreach (var record in allPlayers)
|
||||
{
|
||||
string steamIdStr = record.Item1;
|
||||
List<string> flags = record.Item2;
|
||||
int immunity = record.Item3;
|
||||
|
||||
DateTime? ends = record.Item4;
|
||||
|
||||
if (!string.IsNullOrEmpty(steamIdStr) && SteamID.TryParse(steamIdStr, out var steamId) && steamId != null)
|
||||
{
|
||||
if (!AdminCache.ContainsKey(steamId))
|
||||
{
|
||||
AdminCache.TryAdd(steamId, ends);
|
||||
//_adminCacheTimestamps.Add(steamId, ends);
|
||||
}
|
||||
|
||||
Helper.GivePlayerFlags(steamId, flags, (uint)immunity);
|
||||
// Often need to call 2 times
|
||||
Helper.GivePlayerFlags(steamId, flags, (uint)immunity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<(string, string, List<string>, int, DateTime?)>> GetAllPlayersFlagsSA()
|
||||
{
|
||||
if (database == null) return [];
|
||||
|
||||
|
|
@ -111,71 +301,6 @@ public class PermissionManager(Database.Database? database)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public async Task<Dictionary<int, Tuple<List<string>, List<Tuple<string, DateTime?>>, int>>> GetAllGroupsFlags()
|
||||
{
|
||||
try
|
||||
{
|
||||
await using MySqlConnection connection = await _database.GetConnectionAsync();
|
||||
|
||||
string sql = "SELECT group_id FROM sa_groups_servers WHERE server_id = @serverid";
|
||||
var groupIds = connection.Query<int>(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList();
|
||||
|
||||
sql = @"
|
||||
SELECT g.group_id, f.flag
|
||||
FROM sa_groups_flags f
|
||||
JOIN sa_groups_servers g ON f.group_id = g.group_id
|
||||
WHERE g.server_id = @serverid";
|
||||
|
||||
var groupFlagData = connection.Query(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList();
|
||||
|
||||
if (groupIds.Count == 0 || groupFlagData.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var groupInfoDictionary = new Dictionary<int, Tuple<List<string>, List<Tuple<string, DateTime?>>, int>>();
|
||||
|
||||
foreach (var groupId in groupIds)
|
||||
{
|
||||
groupInfoDictionary[groupId] = new Tuple<List<string>, List<Tuple<string, DateTime?>>, int>([], [], 0);
|
||||
}
|
||||
|
||||
foreach (var row in groupFlagData)
|
||||
{
|
||||
var groupId = (int)row.group_id;
|
||||
var flag = (string)row.flag;
|
||||
|
||||
groupInfoDictionary[groupId].Item1.Add(flag);
|
||||
}
|
||||
|
||||
sql = @"
|
||||
SELECT a.group_id, a.player_steamid, a.ends, g.immunity, g.name
|
||||
FROM sa_admins a
|
||||
JOIN sa_groups g ON a.group_id = g.id
|
||||
WHERE a.group_id IN @groupIds";
|
||||
|
||||
var playerData = (await connection.QueryAsync(sql, new { groupIds })).ToList();
|
||||
|
||||
foreach (var row in playerData)
|
||||
{
|
||||
var groupId = (int)row.group_id;
|
||||
var playerSteamid = (string)row.player_steamid;
|
||||
var ends = row.ends as DateTime?;
|
||||
var immunity = (int)row.immunity;
|
||||
|
||||
groupInfoDictionary[groupId].Item2.Add(new Tuple<string, DateTime?>(playerSteamid, ends));
|
||||
groupInfoDictionary[groupId] = new Tuple<List<string>, List<Tuple<string, DateTime?>>, int>(groupInfoDictionary[groupId].Item1, groupInfoDictionary[groupId].Item2, immunity);
|
||||
}
|
||||
|
||||
return groupInfoDictionary;
|
||||
}
|
||||
catch { }
|
||||
|
||||
return [];
|
||||
}
|
||||
*/
|
||||
|
||||
private async Task<Dictionary<string, (List<string>, int)>> GetAllGroupsData()
|
||||
{
|
||||
if (database == null) return [];
|
||||
|
|
@ -184,6 +309,7 @@ public class PermissionManager(Database.Database? database)
|
|||
try
|
||||
{
|
||||
var sql = "SELECT group_id FROM sa_groups_servers WHERE (server_id = @serverid OR server_id IS NULL)";
|
||||
|
||||
var groupDataSql = connection.Query<int>(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList();
|
||||
|
||||
sql = """
|
||||
|
|
@ -230,7 +356,7 @@ public class PermissionManager(Database.Database? database)
|
|||
return [];
|
||||
}
|
||||
|
||||
public async Task CrateGroupsJsonFile()
|
||||
public async Task CreateGroupsJsonFile()
|
||||
{
|
||||
var groupsData = await GetAllGroupsData();
|
||||
|
||||
|
|
@ -252,69 +378,9 @@ public class PermissionManager(Database.Database? database)
|
|||
await File.WriteAllTextAsync(filePath, json);
|
||||
}
|
||||
|
||||
/*
|
||||
public async Task GiveAllGroupsFlags()
|
||||
{
|
||||
Dictionary<int, Tuple<List<string>, List<Tuple<string, DateTime?>>, int>> groupFlags = await GetAllGroupsFlags();
|
||||
|
||||
foreach (var kvp in groupFlags)
|
||||
{
|
||||
var flags = kvp.Value.Item1;
|
||||
var players = kvp.Value.Item2;
|
||||
int immunity = kvp.Value.Item3;
|
||||
|
||||
foreach (var playerTuple in players)
|
||||
{
|
||||
var steamIdStr = playerTuple.Item1;
|
||||
var ends = playerTuple.Item2;
|
||||
|
||||
if (!string.IsNullOrEmpty(steamIdStr) && SteamID.TryParse(steamIdStr, out var steamId) && steamId != null)
|
||||
{
|
||||
if (!_adminCache.ContainsKey(steamId))
|
||||
{
|
||||
_adminCache.TryAdd(steamId, ends);
|
||||
}
|
||||
|
||||
Helper.GivePlayerFlags(steamId, flags, (uint)immunity);
|
||||
// Often need to call 2 times
|
||||
Helper.GivePlayerFlags(steamId, flags, (uint)immunity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
public async Task GiveAllFlags()
|
||||
{
|
||||
List<(string, string, List<string>, int, DateTime?)> allPlayers = await GetAllPlayersFlags();
|
||||
|
||||
foreach (var record in allPlayers)
|
||||
{
|
||||
string steamIdStr = record.Item1;
|
||||
List<string> flags = record.Item2;
|
||||
int immunity = record.Item3;
|
||||
|
||||
DateTime? ends = record.Item4;
|
||||
|
||||
if (!string.IsNullOrEmpty(steamIdStr) && SteamID.TryParse(steamIdStr, out var steamId) && steamId != null)
|
||||
{
|
||||
if (!_adminCache.ContainsKey(steamId))
|
||||
{
|
||||
_adminCache.TryAdd(steamId, ends);
|
||||
//_adminCacheTimestamps.Add(steamId, ends);
|
||||
}
|
||||
|
||||
Helper.GivePlayerFlags(steamId, flags, (uint)immunity);
|
||||
// Often need to call 2 times
|
||||
Helper.GivePlayerFlags(steamId, flags, (uint)immunity);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public async Task CreateAdminsJsonFile()
|
||||
{
|
||||
List<(string identity, string name, List<string> flags, int immunity, DateTime? ends)> allPlayers = await GetAllPlayersFlags();
|
||||
List<(string identity, string name, List<string> flags, int immunity, DateTime? ends)> allPlayers = await GetAllPlayersFlagsSA();
|
||||
var validPlayers = allPlayers
|
||||
.Where(player => SteamID.TryParse(player.identity, out _)) // Filter invalid SteamID
|
||||
.ToList();
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ public class PlayerManager
|
|||
|
||||
if (victim?.UserId == null) return;
|
||||
|
||||
if (CS2_SimpleAdmin.UnlockedCommands)
|
||||
if (CS2_SimpleAdmin.UnlockedCommands && _config.BanIDBan)
|
||||
Server.ExecuteCommand($"banid 1 {userId}");
|
||||
|
||||
Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
|
||||
|
|
@ -178,7 +178,9 @@ public class PlayerManager
|
|||
AdminManager.PlayerHasPermissions(p, "@css/ban")) &&
|
||||
p.Connected == PlayerConnectedState.PlayerConnected && !CS2_SimpleAdmin.AdminDisabledJoinComms.Contains(p.SteamID)))
|
||||
{
|
||||
if (CS2_SimpleAdmin._localizer != null && admin != player)
|
||||
if (CS2_SimpleAdmin._localizer != null && admin != player
|
||||
&& (CS2_SimpleAdmin.PlayersInfo[userId].TotalBans > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalGags > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalWarns > 0)
|
||||
)
|
||||
admin.SendLocalizedMessage(CS2_SimpleAdmin._localizer, "sa_admin_penalty_info",
|
||||
player.PlayerName,
|
||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalBans,
|
||||
|
|
@ -253,13 +255,14 @@ public class PlayerManager
|
|||
{
|
||||
foreach (var player in players.Where(player => PlayerPenaltyManager.IsSlotInPenalties(player.Slot)))
|
||||
{
|
||||
if (!PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute) && !PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence))
|
||||
player.VoiceFlags = VoiceFlags.Normal;
|
||||
if (!PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute) && !PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence) && player.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
player.VoiceFlags &= ~VoiceFlags.Muted;
|
||||
|
||||
if (PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence) ||
|
||||
PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Mute) ||
|
||||
PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag)) continue;
|
||||
player.VoiceFlags = VoiceFlags.Normal;
|
||||
if (player.VoiceFlags.HasFlag(VoiceFlags.Muted))
|
||||
player.VoiceFlags &= ~VoiceFlags.Muted;
|
||||
}
|
||||
|
||||
PlayerPenaltyManager.RemoveExpiredPenalties();
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public class ServerManager
|
|||
|
||||
var address = $"{ipAddress}:{ConVar.Find("hostport")?.GetPrimitiveValue<int>()}";
|
||||
var hostname = ConVar.Find("hostname")!.StringValue;
|
||||
var rcon = ConVar.Find("rcon_password")!.StringValue;
|
||||
CS2_SimpleAdmin.IpAddress = address;
|
||||
|
||||
Task.Run(async () =>
|
||||
|
|
@ -48,14 +49,14 @@ public class ServerManager
|
|||
if (!addressExists)
|
||||
{
|
||||
await connection.ExecuteAsync(
|
||||
"INSERT INTO sa_servers (address, hostname) VALUES (@address, @hostname)",
|
||||
new { address, hostname });
|
||||
"INSERT INTO sa_servers (address, hostname, rcon) VALUES (@address, @hostname, @rcon)",
|
||||
new { address, hostname, rcon });
|
||||
}
|
||||
else
|
||||
{
|
||||
await connection.ExecuteAsync(
|
||||
"UPDATE `sa_servers` SET `hostname` = @hostname, `id` = `id` WHERE `address` = @address",
|
||||
new { address, hostname });
|
||||
"UPDATE `sa_servers` SET `hostname` = @hostname, rcon = @rcon, `id` = `id` WHERE `address` = @address",
|
||||
new { address, rcon, hostname });
|
||||
}
|
||||
|
||||
int? serverId = await connection.ExecuteScalarAsync<int>(
|
||||
|
|
|
|||
|
|
@ -69,4 +69,8 @@ public partial class CS2_SimpleAdmin
|
|||
internal BanManager BanManager = new(Database);
|
||||
internal MuteManager MuteManager = new(Database);
|
||||
internal WarnManager WarnManager = new(Database);
|
||||
internal ChatManager ChatManager = new();
|
||||
|
||||
static string firstMessage = "";
|
||||
static string secondMessage = "";
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS2-SimpleAdmin_ExampleModule", "CS2-SimpleAdmin_ExampleModule.csproj", "{D940F3E9-0E3F-467A-B336-149E3A624FB6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D940F3E9-0E3F-467A-B336-149E3A624FB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D940F3E9-0E3F-467A-B336-149E3A624FB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D940F3E9-0E3F-467A-B336-149E3A624FB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D940F3E9-0E3F-467A-B336-149E3A624FB6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Loading…
Add table
Add a link
Reference in a new issue