diff --git a/Commands.cs b/Commands.cs index ddc2c6e9..739601cf 100644 --- a/Commands.cs +++ b/Commands.cs @@ -11,7 +11,7 @@ namespace WeaponPaints { private void OnCommandRefresh(CCSPlayerController? player, CommandInfo command) { - if (Config.Additional.CommandsRefresh.Count > 0 || !Config.Additional.SkinEnabled || !g_bCommandsAllowed) return; + if (Config.Additional.CommandsRefresh.Count == 0 || !Config.Additional.SkinEnabled || !g_bCommandsAllowed) return; if (!Utility.IsPlayerValid(player)) return; if (player == null || !player.IsValid || player.UserId == null || player.IsBot) return; @@ -38,7 +38,11 @@ namespace WeaponPaints _ = Task.Run(async () => await weaponSync.GetPlayerData(playerInfo)); GivePlayerGloves(player); + GivePlayerAgent(player); + GivePlayerMusicKit(player); RefreshWeapons(player); + AddTimer(0.1f, () => GivePlayerPin(player)); + AddTimer(0.15f, () => GivePlayerPin(player)); } if (!string.IsNullOrEmpty(Localizer["wp_command_refresh_done"])) @@ -471,7 +475,7 @@ namespace WeaponPaints var selectedPaintName = option.Text; var selectedAgent = agentsList.FirstOrDefault(g => g.ContainsKey("agent_name") && - g["agent_name"] != null && g["agent_name"]!.ToString() == selectedPaintName && + g["agent_name"] != null && g["agent_name"]!.ToString().Contains(selectedPaintName) == true && g["team"] != null && (int)(g["team"]!) == player.TeamNum); if (selectedAgent == null) return; @@ -499,7 +503,7 @@ namespace WeaponPaints if (!string.IsNullOrEmpty(Localizer["wp_agent_menu_select"])) { - player!.Print(Localizer["wp_agent_menu_select", selectedPaintName]); + player!.Print(Localizer["wp_agent_menu_select", selectedAgent?["agent_name"] ?? selectedPaintName]); } if (player.TeamNum == 3) @@ -521,6 +525,7 @@ namespace WeaponPaints _ = Task.Run(async () => { await weaponSync.SyncAgentToDatabase(playerInfo); + GivePlayerAgent(player); }); } }; @@ -584,7 +589,7 @@ namespace WeaponPaints var selectedPaintName = option.Text; - var selectedMusic = musicList.FirstOrDefault(g => g.ContainsKey("name") && g["name"]?.ToString() == selectedPaintName); + var selectedMusic = musicList.FirstOrDefault(g => g.ContainsKey("name") && g["name"]?.ToString().Contains(selectedPaintName) == true); if (selectedMusic != null) { if (!selectedMusic.ContainsKey("id") || @@ -618,7 +623,7 @@ namespace WeaponPaints if (!string.IsNullOrEmpty(Localizer["wp_music_menu_select"])) { - player!.Print(Localizer["wp_music_menu_select", selectedPaintName]); + player!.Print(Localizer["wp_music_menu_select", selectedMusic["name"] ?? selectedPaintName]); } if (weaponSync != null) @@ -658,6 +663,8 @@ namespace WeaponPaints }); } } + + GivePlayerMusicKit(player); }; musicSelectionMenu.AddMenuOption(Localizer["None"], handleMusicSelection); diff --git a/Config.cs b/Config.cs index 60801e50..56120f17 100644 --- a/Config.cs +++ b/Config.cs @@ -41,6 +41,9 @@ namespace WeaponPaints [JsonPropertyName("NameTagEnabled")] public bool NameTagEnabled { get; set; } = true; + [JsonPropertyName("PinEnabled")] + public bool PinEnabled { get; set; } = true; + [JsonPropertyName("CommandsKnife")] public List CommandsKnife { get; set; } = ["knife", "knives"]; diff --git a/Events.cs b/Events.cs index 0fc1ee36..afb0be0b 100644 --- a/Events.cs +++ b/Events.cs @@ -1,4 +1,4 @@ -using CounterStrikeSharp.API; +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Entities; @@ -91,6 +91,10 @@ namespace WeaponPaints { g_playersMusic.TryRemove(player.Slot, out _); } + if (Config.Additional.PinEnabled) + { + g_playersPin.TryRemove(player.Slot, out _); + } commandsCooldown.Remove(player.Slot); @@ -125,6 +129,7 @@ namespace WeaponPaints GivePlayerMusicKit(player); GivePlayerAgent(player); GivePlayerGloves(player); + GivePlayerPin(player); return HookResult.Continue; } diff --git a/Utility.cs b/Utility.cs index 9d28d341..1ad1c836 100644 --- a/Utility.cs +++ b/Utility.cs @@ -1,4 +1,4 @@ -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Translations; using Dapper; using Microsoft.Extensions.Logging; @@ -30,7 +30,8 @@ namespace WeaponPaints "CREATE TABLE IF NOT EXISTS `wp_users_knives` (`user_id` INT UNSIGNED NOT NULL, `knife` SMALLINT UNSIGNED NOT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", "CREATE TABLE IF NOT EXISTS `wp_users_gloves` (`user_id` INT UNSIGNED NOT NULL, `weapon_defindex` SMALLINT UNSIGNED DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", "CREATE TABLE IF NOT EXISTS `wp_users_musics` (`user_id` INT UNSIGNED NOT NULL, `music` SMALLINT UNSIGNED DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", - "CREATE TABLE IF NOT EXISTS `wp_users_agents` (`user_id` INT UNSIGNED NOT NULL,`agent_ct` varchar(64) DEFAULT NULL,`agent_t` varchar(64) DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;" + "CREATE TABLE IF NOT EXISTS `wp_users_agents` (`user_id` INT UNSIGNED NOT NULL,`agent_ct` varchar(64) DEFAULT NULL,`agent_t` varchar(64) DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", + "CREATE TABLE IF NOT EXISTS `wp_users_pins` (`user_id` INT UNSIGNED NOT NULL, `pin` SMALLINT UNSIGNED DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", }; foreach (var query in createTableQueries) diff --git a/WeaponAction.cs b/WeaponAction.cs index d77637c2..a5fdef62 100644 --- a/WeaponAction.cs +++ b/WeaponAction.cs @@ -401,6 +401,18 @@ public partial class WeaponPaints Utilities.SetStateChanged(player, "CCSPlayerController", "m_iMusicKitID"); } + private static void GivePlayerPin(CCSPlayerController player) + { + if (!g_playersPin.TryGetValue(player.Slot, out var value)) return; + if (player.InventoryServices == null) return; + + for (var index = 0; index < player.InventoryServices.Rank.Length; index++) + { + player.InventoryServices.Rank[index] = index == 5 ? (MedalRank_t)value : MedalRank_t.MEDAL_RANK_NONE; + Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInventoryServices"); + } + } + private void GiveOnItemPickup(CCSPlayerController player) { var pawn = player.PlayerPawn.Value; diff --git a/WeaponPaints.cs b/WeaponPaints.cs index 6021328e..8de890a8 100644 --- a/WeaponPaints.cs +++ b/WeaponPaints.cs @@ -83,6 +83,7 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig g_playersKnife = new(); internal static ConcurrentDictionary g_playersGlove = new(); internal static ConcurrentDictionary g_playersMusic = new(); + internal static ConcurrentDictionary g_playersPin = new(); internal static ConcurrentDictionary g_playersAgent = new(); internal static ConcurrentDictionary> gPlayerWeaponsInfo = new(); internal static ConcurrentDictionary g_playersDatabaseIndex = new(); diff --git a/WeaponSynchronization.cs b/WeaponSynchronization.cs index 6c69ff43..ca33a3a0 100644 --- a/WeaponSynchronization.cs +++ b/WeaponSynchronization.cs @@ -1,4 +1,4 @@ -using System.Collections.Concurrent; +using System.Collections.Concurrent; using Dapper; using MySqlConnector; @@ -29,7 +29,7 @@ internal class WeaponSynchronization if (databaseIndex != null) { WeaponPaints.g_playersDatabaseIndex[playerInfo.Slot] = (int)databaseIndex; - query = "UPDATE `wp_users` SET `last_update` = @lastUpdate WHERE `id` = @databaseIndex"; + query = "UPDATE `wp_users` SET `last_online` = @lastUpdate WHERE `id` = @databaseIndex"; await connection.ExecuteAsync(query, new { lastUpdate = DateTime.Now, @@ -71,6 +71,8 @@ internal class WeaponSynchronization GetMusicFromDatabase(player, connection); if (_config.Additional.SkinEnabled) GetWeaponPaintsFromDatabase(player, connection); + if (_config.Additional.PinEnabled) + GetPinFromDatabase(player, connection); } catch (Exception ex) { @@ -200,6 +202,24 @@ internal class WeaponSynchronization } } + private void GetPinFromDatabase(PlayerInfo? player, MySqlConnection connection) + { + try + { + if (!_config.Additional.PinEnabled || string.IsNullOrEmpty(player?.SteamId.ToString())) + return; + + const string query = "SELECT `pin` FROM `wp_users_pins` WHERE `user_id` = @userId"; + var pinData = connection.QueryFirstOrDefault(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot] }); + + if (pinData != null) WeaponPaints.g_playersPin[player.Slot] = pinData.Value; + } + catch (Exception ex) + { + Utility.Log($"An error occurred in GetPinFromDatabase: {ex.Message}"); + } + } + internal async Task PurgeExpiredUsers() { try @@ -208,7 +228,7 @@ internal class WeaponSynchronization await using var transaction = await connection.BeginTransactionAsync(); var userIds = await connection.QueryAsync( - $"SELECT id FROM wp_users WHERE last_update < NOW() - INTERVAL {_config.Additional.ExpireOlderThan} DAY", + $"SELECT id FROM wp_users WHERE last_online < NOW() - INTERVAL {_config.Additional.ExpireOlderThan} DAY", transaction: transaction ); @@ -234,6 +254,9 @@ internal class WeaponSynchronization query = $"DELETE FROM wp_users_musics WHERE user_id IN ({ids})"; await connection.ExecuteAsync(query, transaction: transaction); + query = $"DELETE FROM wp_users_pins WHERE user_id IN ({ids})"; + await connection.ExecuteAsync(query, transaction: transaction); + // Step 3: Delete users from wp_users query = $"DELETE FROM wp_users WHERE id IN ({ids})"; await connection.ExecuteAsync(query, transaction: transaction); @@ -367,7 +390,7 @@ internal class WeaponSynchronization { await using var connection = await _database.GetConnectionAsync(); const string query = - "INSERT INTO `wp_users_musics` (`user_id`, `music_id`) VALUES(@userId, @newMusic) ON DUPLICATE KEY UPDATE `music_id` = @newMusic"; + "INSERT INTO `wp_users_musics` (`user_id`, `music`) VALUES(@userId, @newMusic) ON DUPLICATE KEY UPDATE `music` = @newMusic"; await connection.ExecuteAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], newMusic = music }); } catch (Exception e)