From 56537971ade4bc1532ad57fcb7ee8f83aa13e9ac Mon Sep 17 00:00:00 2001 From: Nereziel Date: Sat, 3 Feb 2024 05:34:10 +0100 Subject: [PATCH] test update min CSShrap 155 globalshare not working db remake add option to not use ontick fix to cs2 weapon models !skins will save only changed weapon --- .gitignore | 1 + Commands.cs | 48 ++++---- Config.cs | 22 +++- Events.cs | 152 +++++++++++------------ PlayerInfo.cs | 4 +- Utility.cs | 24 ++-- WeaponAction.cs | 52 ++++---- WeaponInfo.cs | 10 +- WeaponPaints.cs | 180 +++++++++++++++------------ WeaponSynchronization.cs | 256 ++++++++++++++++++++++++++------------- 10 files changed, 429 insertions(+), 320 deletions(-) diff --git a/.gitignore b/.gitignore index 4a1b51e0..27e36d31 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .vs/ bin/ obj/ +.test/ diff --git a/Commands.cs b/Commands.cs index 78158223..6d8245e6 100644 --- a/Commands.cs +++ b/Commands.cs @@ -8,7 +8,7 @@ namespace WeaponPaints { private void OnCommandRefresh(CCSPlayerController? player, CommandInfo command) { - if (!Config.Additional.CommandWpEnabled || !Config.Additional.SkinEnabled || !g_bCommandsAllowed) return; + if (!Config.AdditionalSetting.CommandWpEnabled || !Config.AdditionalSetting.SkinEnabled || !g_bCommandsAllowed) return; if (!Utility.IsPlayerValid(player)) return; if (player == null || player.Index <= 0) return; int playerIndex = (int)player!.Index; @@ -17,7 +17,7 @@ namespace WeaponPaints { UserId = player.UserId, Index = (int)player.Index, - SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(), + SteamId = player?.AuthorizedSteamID?.SteamId64, Name = player?.PlayerName, IpAddress = player?.IpAddress?.Split(":")[0] }; @@ -30,7 +30,7 @@ namespace WeaponPaints commandsCooldown[(int)player.UserId] = DateTime.UtcNow.AddSeconds(Config.CmdRefreshCooldownSeconds); if (weaponSync != null) Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo)); - if (Config.Additional.KnifeEnabled) + if (Config.AdditionalSetting.KnifeEnabled) { if (weaponSync != null) Task.Run(async () => await weaponSync.GetKnifeFromDatabase(playerInfo)); @@ -51,7 +51,7 @@ namespace WeaponPaints private void OnCommandWS(CCSPlayerController? player, CommandInfo command) { - if (!Config.Additional.SkinEnabled) return; + if (!Config.AdditionalSetting.SkinEnabled) return; if (!Utility.IsPlayerValid(player)) return; if (!string.IsNullOrEmpty(Localizer["wp_info_website"])) @@ -62,7 +62,7 @@ namespace WeaponPaints { player!.Print(Localizer["wp_info_refresh"]); } - if (!Config.Additional.KnifeEnabled) return; + if (!Config.AdditionalSetting.KnifeEnabled) return; if (!string.IsNullOrEmpty(Localizer["wp_info_knife"])) { player!.Print(Localizer["wp_info_knife"]); @@ -71,19 +71,19 @@ namespace WeaponPaints private void RegisterCommands() { - AddCommand($"css_{Config.Additional.CommandSkin}", "Skins info", (player, info) => + AddCommand($"css_{Config.AdditionalSetting.CommandSkin}", "Skins info", (player, info) => { if (!Utility.IsPlayerValid(player)) return; OnCommandWS(player, info); }); - AddCommand($"css_{Config.Additional.CommandRefresh}", "Skins refresh", (player, info) => + AddCommand($"css_{Config.AdditionalSetting.CommandRefresh}", "Skins refresh", (player, info) => { if (!Utility.IsPlayerValid(player) || !g_bCommandsAllowed) return; OnCommandRefresh(player, info); }); - if (Config.Additional.CommandKillEnabled) + if (Config.AdditionalSetting.CommandKillEnabled) { - AddCommand($"css_{Config.Additional.CommandKill}", "kill yourself", (player, info) => + AddCommand($"css_{Config.AdditionalSetting.CommandKill}", "kill yourself", (player, info) => { if (player == null || !Utility.IsPlayerValid(player) || player.PlayerPawn.Value == null || !player!.PlayerPawn.IsValid) return; @@ -94,7 +94,7 @@ namespace WeaponPaints private void SetupKnifeMenu() { - if (!Config.Additional.KnifeEnabled || !g_bCommandsAllowed) return; + if (!Config.AdditionalSetting.KnifeEnabled || !g_bCommandsAllowed) return; var knivesOnly = weaponList .Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet")) @@ -115,7 +115,7 @@ namespace WeaponPaints player!.Print(Localizer["wp_knife_menu_select", knifeName]); } - if (!string.IsNullOrEmpty(Localizer["wp_knife_menu_kill"]) && Config.Additional.CommandKillEnabled) + if (!string.IsNullOrEmpty(Localizer["wp_knife_menu_kill"]) && Config.AdditionalSetting.CommandKillEnabled) { player!.Print(Localizer["wp_knife_menu_kill"]); } @@ -124,7 +124,7 @@ namespace WeaponPaints { UserId = player.UserId, Index = (int)player.Index, - SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(), + SteamId = player?.AuthorizedSteamID?.SteamId64, Name = player?.PlayerName, IpAddress = player?.IpAddress?.Split(":")[0] }; @@ -145,7 +145,7 @@ namespace WeaponPaints { giveItemMenu.AddMenuOption(knifePair.Value, handleGive); } - AddCommand($"css_{Config.Additional.CommandKnife}", "Knife Menu", (player, info) => + AddCommand($"css_{Config.AdditionalSetting.CommandKnife}", "Knife Menu", (player, info) => { if (!Utility.IsPlayerValid(player) || !g_bCommandsAllowed) return; @@ -212,25 +212,25 @@ namespace WeaponPaints if (firstSkin != null && firstSkin.TryGetValue("weapon_defindex", out var weaponDefIndexObj) && weaponDefIndexObj != null && - int.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) && - int.TryParse(selectedPaintID, out var paintID)) + ushort.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) && + ushort.TryParse(selectedPaintID, out var paintID)) { p!.Print(Localizer["wp_skin_menu_select", selectedSkin]); - if (!gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex)) - { - gPlayerWeaponsInfo[playerIndex][weaponDefIndex] = new WeaponInfo(); - } + if (!gPlayerWeaponsInfo[playerIndex].TryGetValue(weaponDefIndex, out _)) + { + gPlayerWeaponsInfo[playerIndex][weaponDefIndex] = new WeaponInfo(); + } - gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Paint = paintID; - gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.01f; + gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Paint = paintID; + gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.00001f; gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Seed = 0; PlayerInfo playerInfo = new PlayerInfo { UserId = player.UserId, Index = (int)player.Index, - SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(), + SteamId = player?.AuthorizedSteamID?.SteamId64, Name = player?.PlayerName, IpAddress = player?.IpAddress?.Split(":")[0] }; @@ -238,7 +238,7 @@ namespace WeaponPaints if (!Config.GlobalShare) { if (weaponSync != null) - Task.Run(async () => await weaponSync.SyncWeaponPaintsToDatabase(playerInfo)); + Task.Run(async () => await weaponSync.SyncWeaponPaintToDatabase(playerInfo, weaponDefIndex)); } } }; @@ -273,7 +273,7 @@ namespace WeaponPaints weaponSelectionMenu.AddMenuOption(weaponName, handleWeaponSelection); } // Command to open the weapon selection menu for players - AddCommand($"css_{Config.Additional.CommandSkinSelection}", "Skins selection menu", (player, info) => + AddCommand($"css_{Config.AdditionalSetting.CommandSkinSelection}", "Skins selection menu", (player, info) => { if (!Utility.IsPlayerValid(player)) return; diff --git a/Config.cs b/Config.cs index 2795400c..f64d9393 100644 --- a/Config.cs +++ b/Config.cs @@ -3,9 +3,13 @@ using System.Text.Json.Serialization; namespace WeaponPaints { - public class Additional + public class AdditionalSetting { - [JsonPropertyName("SkinVisibilityFix")] + + [JsonPropertyName("UseMetamodAlwaysLegacyModel")] + public bool UseMetamodAlwaysLegacyModel { get; set; } = false; + + [JsonPropertyName("SkinVisibilityFix")] public bool SkinVisibilityFix { get; set; } = true; [JsonPropertyName("KnifeEnabled")] @@ -14,7 +18,13 @@ namespace WeaponPaints [JsonPropertyName("SkinEnabled")] public bool SkinEnabled { get; set; } = true; - [JsonPropertyName("CommandWpEnabled")] + [JsonPropertyName("MusicKitEnabled")] + public bool MusicKitEnabled { get; set; } = true; + + [JsonPropertyName("NameTagEnabled")] + public bool NameTagEnabled { get; set; } = true; + + [JsonPropertyName("CommandWpEnabled")] public bool CommandWpEnabled { get; set; } = true; [JsonPropertyName("CommandKillEnabled")] @@ -46,7 +56,7 @@ namespace WeaponPaints public class WeaponPaintsConfig : BasePluginConfig { - public override int Version { get; set; } = 4; + public override int Version { get; set; } = 5; [JsonPropertyName("DatabaseHost")] public string DatabaseHost { get; set; } = ""; @@ -75,8 +85,8 @@ namespace WeaponPaints [JsonPropertyName("Website")] public string Website { get; set; } = "example.com/skins"; - [JsonPropertyName("Additional")] - public Additional Additional { get; set; } = new Additional(); + [JsonPropertyName("AdditionalSetting")] + public AdditionalSetting AdditionalSetting { get; set; } = new AdditionalSetting(); } } diff --git a/Events.cs b/Events.cs index 583d4b59..29171812 100644 --- a/Events.cs +++ b/Events.cs @@ -1,5 +1,7 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Entities; +using System.Numerics; namespace WeaponPaints { @@ -13,22 +15,18 @@ namespace WeaponPaints { UserId = player.UserId, Index = (int)player.Index, - SteamId = player.SteamID.ToString(), + SteamId = player.SteamID, Name = player?.PlayerName, IpAddress = player?.IpAddress?.Split(":")[0] }; - if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || weaponSync == null) return; + if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || weaponSync == null) return; - Task.Run(async () => + Task.Run(async () => { - if (Config.Additional.SkinEnabled) - await weaponSync.GetKnifeFromDatabase(playerInfo); + await weaponSync.GetPlayerDatabaseIndex(playerInfo); }); - - //if (Config.Additional.KnifeEnabled && weaponSync != null) - //_ = weaponSync.GetKnifeFromDatabase(playerIndex); - } + } private void OnClientDisconnect(int playerSlot) { @@ -36,16 +34,19 @@ namespace WeaponPaints if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.UserId == null) return; - if (Config.Additional.KnifeEnabled) + g_playersDatabaseIndex.TryRemove((int)player.Index, out _); + if (Config.AdditionalSetting.KnifeEnabled) g_playersKnife.TryRemove((int)player.Index, out _); - if (Config.Additional.SkinEnabled) + if (Config.AdditionalSetting.SkinEnabled) { if (gPlayerWeaponsInfo.TryRemove((int)player.Index, out var innerDictionary)) { innerDictionary.Clear(); } } - if (commandsCooldown.ContainsKey((int)player.UserId)) + if (Config.AdditionalSetting.MusicKitEnabled) + g_playersMusicKit.TryRemove((int)player.Index, out _); + if (commandsCooldown.ContainsKey((int)player.UserId)) { commandsCooldown.Remove((int)player.UserId); } @@ -53,7 +54,7 @@ namespace WeaponPaints private void OnEntityCreated(CEntityInstance entity) { - if (!Config.Additional.SkinEnabled) return; + if (!Config.AdditionalSetting.SkinEnabled) return; if (entity == null || !entity.IsValid || string.IsNullOrEmpty(entity.DesignerName)) return; string designerName = entity.DesignerName; if (!weaponList.ContainsKey(designerName)) return; @@ -93,42 +94,41 @@ namespace WeaponPaints if (player == null || !player.IsValid) return HookResult.Continue; /* - if (Config.Additional.SkinVisibilityFix) + if (Config.AdditionalSetting.SkinVisibilityFix) AddTimer(0.2f, () => RefreshSkins(player)); */ return HookResult.Continue; } - - /* - private HookResult OnItemPickup(EventItemPickup @event, GameEventInfo info) - { - if (@event.Defindex == 42 || @event.Defindex == 59) - { - CCSPlayerController? player = @event.Userid; - if (player == null || !player.IsValid || !g_knifePickupCount.ContainsKey((int)player.Index) || player.IsBot || !g_playersKnife.ContainsKey((int)player.Index)) - return HookResult.Continue; + /* + private HookResult OnItemPickup(EventItemPickup @event, GameEventInfo info) + { + if (@event.Defindex == 42 || @event.Defindex == 59) + { + CCSPlayerController? player = @event.Userid; + if (player == null || !player.IsValid || !g_knifePickupCount.ContainsKey((int)player.Index) || player.IsBot || !g_playersKnife.ContainsKey((int)player.Index)) + return HookResult.Continue; - if (g_knifePickupCount[(int)player.Index] >= 2) return HookResult.Continue; + if (g_knifePickupCount[(int)player.Index] >= 2) return HookResult.Continue; - if (g_playersKnife.ContainsKey((int)player.Index) - && - g_playersKnife[(int)player.Index] != "weapon_knife") - { - g_knifePickupCount[(int)player.Index]++; + if (g_playersKnife.ContainsKey((int)player.Index) + && + g_playersKnife[(int)player.Index] != "weapon_knife") + { + g_knifePickupCount[(int)player.Index]++; - RemovePlayerKnife(player, true); + RemovePlayerKnife(player, true); - if (!PlayerHasKnife(player) && Config.Additional.GiveKnifeAfterRemove) - AddTimer(0.3f, () => GiveKnifeToPlayer(player)); - } - } - return HookResult.Continue; - } - */ + if (!PlayerHasKnife(player) && Config.AdditionalSetting.GiveKnifeAfterRemove) + AddTimer(0.3f, () => GiveKnifeToPlayer(player)); + } + } + return HookResult.Continue; + } + */ - public HookResult OnPickup(CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay) + public HookResult OnPickup(CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay) { CCSPlayerController? player = Utilities.GetEntityFromIndex((int)activator.Index).OriginalController.Value; @@ -150,26 +150,25 @@ namespace WeaponPaints { g_knifePickupCount[(int)player.Index]++; player.RemoveItemByDesignerName(weapon.DesignerName); - if (Config.Additional.GiveKnifeAfterRemove) + if (Config.AdditionalSetting.GiveKnifeAfterRemove) AddTimer(0.2f, () => GiveKnifeToPlayer(player)); } return HookResult.Continue; } - - private void OnMapStart(string mapName) + private void OnMapStart(string mapName) { - if (!Config.Additional.KnifeEnabled) return; - // TODO - // needed for now - AddTimer(2.0f, () => + if (!Config.AdditionalSetting.KnifeEnabled) return; + // TODO + // needed for now + AddTimer(2.0f, () => { NativeAPI.IssueServerCommand("mp_t_default_melee \"\""); NativeAPI.IssueServerCommand("mp_ct_default_melee \"\""); NativeAPI.IssueServerCommand("mp_equipment_reset_rounds 0"); - if (Config.GlobalShare) + if (Config.GlobalShare) GlobalShareConnect(); weaponSync = new WeaponSynchronization(DatabaseConnectionString, Config, GlobalShareApi, GlobalShareServerId); @@ -178,26 +177,24 @@ namespace WeaponPaints g_hTimerCheckSkinsData = AddTimer(10.0f, () => { List players = Utilities.GetPlayers(); - - foreach (CCSPlayerController player in players) + HashSet playerIndexes = new HashSet(gPlayerWeaponsInfo.Keys); + foreach (CCSPlayerController player in players) { if (player.IsBot || player.IsHLTV || player.SteamID.ToString() == "") continue; - if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue; + //if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue; + if (playerIndexes.Contains((int)player.Index)) continue; - PlayerInfo playerInfo = new PlayerInfo + PlayerInfo playerInfo = new PlayerInfo { UserId = player.UserId, Index = (int)player.Index, - SteamId = player?.SteamID.ToString(), + SteamId = player?.SteamID, Name = player?.PlayerName, IpAddress = player?.IpAddress?.Split(":")[0] }; - - if (Config.Additional.SkinEnabled && weaponSync != null) - _ = weaponSync.GetWeaponPaintsFromDatabase(playerInfo); - if (Config.Additional.KnifeEnabled && weaponSync != null) - _ = weaponSync.GetKnifeFromDatabase(playerInfo); - } + if (weaponSync != null) + _ = weaponSync.GetKnifeFromDatabase(playerInfo); + } }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE | CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT); } @@ -211,22 +208,19 @@ namespace WeaponPaints { UserId = player.UserId, Index = (int)player.Index, - SteamId = player?.SteamID.ToString(), + SteamId = player?.SteamID, Name = player?.PlayerName, IpAddress = player?.IpAddress?.Split(":")[0] }; - if (!gPlayerWeaponsInfo.ContainsKey((int)player!.Index)) + if (!g_playersDatabaseIndex.ContainsKey((int)player!.Index)) { Console.WriteLine($"[WeaponPaints] Retrying to retrieve player {player.PlayerName} skins"); Task.Run(async () => { - if (Config.Additional.SkinEnabled) - await weaponSync.GetWeaponPaintsFromDatabase(playerInfo); - if (Config.Additional.KnifeEnabled) - await weaponSync.GetKnifeFromDatabase(playerInfo); - }); - } + await weaponSync.GetPlayerDatabaseIndex(playerInfo); + }); + } return HookResult.Continue; } @@ -239,7 +233,7 @@ namespace WeaponPaints return HookResult.Continue; } - if (Config.Additional.KnifeEnabled && !PlayerHasKnife(player)) + if (Config.AdditionalSetting.KnifeEnabled && !PlayerHasKnife(player)) { g_knifePickupCount[(int)player.Index] = 0; GiveKnifeToPlayer(player); @@ -247,7 +241,7 @@ namespace WeaponPaints } /* - if (Config.Additional.SkinVisibilityFix) + if (Config.AdditionalSetting.SkinVisibilityFix) { AddTimer(0.3f, () => RefreshSkins(player)); } @@ -298,11 +292,11 @@ namespace WeaponPaints if ( viewModel.Value.CBodyComponent != null && viewModel.Value.CBodyComponent.SceneNode != null - ) + && weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2 + ) { - var skeleton = GetSkeletonInstance(viewModel.Value.CBodyComponent.SceneNode); - skeleton.ModelState.MeshGroupMask = 2; - } + weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2; + } Utilities.SetStateChanged(viewModel.Value, "CBaseEntity", "m_CBodyComponent"); } @@ -318,16 +312,18 @@ namespace WeaponPaints RegisterListener(OnClientPutInServer); RegisterListener(OnClientDisconnect); RegisterListener(OnMapStart); - RegisterListener(OnTick); - RegisterEventHandler(OnPlayerConnectFull); + if (!Config.AdditionalSetting.UseMetamodAlwaysLegacyModel) + RegisterListener(OnTick); + + RegisterEventHandler(OnPlayerConnectFull); RegisterEventHandler(OnPlayerSpawn); RegisterEventHandler(OnRoundStart, HookMode.Pre); RegisterEventHandler(OnRoundEnd); RegisterEventHandler(OnEventItemPurchasePost); //RegisterEventHandler(OnItemPickup); HookEntityOutput("weapon_knife", "OnPlayerPickup", OnPickup, HookMode.Pre); - } + } /* WORKAROUND FOR CLIENTS WITHOUT STEAMID ON AUTHORIZATION */ @@ -338,15 +334,15 @@ namespace WeaponPaints if (player == null || !player.IsValid || !player.EntityIndex.HasValue || player.IsHLTV) return HookResult.Continue; int playerIndex = (int)player.EntityIndex.Value.Value; - if (Config.Additional.SkinEnabled && weaponSync != null) + if (Config.AdditionalSetting.SkinEnabled && weaponSync != null) _ = weaponSync.GetWeaponPaintsFromDatabase(playerIndex); - if (Config.Additional.KnifeEnabled && weaponSync != null) + if (Config.AdditionalSetting.KnifeEnabled && weaponSync != null) _ = weaponSync.GetKnifeFromDatabase(playerIndex); Task.Run(async () => { - if (Config.Additional.SkinEnabled && weaponSync != null) - if (Config.Additional.KnifeEnabled && weaponSync != null) + if (Config.AdditionalSetting.SkinEnabled && weaponSync != null) + if (Config.AdditionalSetting.KnifeEnabled && weaponSync != null) }); return HookResult.Continue; diff --git a/PlayerInfo.cs b/PlayerInfo.cs index dba103b6..780e0ec9 100644 --- a/PlayerInfo.cs +++ b/PlayerInfo.cs @@ -4,8 +4,8 @@ { public int Index { get; set; } public int? UserId { get; set; } - public string? SteamId { get; set; } + public ulong? SteamId { get; set; } public string? Name { get; set; } public string? IpAddress { get; set; } - } + } } diff --git a/Utility.cs b/Utility.cs index d18c8ce2..9740a5ad 100644 --- a/Utility.cs +++ b/Utility.cs @@ -27,8 +27,7 @@ namespace WeaponPaints return builder.ConnectionString; } - - internal static async void CheckDatabaseTables() + internal static async void CheckDatabaseTables() { try { @@ -37,15 +36,22 @@ namespace WeaponPaints using var transaction = await connection.BeginTransactionAsync(); - try + // Minimal version for MySQL 5.6.5 + string[] sqlCommands = new string[] + { + "CREATE TABLE IF NOT EXISTS `wp_users` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `steamid` BIGINT UNSIGNED NOT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `unique_steamid` (`steamid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", + "CREATE TABLE IF NOT EXISTS `wp_users_items` (`user_id` INT UNSIGNED NOT NULL, `weapon` SMALLINT UNSIGNED NOT NULL, `paint` SMALLINT UNSIGNED NOT NULL, `wear` FLOAT NOT NULL DEFAULT 0.00001, `seed` SMALLINT UNSIGNED NOT NULL DEFAULT 0, `nametag` VARCHAR(20) DEFAULT NULL, `stattrack` INT UNSIGNED NOT NULL DEFAULT 0, `stattrack_enabled` SMALLINT NOT NULL DEFAULT 0, `quality` SMALLINT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`user_id`,`weapon`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", + "CREATE TABLE IF NOT EXISTS `wp_users_knife` (`user_id` INT UNSIGNED NOT NULL, `knife` VARCHAR(32) DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;", + "CREATE TABLE IF NOT EXISTS `wp_users_music` (`user_id` INT UNSIGNED NOT NULL, `music` SMALLINT UNSIGNED DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;" + }; + try { - string createTable1 = "CREATE TABLE IF NOT EXISTS `wp_player_skins` (`steamid` varchar(64) NOT NULL, `weapon_defindex` int(6) NOT NULL, `weapon_paint_id` int(6) NOT NULL, `weapon_wear` float NOT NULL DEFAULT 0.000001, `weapon_seed` int(16) NOT NULL DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci"; - string createTable2 = "CREATE TABLE IF NOT EXISTS `wp_player_knife` (`steamid` varchar(64) NOT NULL, `knife` varchar(64) NOT NULL, UNIQUE (`steamid`)) ENGINE = InnoDB"; + foreach (string command in sqlCommands) + { + await connection.ExecuteAsync(command, transaction: transaction); + } - await connection.ExecuteAsync(createTable1, transaction: transaction); - await connection.ExecuteAsync(createTable2, transaction: transaction); - - await transaction.CommitAsync(); + await transaction.CommitAsync(); } catch (Exception) { diff --git a/WeaponAction.cs b/WeaponAction.cs index 67659f1b..afb0ae2a 100644 --- a/WeaponAction.cs +++ b/WeaponAction.cs @@ -19,15 +19,14 @@ namespace WeaponPaints if (isKnife && !g_playersKnife.ContainsKey(playerIndex) || isKnife && g_playersKnife[playerIndex] == "weapon_knife") return; - int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex; - + ushort weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex; if (isKnife) { weapon.AttributeManager.Item.EntityQuality = 3; } - if (_config.Additional.GiveRandomSkin && + if (_config.AdditionalSetting.GiveRandomSkin && !gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex)) { // Random skins @@ -36,13 +35,12 @@ namespace WeaponPaints weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32; weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex); weapon.FallbackSeed = 0; - weapon.FallbackWear = 0.000001f; + weapon.FallbackWear = 0.00001f; if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) { - var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode); - if (skeleton.ModelState.MeshGroupMask != 2) + if (weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2) { - skeleton.ModelState.MeshGroupMask = 2; + weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2; } } return; @@ -58,25 +56,25 @@ namespace WeaponPaints weapon.FallbackSeed = weaponInfo.Seed; weapon.FallbackWear = weaponInfo.Wear; - if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) + if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) { - var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode); - if (skeleton.ModelState.MeshGroupMask != 2) + if (weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2) { - skeleton.ModelState.MeshGroupMask = 2; - } - } - } + weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2; + } + } + + } internal static void GiveKnifeToPlayer(CCSPlayerController? player) { - if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return; + if (!_config.AdditionalSetting.KnifeEnabled || player == null || !player.IsValid) return; if (g_playersKnife.TryGetValue((int)player.Index, out var knife)) { player.GiveNamedItem(knife); } - else if (_config.Additional.GiveRandomKnife) + else if (_config.AdditionalSetting.GiveRandomKnife) { var knifeTypes = weaponList.Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet")).ToDictionary(pair => pair.Key, pair => pair.Value); @@ -95,7 +93,7 @@ namespace WeaponPaints internal static bool PlayerHasKnife(CCSPlayerController? player) { - if (!_config.Additional.KnifeEnabled) return false; + if (!_config.AdditionalSetting.KnifeEnabled) return false; if (player == null || !player.IsValid || player.PlayerPawn == null || !player.PlayerPawn.IsValid || !player.PawnIsAlive) { @@ -177,7 +175,7 @@ namespace WeaponPaints } } } - + /* internal void RefreshSkins(CCSPlayerController? player) { return; @@ -187,8 +185,8 @@ namespace WeaponPaints AddTimer(0.25f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot2")); AddTimer(0.38f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot1")); } - - internal void RefreshWeapons(CCSPlayerController? player) + */ + internal void RefreshWeapons(CCSPlayerController? player) { if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PawnIsAlive) return; if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null) return; @@ -213,13 +211,13 @@ namespace WeaponPaints } else { - if (!weaponDefindex.ContainsKey(weapon.Value.AttributeManager.Item.ItemDefinitionIndex)) continue; + if (!WeaponDefindex.ContainsKey(weapon.Value.AttributeManager.Item.ItemDefinitionIndex)) continue; int clip1, reservedAmmo; clip1 = weapon.Value.Clip1; reservedAmmo = weapon.Value.ReserveAmmo[0]; - string weaponByDefindex = weaponDefindex[weapon.Value.AttributeManager.Item.ItemDefinitionIndex]; + string weaponByDefindex = WeaponDefindex[weapon.Value.AttributeManager.Item.ItemDefinitionIndex]; player.RemoveItemByDesignerName(weapon.Value.DesignerName, true); CBasePlayerWeapon newWeapon = new(player.GiveNamedItem(weaponByDefindex)); @@ -246,7 +244,7 @@ namespace WeaponPaints } /* - if (Config.Additional.SkinVisibilityFix) + if (Config.AdditionalSetting.SkinVisibilityFix) RefreshSkins(player); */ } @@ -321,13 +319,6 @@ namespace WeaponPaints } return 0; } - - private static CSkeletonInstance GetSkeletonInstance(CGameSceneNode node) - { - Func GetSkeletonInstance = VirtualFunction.Create(node.Handle, 8); - return new CSkeletonInstance(GetSkeletonInstance(node.Handle)); - } - private static unsafe CHandle[]? GetPlayerViewModels(CCSPlayerController player) { if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null; @@ -348,6 +339,5 @@ namespace WeaponPaints return values; } - } } \ No newline at end of file diff --git a/WeaponInfo.cs b/WeaponInfo.cs index dc702bbf..be1f52c8 100644 --- a/WeaponInfo.cs +++ b/WeaponInfo.cs @@ -2,8 +2,12 @@ { public class WeaponInfo { - public int Paint { get; set; } - public int Seed { get; set; } + public ushort Paint { get; set; } + public ushort Seed { get; set; } public float Wear { get; set; } - } + public string? NameTag { get; set; } + public ushort Quality { get; set; } + public uint StatTrack { get; set; } + public bool StatTrackEnabled { get; set; } + } } \ No newline at end of file diff --git a/WeaponPaints.cs b/WeaponPaints.cs index 7cb447de..dbfc6232 100644 --- a/WeaponPaints.cs +++ b/WeaponPaints.cs @@ -9,7 +9,7 @@ using System.Collections.Concurrent; namespace WeaponPaints; -[MinimumApiVersion(144)] +[MinimumApiVersion(155)] public partial class WeaponPaints : BasePlugin, IPluginConfig { internal static readonly Dictionary weaponList = new() @@ -69,12 +69,70 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig WeaponDefindex { get; } = new Dictionary + { + { 1, "weapon_deagle" }, + { 2, "weapon_elite" }, + { 3, "weapon_fiveseven" }, + { 4, "weapon_glock" }, + { 7, "weapon_ak47" }, + { 8, "weapon_aug" }, + { 9, "weapon_awp" }, + { 10, "weapon_famas" }, + { 11, "weapon_g3sg1" }, + { 13, "weapon_galilar" }, + { 14, "weapon_m249" }, + { 16, "weapon_m4a1" }, + { 17, "weapon_mac10" }, + { 19, "weapon_p90" }, + { 23, "weapon_mp5sd" }, + { 24, "weapon_ump45" }, + { 25, "weapon_xm1014" }, + { 26, "weapon_bizon" }, + { 27, "weapon_mag7" }, + { 28, "weapon_negev" }, + { 29, "weapon_sawedoff" }, + { 30, "weapon_tec9" }, + { 32, "weapon_hkp2000" }, + { 33, "weapon_mp7" }, + { 34, "weapon_mp9" }, + { 35, "weapon_nova" }, + { 36, "weapon_p250" }, + { 38, "weapon_scar20" }, + { 39, "weapon_sg556" }, + { 40, "weapon_ssg08" }, + { 60, "weapon_m4a1_silencer" }, + { 61, "weapon_usp_silencer" }, + { 63, "weapon_cz75a" }, + { 64, "weapon_revolver" }, + { 500, "weapon_bayonet" }, + { 503, "weapon_knife_css" }, + { 505, "weapon_knife_flip" }, + { 506, "weapon_knife_gut" }, + { 507, "weapon_knife_karambit" }, + { 508, "weapon_knife_m9_bayonet" }, + { 509, "weapon_knife_tactical" }, + { 512, "weapon_knife_falchion" }, + { 514, "weapon_knife_survival_bowie" }, + { 515, "weapon_knife_butterfly" }, + { 516, "weapon_knife_push" }, + { 517, "weapon_knife_cord" }, + { 518, "weapon_knife_canis" }, + { 519, "weapon_knife_ursus" }, + { 520, "weapon_knife_gypsy_jackknife" }, + { 521, "weapon_knife_outdoor" }, + { 522, "weapon_knife_stiletto" }, + { 523, "weapon_knife_widowmaker" }, + { 525, "weapon_knife_skeleton" } + }; - internal static WeaponPaintsConfig _config = new WeaponPaintsConfig(); + internal static WeaponPaintsConfig _config = new WeaponPaintsConfig(); internal static IStringLocalizer? _localizer; internal static Dictionary g_knifePickupCount = new Dictionary(); - internal static ConcurrentDictionary g_playersKnife = new ConcurrentDictionary(); - internal static ConcurrentDictionary> gPlayerWeaponsInfo = new ConcurrentDictionary>(); + internal static ConcurrentDictionary g_playersDatabaseIndex = new ConcurrentDictionary(); + internal static ConcurrentDictionary g_playersKnife = new ConcurrentDictionary(); + internal static ConcurrentDictionary g_playersMusicKit = new ConcurrentDictionary(); + internal static ConcurrentDictionary> gPlayerWeaponsInfo = new ConcurrentDictionary>(); internal static List skinsList = new List(); internal static WeaponSynchronization? weaponSync; internal bool g_bCommandsAllowed = true; @@ -84,68 +142,11 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig commandsCooldown = new Dictionary(); private string DatabaseConnectionString = string.Empty; private CounterStrikeSharp.API.Modules.Timers.Timer? g_hTimerCheckSkinsData = null; - public static Dictionary weaponDefindex { get; } = new Dictionary - { - { 1, "weapon_deagle" }, - { 2, "weapon_elite" }, - { 3, "weapon_fiveseven" }, - { 4, "weapon_glock" }, - { 7, "weapon_ak47" }, - { 8, "weapon_aug" }, - { 9, "weapon_awp" }, - { 10, "weapon_famas" }, - { 11, "weapon_g3sg1" }, - { 13, "weapon_galilar" }, - { 14, "weapon_m249" }, - { 16, "weapon_m4a1" }, - { 17, "weapon_mac10" }, - { 19, "weapon_p90" }, - { 23, "weapon_mp5sd" }, - { 24, "weapon_ump45" }, - { 25, "weapon_xm1014" }, - { 26, "weapon_bizon" }, - { 27, "weapon_mag7" }, - { 28, "weapon_negev" }, - { 29, "weapon_sawedoff" }, - { 30, "weapon_tec9" }, - { 32, "weapon_hkp2000" }, - { 33, "weapon_mp7" }, - { 34, "weapon_mp9" }, - { 35, "weapon_nova" }, - { 36, "weapon_p250" }, - { 38, "weapon_scar20" }, - { 39, "weapon_sg556" }, - { 40, "weapon_ssg08" }, - { 60, "weapon_m4a1_silencer" }, - { 61, "weapon_usp_silencer" }, - { 63, "weapon_cz75a" }, - { 64, "weapon_revolver" }, - { 500, "weapon_bayonet" }, - { 503, "weapon_knife_css" }, - { 505, "weapon_knife_flip" }, - { 506, "weapon_knife_gut" }, - { 507, "weapon_knife_karambit" }, - { 508, "weapon_knife_m9_bayonet" }, - { 509, "weapon_knife_tactical" }, - { 512, "weapon_knife_falchion" }, - { 514, "weapon_knife_survival_bowie" }, - { 515, "weapon_knife_butterfly" }, - { 516, "weapon_knife_push" }, - { 517, "weapon_knife_cord" }, - { 518, "weapon_knife_canis" }, - { 519, "weapon_knife_ursus" }, - { 520, "weapon_knife_gypsy_jackknife" }, - { 521, "weapon_knife_outdoor" }, - { 522, "weapon_knife_stiletto" }, - { 523, "weapon_knife_widowmaker" }, - { 525, "weapon_knife_skeleton" } - }; - - public WeaponPaintsConfig Config { get; set; } = new(); + public WeaponPaintsConfig Config { get; set; } = new(); public override string ModuleAuthor => "Nereziel & daffyy"; public override string ModuleDescription => "Skin and knife selector, standalone and web-based"; public override string ModuleName => "WeaponPaints"; - public override string ModuleVersion => "1.4b"; + public override string ModuleVersion => "1.5.0"; public static WeaponPaintsConfig GetWeaponPaintsConfig() { @@ -169,23 +170,21 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig await Utility.CheckVersion(ModuleVersion, Logger)); } diff --git a/WeaponSynchronization.cs b/WeaponSynchronization.cs index 4e712cba..d4eb9c35 100644 --- a/WeaponSynchronization.cs +++ b/WeaponSynchronization.cs @@ -1,4 +1,6 @@ -using Dapper; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Entities; +using Dapper; using MySqlConnector; using Newtonsoft.Json.Linq; using System.Collections.Concurrent; @@ -19,21 +21,64 @@ namespace WeaponPaints _globalShareApi = globalShareApi; _globalShareServerId = globalShareServerId; } - - internal async Task GetKnifeFromDatabase(PlayerInfo player) + internal async Task GetPlayerDatabaseIndex(PlayerInfo player) { - if (!_config.Additional.KnifeEnabled) return; + if (player.SteamId == null || player.Index == 0) return; + + try + { + using (var connection = new MySqlConnection(_databaseConnectionString)) + { + await connection.OpenAsync(); + + string query = "SELECT `id` FROM `wp_users` WHERE `steamid` = @steamid"; + int? databaseIndex = await connection.QueryFirstOrDefaultAsync(query, new { steamid = player.SteamId }); + if (databaseIndex != null) + { + WeaponPaints.g_playersDatabaseIndex[player.Index] = (int)databaseIndex; + } + else + { + string insertQuery = "INSERT INTO `wp_users` (`steamid`) VALUES (@steamid)"; + await connection.ExecuteAsync(insertQuery, new { steamid = player.SteamId }); + Console.WriteLine("SQL Insert Query: " + insertQuery); + databaseIndex = await connection.QueryFirstOrDefaultAsync(query, new { steamid = player.SteamId }); + WeaponPaints.g_playersDatabaseIndex[(int)player.Index] = (int)databaseIndex; + } + await connection.CloseAsync(); + + if (databaseIndex != null) + { + if (_config.AdditionalSetting.SkinEnabled) + await GetWeaponPaintsFromDatabase(player); + if (_config.AdditionalSetting.KnifeEnabled) + await GetKnifeFromDatabase(player); + if (_config.AdditionalSetting.MusicKitEnabled) + await GetMusicKitFromDatabase(player); + } + } + + } + catch (Exception e) + { + Utility.Log("GetPlayerDatabaseIndex: " + e.Message); + return; + } + } + internal async Task GetKnifeFromDatabase(PlayerInfo player) + { + if (!_config.AdditionalSetting.KnifeEnabled) return; if (player.SteamId == null || player.Index == 0) return; try { if (_config.GlobalShare) { var values = new Dictionary - { - { "server_id", _globalShareServerId.ToString() }, - { "steamid", player.SteamId }, - { "knife", "1" } - }; + { + { "server_id", _globalShareServerId.ToString() }, + { "steamid", player.SteamId.ToString()! }, + { "knife", "1" } + }; UriBuilder builder = new UriBuilder(_globalShareApi); builder.Query = string.Join("&", values.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}")); @@ -64,13 +109,17 @@ namespace WeaponPaints return; } - using (var connection = new MySqlConnection(_databaseConnectionString)) + if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _)) + { + return; + } + + using (var connection = new MySqlConnection(_databaseConnectionString)) { await connection.OpenAsync(); - string query = "SELECT `knife` FROM `wp_player_knife` WHERE `steamid` = @steamid"; - string? PlayerKnife = await connection.QueryFirstOrDefaultAsync(query, new { steamid = player.SteamId }); - - if (PlayerKnife != null) + string query = "SELECT `knife` FROM `wp_users_knife` WHERE `user_id` = @userId"; + string? PlayerKnife = await connection.QueryFirstOrDefaultAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] }); + if (PlayerKnife != null) { WeaponPaints.g_playersKnife[player.Index] = PlayerKnife; } @@ -83,30 +132,63 @@ namespace WeaponPaints } catch (Exception e) { - Utility.Log(e.Message); + Utility.Log("GetKnifeFromDatabase: " + e.Message); return; } } + internal async Task GetMusicKitFromDatabase(PlayerInfo player) + { + if (!_config.AdditionalSetting.MusicKitEnabled) return; + if (player.SteamId == null || player.Index == 0) return; + if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _)) + { + return; + } + try + { + using (var connection = new MySqlConnection(_databaseConnectionString)) + { + await connection.OpenAsync(); + string query = "SELECT `music` FROM `wp_users_music` WHERE `user_id` = @userId"; + int? PlayerMusitKit = await connection.QueryFirstOrDefaultAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] }); + if (PlayerMusitKit != null) + { + WeaponPaints.g_playersMusicKit[player.Index] = PlayerMusitKit; + } + else + { + return; + } + await connection.CloseAsync(); + } + } + catch (Exception e) + { + Utility.Log("GetMusicKitFromDatabase: " + e.Message); + return; + } + } - internal async Task GetWeaponPaintsFromDatabase(PlayerInfo player) + internal async Task GetWeaponPaintsFromDatabase(PlayerInfo player) { - if (!_config.Additional.SkinEnabled) return; + if (!_config.AdditionalSetting.SkinEnabled) return; if (player.SteamId == null || player.Index == 0) return; - if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out _)) - { - WeaponPaints.gPlayerWeaponsInfo[player.Index] = new ConcurrentDictionary(); - } - try + if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out _)) + { + WeaponPaints.gPlayerWeaponsInfo[player.Index] = new ConcurrentDictionary(); + } + + try { if (_config.GlobalShare) { var values = new Dictionary - { - { "server_id", _globalShareServerId.ToString() }, - { "steamid", player.SteamId }, - { "skins", "1" } - }; + { + { "server_id", _globalShareServerId.ToString() }, + { "steamid", player.SteamId.ToString()! }, + { "skins", "1" } + }; UriBuilder builder = new UriBuilder(_globalShareApi); builder.Query = string.Join("&", values.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}")); @@ -124,19 +206,20 @@ namespace WeaponPaints { foreach (var weapon in jsonArray) { - int? weaponDefIndex = weapon["weapon_defindex"]?.Value(); - int? weaponPaintId = weapon["weapon_paint_id"]?.Value(); + ushort? weaponDefIndex = weapon["weapon_defindex"]?.Value(); + ushort? weaponPaintId = weapon["weapon_paint_id"]?.Value(); float? weaponWear = weapon["weapon_wear"]?.Value(); - int? weaponSeed = weapon["weapon_seed"]?.Value(); + ushort? weaponSeed = weapon["weapon_seed"]?.Value(); - if (weaponDefIndex != null && weaponPaintId != null && weaponWear != null && weaponSeed != null) + if (weaponDefIndex != null && weaponPaintId != null && weaponWear != null && weaponSeed != null) { WeaponInfo weaponInfo = new WeaponInfo { Paint = weaponPaintId.Value, Seed = weaponSeed.Value, - Wear = weaponWear.Value - }; + Wear = weaponWear.Value, + NameTag = null + }; WeaponPaints.gPlayerWeaponsInfo[player.Index][weaponDefIndex.Value] = weaponInfo; } } @@ -150,28 +233,33 @@ namespace WeaponPaints } } - using (var connection = new MySqlConnection(_databaseConnectionString)) + if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _)) + { + return; + } + + using (var connection = new MySqlConnection(_databaseConnectionString)) { await connection.OpenAsync(); - - string query = "SELECT * FROM `wp_player_skins` WHERE `steamid` = @steamid"; - IEnumerable PlayerSkins = await connection.QueryAsync(query, new { steamid = player.SteamId }); - - if (PlayerSkins != null && PlayerSkins.AsList().Count > 0) + string query = "SELECT `weapon`, `paint`, `wear`, `seed`, `nametag` FROM `wp_users_items` WHERE `user_id` = @userId"; + IEnumerable PlayerSkins = await connection.QueryAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] }); + if (PlayerSkins != null && PlayerSkins.Any()) { - PlayerSkins.ToList().ForEach(row => + PlayerSkins.ToList().ForEach(row => { - int weaponDefIndex = row.weapon_defindex ?? default(int); - int weaponPaintId = row.weapon_paint_id ?? default(int); - float weaponWear = row.weapon_wear ?? default(float); - int weaponSeed = row.weapon_seed ?? default(int); + ushort weaponDefIndex = row.weapon ?? default(ushort); + ushort weaponPaintId = row.paint ?? default(ushort); + float weaponWear = row.wear ?? default(float); + ushort weaponSeed = row.seed ?? default(ushort); + string weaponNameTag = row.nametag; - WeaponInfo weaponInfo = new WeaponInfo + WeaponInfo weaponInfo = new WeaponInfo { Paint = weaponPaintId, Seed = weaponSeed, - Wear = weaponWear - }; + Wear = weaponWear, + NameTag = weaponNameTag + }; WeaponPaints.gPlayerWeaponsInfo[player.Index][weaponDefIndex] = weaponInfo; }); } @@ -184,22 +272,24 @@ namespace WeaponPaints } catch (Exception e) { - Utility.Log(e.Message); + Utility.Log("GetWeaponPaintsFromDatabase: " + e.Message); return; } } internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife) { - if (!_config.Additional.KnifeEnabled) return; - try + if (!_config.AdditionalSetting.KnifeEnabled) return; + if(player == null || player.Index <= 0) return; + try { - if (player.SteamId == null || player.Index == 0) return; + if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _)) + return; - using var connection = new MySqlConnection(_databaseConnectionString); + using var connection = new MySqlConnection(_databaseConnectionString); await connection.OpenAsync(); - string query = "INSERT INTO `wp_player_knife` (`steamid`, `knife`) VALUES(@steamid, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife"; - await connection.ExecuteAsync(query, new { steamid = player.SteamId, newKnife = knife }); + string query = "INSERT INTO `wp_users_knife` (`user_id`, `knife`) VALUES(@userId, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife"; + await connection.ExecuteAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index], newKnife = knife }); await connection.CloseAsync(); } catch (Exception e) @@ -208,42 +298,34 @@ namespace WeaponPaints return; } } - internal async Task SyncWeaponPaintsToDatabase(PlayerInfo player) + internal async Task SyncWeaponPaintToDatabase(PlayerInfo player, ushort weaponDefIndex) { - if (player == null || player.Index <= 0 || player.SteamId == null) return; + if (!_config.AdditionalSetting.SkinEnabled) return; + if (player == null || player.Index <= 0) return; - using var connection = new MySqlConnection(_databaseConnectionString); - await connection.OpenAsync(); + if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out var playerDatabaseIndex)) + return; + + if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out var playerSavedWeapons)) + return; + + if (!playerSavedWeapons.TryGetValue(weaponDefIndex, out var weaponInfo)) + return; - if (!WeaponPaints.gPlayerWeaponsInfo.ContainsKey(player.Index)) - return; - - foreach (var weaponInfoPair in WeaponPaints.gPlayerWeaponsInfo[player.Index]) - { - int weaponDefIndex = weaponInfoPair.Key; - WeaponInfo weaponInfo = weaponInfoPair.Value; - - int paintId = weaponInfo.Paint; - float wear = weaponInfo.Wear; - int seed = weaponInfo.Seed; - - string updateSql = "UPDATE `wp_player_skins` SET `weapon_paint_id` = @paintId, " + - "`weapon_wear` = @wear, `weapon_seed` = @seed WHERE `steamid` = @steamid " + - "AND `weapon_defindex` = @weaponDefIndex"; - - var updateParams = new { paintId, wear, seed, steamid = player.SteamId, weaponDefIndex }; - int rowsAffected = await connection.ExecuteAsync(updateSql, updateParams); - - if (rowsAffected == 0) - { - string insertSql = "INSERT INTO `wp_player_skins` (`steamid`, `weapon_defindex`, " + - "`weapon_paint_id`, `weapon_wear`, `weapon_seed`) " + - "VALUES (@steamid, @weaponDefIndex, @paintId, @wear, @seed)"; - - await connection.ExecuteAsync(insertSql, updateParams); - } - } - await connection.CloseAsync(); + using var connection = new MySqlConnection(_databaseConnectionString); + string querySql = @" + INSERT INTO `wp_users_items` + (`user_id`, `weapon`, `paint`, `wear`, `seed`) + VALUES + (@userId, @weaponDefIndex, @paintId, @wear, @seed) + ON DUPLICATE KEY UPDATE + paint = @paintId, + wear = @wear, + seed = @seed"; + var queryParams = new { weaponDefIndex, userId = playerDatabaseIndex, paintId = weaponInfo.Paint, wear = weaponInfo.Wear, seed = weaponInfo.Seed }; + await connection.ExecuteAsync(querySql, queryParams); + await connection.CloseAsync(); + } } } \ No newline at end of file