using CounterStrikeSharp.API; using CounterStrikeSharp.API.Modules.Cvars; using Dapper; using Microsoft.Extensions.Logging; namespace CS2_SimpleAdmin.Managers; public class ServerManager { private int _getIpTryCount; /// /// Checks whether the server setting sv_hibernate_when_empty is enabled. /// Logs an error if this setting is true, since it prevents the plugin from working properly. /// public static void CheckHibernationStatus() { var convar = ConVar.Find("sv_hibernate_when_empty"); if (convar == null || !convar.GetPrimitiveValue()) return; CS2_SimpleAdmin._logger?.LogError("Detected setting \"sv_hibernate_when_empty true\", set false to make plugin work properly"); } /// /// Initiates the asynchronous process to load server data such as IP address, port, hostname, and RCON password. /// Handles retry attempts if IP address is not immediately available. /// Updates or inserts the server record in the database accordingly. /// After loading, triggers admin reload and cache initialization. /// Also optionally sends plugin usage metrics if enabled in configuration. /// public void LoadServerData() { CS2_SimpleAdmin.Instance.AddTimer(1.0f, () => { if (CS2_SimpleAdmin.ServerLoaded || CS2_SimpleAdmin.DatabaseProvider == null) return; // Optimization: Get server IP once and reuse var serverIp = Helper.GetServerIp(); var isInvalidIp = string.IsNullOrEmpty(serverIp) || serverIp.StartsWith("0.0.0"); // Check if we've exceeded retry limit with invalid IP if (_getIpTryCount > 32 && isInvalidIp) { CS2_SimpleAdmin._logger?.LogError("Unable to load server data - can't fetch ip address!"); return; } // Optimization: Cache ConVar lookups var ipConVar = ConVar.Find("ip"); var ipAddress = ipConVar?.StringValue; // Use Helper IP if ConVar IP is invalid if (string.IsNullOrEmpty(ipAddress) || ipAddress.StartsWith("0.0.0")) { ipAddress = serverIp; // Retry if still invalid and under retry limit if (_getIpTryCount <= 32 && isInvalidIp) { _getIpTryCount++; LoadServerData(); return; } } // Optimization: Cache remaining ConVar lookups var hostportConVar = ConVar.Find("hostport"); var hostnameConVar = ConVar.Find("hostname"); var rconPasswordConVar = ConVar.Find("rcon_password"); var address = $"{ipAddress}:{hostportConVar?.GetPrimitiveValue()}"; var hostname = hostnameConVar?.StringValue ?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; var rconPassword = rconPasswordConVar?.StringValue ?? ""; CS2_SimpleAdmin.IpAddress = address; Task.Run(async () => { try { await using var connection = await CS2_SimpleAdmin.DatabaseProvider.CreateConnectionAsync(); int? serverId = await connection.ExecuteScalarAsync( "SELECT id FROM sa_servers WHERE address = @address", new { address }); if (serverId == null) { await connection.ExecuteAsync( "INSERT INTO sa_servers (address, hostname, rcon_password) VALUES (@address, @hostname, @rconPassword)", new { address, hostname, rconPassword }); serverId = await connection.ExecuteScalarAsync( "SELECT id FROM sa_servers WHERE address = @address", new { address }); } else { await connection.ExecuteAsync( "UPDATE sa_servers SET hostname = @hostname, rcon_password = @rconPassword WHERE address = @address", new { address, hostname, rconPassword }); } CS2_SimpleAdmin.ServerId = serverId; CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress); CS2_SimpleAdmin.ServerLoaded = true; if (CS2_SimpleAdmin.Instance.CacheManager != null) { await CS2_SimpleAdmin.Instance.CacheManager.InitializeCacheAsync(); } } catch (Exception ex) { CS2_SimpleAdmin._logger?.LogCritical("Unable to create or get server_id: " + ex.Message); } if (CS2_SimpleAdmin.Instance.Config.EnableMetrics) { var queryString = $"?address={address}&hostname={hostname}"; var client = CS2_SimpleAdmin.HttpClient; try { await client.GetAsync($"https://api.daffyy.dev/index.php{queryString}"); } catch (HttpRequestException ex) { CS2_SimpleAdmin._logger?.LogWarning($"Unable to make metrics call: {ex.Message}"); } } }); CS2_SimpleAdmin.SimpleAdminApi?.OnSimpleAdminReadyEvent(); }); } }