Refactor database layer and add module/plugin improvements
Reworked the database layer to support both MySQL and SQLite via new provider classes and migration scripts for each backend. Updated the build workflow to support building and packaging additional modules, including StealthModule and BanSoundModule, and improved artifact handling. Refactored command registration to allow dynamic registration/unregistration and improved API event handling. Updated dependencies, project structure, and configuration checks for better reliability and extensibility. Added new language files, updated versioning, and removed obsolete files.
**⚠️ Warning: SQLite support is currently experimental.
Using this version requires reconfiguration of your database settings!
Plugin now uses UTC time. Please adjust your configurations accordingly!
**
This commit is contained in:
parent
b97426313b
commit
5701455de0
111 changed files with 5387 additions and 2871 deletions
|
|
@ -1,9 +1,12 @@
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using System.Reflection;
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Capabilities;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CS2_SimpleAdmin.Database;
|
||||
using CS2_SimpleAdmin.Managers;
|
||||
using CS2_SimpleAdminApi;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -19,47 +22,55 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
|||
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
|
||||
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
|
||||
public override string ModuleAuthor => "daffyy & Dliix66";
|
||||
public override string ModuleVersion => "1.7.7-alpha";
|
||||
public override string ModuleVersion => "1.7.7-alpha-9";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
RegisterEvents();
|
||||
|
||||
|
||||
if (hotReload)
|
||||
{
|
||||
ServerLoaded = false;
|
||||
_serverLoading = false;
|
||||
|
||||
CacheManager?.Dispose();
|
||||
CacheManager = new CacheManager();
|
||||
OnGameServerSteamAPIActivated();
|
||||
|
||||
// OnGameServerSteamAPIActivated();
|
||||
OnMapStart(string.Empty);
|
||||
|
||||
AddTimer(2.0f, () =>
|
||||
AddTimer(6.0f, () =>
|
||||
{
|
||||
if (Database == null) return;
|
||||
if (DatabaseProvider == null) return;
|
||||
|
||||
var playerManager = new PlayerManager();
|
||||
|
||||
foreach (var player in Helper.GetValidPlayers())
|
||||
PlayersInfo.Clear();
|
||||
CachedPlayers.Clear();
|
||||
BotPlayers.Clear();
|
||||
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsHLTV).ToArray())
|
||||
{
|
||||
playerManager.LoadPlayerData(player);
|
||||
if (!player.IsBot)
|
||||
PlayerManager.LoadPlayerData(player, true);
|
||||
else
|
||||
BotPlayers.Add(player);
|
||||
};
|
||||
});
|
||||
|
||||
PlayersTimer?.Kill();
|
||||
PlayersTimer = null;
|
||||
}
|
||||
_cBasePlayerControllerSetPawnFunc = new MemoryFunctionVoid<CBasePlayerController, CCSPlayerPawn, bool, bool>(GameData.GetSignature("CBasePlayerController_SetPawn"));
|
||||
|
||||
SimpleAdminApi = new Api.CS2_SimpleAdminApi();
|
||||
Capabilities.RegisterPluginCapability(ICS2_SimpleAdminApi.PluginCapability, () => SimpleAdminApi);
|
||||
|
||||
new PlayerManager().CheckPlayersTimer();
|
||||
PlayersTimer?.Kill();
|
||||
PlayersTimer = null;
|
||||
PlayerManager.CheckPlayersTimer();
|
||||
}
|
||||
|
||||
public override void OnAllPluginsLoaded(bool hotReload)
|
||||
{
|
||||
AddTimer(5.0f, () => ReloadAdmins(null));
|
||||
|
||||
try
|
||||
{
|
||||
MenuApi = MenuCapability.Get();
|
||||
|
|
@ -67,51 +78,141 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
|||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Unable to load required plugins ... \n{exception}", ex.Message);
|
||||
Unload(false);
|
||||
}
|
||||
|
||||
|
||||
AddTimer(6.0f, () => ReloadAdmins(null));
|
||||
RegisterEvents();
|
||||
RegisterCommands.InitializeCommands();
|
||||
|
||||
if (!CoreConfig.UnlockConCommands)
|
||||
{
|
||||
_logger?.LogError(
|
||||
$"⚠️ Warning: 'UnlockConCommands' is disabled in core.json. " +
|
||||
$"Players will not be automatically banned when kicked and will be able " +
|
||||
$"to rejoin the server for 60 seconds. " +
|
||||
$"To enable instant banning, set 'UnlockConCommands': true"
|
||||
);
|
||||
_logger?.LogError(
|
||||
$"⚠️ Warning: 'UnlockConCommands' is disabled in core.json. " +
|
||||
$"Players will not be automatically banned when kicked and will be able " +
|
||||
$"to rejoin the server for 60 seconds. " +
|
||||
$"To enable instant banning, set 'UnlockConCommands': true"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnConfigParsed(CS2_SimpleAdminConfig config)
|
||||
{
|
||||
Instance = this;
|
||||
_logger = Logger;
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
Environment.FailFast(":(!");
|
||||
|
||||
if (config.DatabaseHost.Length < 1 || config.DatabaseName.Length < 1 || config.DatabaseUser.Length < 1)
|
||||
Helper.UpdateConfig(config);
|
||||
|
||||
_logger = Logger;
|
||||
Config = config;
|
||||
|
||||
bool missing = false;
|
||||
var cssPath = Path.Combine(Server.GameDirectory, "csgo", "addons", "counterstrikesharp");
|
||||
var pluginsPath = Path.Combine(cssPath, "plugins");
|
||||
var sharedPath = Path.Combine(cssPath, "shared");
|
||||
|
||||
foreach (var plugin in _requiredPlugins)
|
||||
{
|
||||
throw new Exception("[CS2-SimpleAdmin] You need to setup Database credentials in config!");
|
||||
var pluginDirPath = Path.Combine(pluginsPath, plugin);
|
||||
var pluginDllPath = Path.Combine(pluginDirPath, $"{plugin}.dll");
|
||||
|
||||
if (!Directory.Exists(pluginDirPath))
|
||||
{
|
||||
_logger?.LogError(
|
||||
$"❌ Plugin directory '{plugin}' missing at: {pluginDirPath}"
|
||||
);
|
||||
missing = true;
|
||||
}
|
||||
|
||||
if (!File.Exists(pluginDllPath))
|
||||
{
|
||||
_logger?.LogError(
|
||||
$"❌ Plugin DLL '{plugin}.dll' missing at: {pluginDllPath}"
|
||||
);
|
||||
missing = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var shared in _requiredShared)
|
||||
{
|
||||
var sharedDirPath = Path.Combine(sharedPath, shared);
|
||||
var sharedDllPath = Path.Combine(sharedDirPath, $"{shared}.dll");
|
||||
|
||||
if (!Directory.Exists(sharedDirPath))
|
||||
{
|
||||
_logger?.LogError(
|
||||
$"❌ Shared library directory '{shared}' missing at: {sharedDirPath}"
|
||||
);
|
||||
missing = true;
|
||||
}
|
||||
|
||||
if (!File.Exists(sharedDllPath))
|
||||
{
|
||||
_logger?.LogError(
|
||||
$"❌ Shared library DLL '{shared}.dll' missing at: {sharedDllPath}"
|
||||
);
|
||||
missing = true;
|
||||
}
|
||||
}
|
||||
|
||||
MySqlConnectionStringBuilder builder = new()
|
||||
if (missing)
|
||||
Server.ExecuteCommand($"css_plugins unload {ModuleName}");
|
||||
|
||||
Instance = this;
|
||||
|
||||
if (Config.DatabaseConfig.DatabaseType.Contains("mysql", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(config.DatabaseConfig.DatabaseHost) ||
|
||||
string.IsNullOrWhiteSpace(config.DatabaseConfig.DatabaseName) ||
|
||||
string.IsNullOrWhiteSpace(config.DatabaseConfig.DatabaseUser))
|
||||
{
|
||||
Server = config.DatabaseHost,
|
||||
Database = config.DatabaseName,
|
||||
UserID = config.DatabaseUser,
|
||||
Password = config.DatabasePassword,
|
||||
Port = (uint)config.DatabasePort,
|
||||
SslMode = Enum.TryParse(config.DatabaseSSlMode, true, out MySqlSslMode sslMode) ? sslMode : MySqlSslMode.Preferred,
|
||||
throw new Exception("[CS2-SimpleAdmin] You need to setup MySQL credentials in config!");
|
||||
}
|
||||
|
||||
var builder = new MySqlConnectionStringBuilder()
|
||||
{
|
||||
Server = config.DatabaseConfig.DatabaseHost,
|
||||
Database = config.DatabaseConfig.DatabaseName,
|
||||
UserID = config.DatabaseConfig.DatabaseUser,
|
||||
Password = config.DatabaseConfig.DatabasePassword,
|
||||
Port = (uint)config.DatabaseConfig.DatabasePort,
|
||||
SslMode = Enum.TryParse(config.DatabaseConfig.DatabaseSSlMode, true, out MySqlSslMode sslMode)
|
||||
? sslMode
|
||||
: MySqlSslMode.Preferred,
|
||||
Pooling = true,
|
||||
MinimumPoolSize = 0,
|
||||
MaximumPoolSize = 640,
|
||||
};
|
||||
|
||||
DbConnectionString = builder.ConnectionString;
|
||||
Database = new Database.Database(DbConnectionString);
|
||||
|
||||
if (!Database.CheckDatabaseConnection(out var exception))
|
||||
DatabaseProvider = new MySqlDatabaseProvider(DbConnectionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(config.DatabaseConfig.SqliteFilePath))
|
||||
{
|
||||
if (exception != null)
|
||||
Logger.LogError("Problem with database connection! \n{exception}", exception);
|
||||
|
||||
Unload(false);
|
||||
return;
|
||||
throw new Exception("[CS2-SimpleAdmin] You need to specify SQLite file path in config!");
|
||||
}
|
||||
|
||||
Task.Run(() => Database.DatabaseMigration());
|
||||
|
||||
Config = config;
|
||||
Helper.UpdateConfig(config);
|
||||
DatabaseProvider = new SqliteDatabaseProvider(ModuleDirectory + "/" + config.DatabaseConfig.SqliteFilePath);
|
||||
}
|
||||
|
||||
var (success, exception) = Task.Run(() => DatabaseProvider.CheckConnectionAsync()).GetAwaiter().GetResult();
|
||||
if (!success)
|
||||
{
|
||||
if (exception != null)
|
||||
Logger.LogError("Problem with database connection! \n{exception}", exception);
|
||||
|
||||
Unload(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => DatabaseProvider.DatabaseMigrationAsync());
|
||||
|
||||
if (!Directory.Exists(ModuleDirectory + "/data"))
|
||||
{
|
||||
Directory.CreateDirectory(ModuleDirectory + "/data");
|
||||
|
|
@ -122,33 +223,32 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
|||
if (!string.IsNullOrEmpty(Config.Discord.DiscordLogWebhook))
|
||||
DiscordWebhookClientLog = new DiscordManager(Config.Discord.DiscordLogWebhook);
|
||||
|
||||
PluginInfo.ShowAd(ModuleVersion);
|
||||
if (Config.EnableUpdateCheck)
|
||||
Task.Run(async () => await PluginInfo.CheckVersion(ModuleVersion, _logger));
|
||||
Task.Run(async () => await PluginInfo.CheckVersion(ModuleVersion, Logger));
|
||||
|
||||
PermissionManager = new PermissionManager(Database);
|
||||
BanManager = new BanManager(Database);
|
||||
MuteManager = new MuteManager(Database);
|
||||
WarnManager = new WarnManager(Database);
|
||||
PermissionManager = new PermissionManager(DatabaseProvider);
|
||||
BanManager = new BanManager(DatabaseProvider);
|
||||
MuteManager = new MuteManager(DatabaseProvider);
|
||||
WarnManager = new WarnManager(DatabaseProvider);
|
||||
}
|
||||
|
||||
private static TargetResult? GetTarget(CommandInfo command)
|
||||
private static TargetResult? GetTarget(CommandInfo command, int argument = 1)
|
||||
{
|
||||
var matches = command.GetArgTargetResult(1);
|
||||
var matches = command.GetArgTargetResult(argument);
|
||||
|
||||
if (!matches.Any())
|
||||
{
|
||||
command.ReplyToCommand($"Target {command.GetArg(1)} not found.");
|
||||
command.ReplyToCommand($"Target {command.GetArg(argument)} not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (command.GetArg(1).StartsWith('@'))
|
||||
if (command.GetArg(argument).StartsWith('@'))
|
||||
return matches;
|
||||
|
||||
if (matches.Count() == 1)
|
||||
return matches;
|
||||
|
||||
command.ReplyToCommand($"Multiple targets found for \"{command.GetArg(1)}\".");
|
||||
command.ReplyToCommand($"Multiple targets found for \"{command.GetArg(argument)}\".");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -156,5 +256,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
|||
{
|
||||
CacheManager?.Dispose();
|
||||
CacheManager = null;
|
||||
PlayersTimer?.Kill();
|
||||
PlayersTimer = null;
|
||||
UnregisterEvents();
|
||||
|
||||
if (hotReload)
|
||||
PlayersInfo.Clear();
|
||||
else
|
||||
Server.ExecuteCommand($"css_plugins unload {ModuleDirectory}");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue