Compare commits

...

14 Commits

Author SHA1 Message Date
Dawid Bepierszcz
c594cd534e Merge pull request #237 from daffyyyy/main
2.4b
2024-04-08 21:31:43 +02:00
Dawid Bepierszcz
5aaf0e6f62 Merge branch 'Nereziel:main' into main 2024-04-08 21:30:46 +02:00
Dawid Bepierszcz
942e776688 2.4b
- Nothing big ;P
2024-04-08 21:30:22 +02:00
Dawid Bepierszcz
36046fee2d Merge pull request #231 from daffyyyy/main
2.4a
2024-04-03 01:35:07 +02:00
Dawid Bepierszcz
d6de0ce6c8 Merge branch 'Nereziel:main' into main 2024-04-03 01:33:52 +02:00
Dawid Bepierszcz
d2c19d8af8 Merge branch 'main' of https://github.com/daffyyyy/cs2-WeaponPaints 2024-04-03 01:32:27 +02:00
Dawid Bepierszcz
0f6d334621 2.4a
- .NET8
- Mysql queries optimization
- CounterStrikeSharp updated
2024-04-03 01:32:24 +02:00
Dawid Bepierszcz
f99c9b2767 Merge pull request #226 from daffyyyy/main
2.3c
2024-03-27 23:20:43 +01:00
Dawid Bepierszcz
6a2d28c303 Merge branch 'Nereziel:main' into main 2024-03-27 23:19:42 +01:00
Dawid Bepierszcz
27a2ae5be9 Merge branch 'main' of https://github.com/daffyyyy/cs2-WeaponPaints 2024-03-27 23:19:26 +01:00
Dawid Bepierszcz
0af9177f07 2.3c
- Small change for mysql performance
2024-03-27 23:19:24 +01:00
Dawid Bepierszcz
cfb49e1498 Merge pull request #222 from daffyyyy/main
2.3b
2024-03-21 01:13:14 +01:00
Dawid Bepierszcz
bbdb4b82ce Merge branch 'Nereziel:main' into main 2024-03-21 01:12:08 +01:00
Dawid Bepierszcz
bfb7defcaa 2.3b
- Fixed agent team bug
- Minor changes
2024-03-21 01:09:45 +01:00
10 changed files with 215 additions and 202 deletions

View File

@@ -33,6 +33,8 @@ namespace WeaponPaints
if (weaponSync != null)
{
_ = Task.Run(async () => await weaponSync.GetPlayerData(playerInfo));
/*
if (Config.Additional.SkinEnabled)
{
_ = Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
@@ -53,6 +55,7 @@ namespace WeaponPaints
{
_ = Task.Run(async () => await weaponSync.GetMusicFromDatabase(playerInfo));
}
*/
RefreshGloves(player);
RefreshWeapons(player);
@@ -471,60 +474,62 @@ namespace WeaponPaints
if (!Utility.IsPlayerValid(player) || player is null) return;
string selectedPaintName = option.Text;
var selectedAgent = agentsList.FirstOrDefault(g =>
g.ContainsKey("agent_name") &&
g["agent_name"] != null && g["agent_name"]!.ToString() == selectedPaintName &&
g["team"] != null && (int)(g["team"]!) == player.TeamNum);
var selectedAgent = agentsList.FirstOrDefault(g => g.ContainsKey("agent_name") && g["agent_name"]?.ToString() == selectedPaintName);
if (selectedAgent != null)
if (selectedAgent == null) return;
if (
selectedAgent != null &&
selectedAgent.ContainsKey("model")
)
{
if (
selectedAgent != null &&
selectedAgent.ContainsKey("model")
)
PlayerInfo playerInfo = new PlayerInfo
{
PlayerInfo playerInfo = new PlayerInfo
{
UserId = player.UserId,
Slot = player.Slot,
Index = (int)player.Index,
SteamId = player.SteamID.ToString(),
Name = player.PlayerName,
IpAddress = player.IpAddress?.Split(":")[0]
};
if (Config.Additional.ShowSkinImage)
{
string image = selectedAgent["image"]?.ToString() ?? "";
PlayerWeaponImage[player.Slot] = image;
AddTimer(2.0f, () => PlayerWeaponImage.Remove(player.Slot), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
if (!string.IsNullOrEmpty(Localizer["wp_agent_menu_select"]))
{
player!.Print(Localizer["wp_agent_menu_select", selectedPaintName]);
}
if (player.TeamNum == 3)
{
g_playersAgent.AddOrUpdate(player.Slot,
key => (selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString(), null),
(key, oldValue) => (selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString(), oldValue.T));
}
else
{
g_playersAgent.AddOrUpdate(player.Slot,
key => (null, selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString()),
(key, oldValue) => (oldValue.CT, selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString())
);
}
if (weaponSync != null)
{
_ = Task.Run(async () =>
{
await weaponSync.SyncAgentToDatabase(playerInfo);
});
}
UserId = player.UserId,
Slot = player.Slot,
Index = (int)player.Index,
SteamId = player.SteamID.ToString(),
Name = player.PlayerName,
IpAddress = player.IpAddress?.Split(":")[0]
};
}
if (Config.Additional.ShowSkinImage)
{
string image = selectedAgent["image"]?.ToString() ?? "";
PlayerWeaponImage[player.Slot] = image;
AddTimer(2.0f, () => PlayerWeaponImage.Remove(player.Slot), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
if (!string.IsNullOrEmpty(Localizer["wp_agent_menu_select"]))
{
player!.Print(Localizer["wp_agent_menu_select", selectedPaintName]);
}
if (player.TeamNum == 3)
{
g_playersAgent.AddOrUpdate(player.Slot,
key => (selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString(), null),
(key, oldValue) => (selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString(), oldValue.T));
}
else
{
g_playersAgent.AddOrUpdate(player.Slot,
key => (null, selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString()),
(key, oldValue) => (oldValue.CT, selectedAgent["model"]!.ToString().Equals("null") ? null : selectedAgent["model"]!.ToString())
);
}
if (weaponSync != null)
{
_ = Task.Run(async () =>
{
await weaponSync.SyncAgentToDatabase(playerInfo);
});
}
};
};
// Command to open the weapon selection menu for players

View File

@@ -1,15 +1,11 @@
using MySqlConnector;
using Microsoft.Extensions.Logging;
using MySqlConnector;
namespace WeaponPaints
{
public class Database
public class Database(string dbConnectionString)
{
private readonly string _dbConnectionString;
public Database(string dbConnectionString)
{
_dbConnectionString = dbConnectionString;
}
private readonly string _dbConnectionString = dbConnectionString;
public async Task<MySqlConnection> GetConnectionAsync()
{
@@ -19,8 +15,9 @@ namespace WeaponPaints
await connection.OpenAsync();
return connection;
}
catch (Exception)
catch (Exception ex)
{
WeaponPaints.Instance.Logger.LogError($"Unable to connect to database: {ex.Message}");
throw;
}
}

View File

@@ -2,6 +2,8 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
namespace WeaponPaints
{
@@ -27,6 +29,8 @@ namespace WeaponPaints
try
{
_ = Task.Run(async () => await weaponSync.GetPlayerData(playerInfo));
/*
if (Config.Additional.SkinEnabled)
{
_ = Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
@@ -47,6 +51,7 @@ namespace WeaponPaints
{
_ = Task.Run(async () => await weaponSync.GetMusicFromDatabase(playerInfo));
}
*/
}
catch (Exception)
{
@@ -102,8 +107,7 @@ namespace WeaponPaints
private void GivePlayerWeaponSkin(CCSPlayerController player, CBasePlayerWeapon weapon)
{
if (!Config.Additional.SkinEnabled) return;
if (player is null || weapon is null || !weapon.IsValid || !Utility.IsPlayerValid(player)) return;
if (!gPlayerWeaponsInfo.ContainsKey(player.Slot)) return;
if (!gPlayerWeaponsInfo.TryGetValue(player.Slot, out System.Collections.Concurrent.ConcurrentDictionary<int, WeaponInfo>? _value)) return;
bool isKnife = weapon.DesignerName.Contains("knife") || weapon.DesignerName.Contains("bayonet");
@@ -160,9 +164,9 @@ namespace WeaponPaints
return;
}
if (!gPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex) || gPlayerWeaponsInfo[player.Slot][weaponDefIndex].Paint == 0) return;
if (!gPlayerWeaponsInfo[player.Slot].TryGetValue(weaponDefIndex, out WeaponInfo? value) || value.Paint == 0) return;
WeaponInfo weaponInfo = gPlayerWeaponsInfo[player.Slot][weaponDefIndex];
WeaponInfo weaponInfo = value;
//Log($"Apply on {weapon.DesignerName}({weapon.AttributeManager.Item.ItemDefinitionIndex}) paint {gPlayerWeaponPaints[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} seed {gPlayerWeaponSeed[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} wear {gPlayerWeaponWear[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]}");
weapon.AttributeManager.Item.ItemID = 16384;
weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF;
@@ -214,6 +218,7 @@ namespace WeaponPaints
GivePlayerMusicKit(player);
GivePlayerAgent(player);
Server.NextFrame(() =>
{
RefreshGloves(player);
@@ -241,21 +246,25 @@ namespace WeaponPaints
return HookResult.Continue;
}
/*
public HookResult OnGiveNamedItemPost(DynamicHook hook)
{
var itemServices = hook.GetParam<CCSPlayer_ItemServices>(0);
var weapon = hook.GetReturn<CBasePlayerWeapon>(0);
if (!weapon.DesignerName.Contains("weapon"))
return HookResult.Continue;
try
{
var itemServices = hook.GetParam<CCSPlayer_ItemServices>(0);
var weapon = hook.GetReturn<CBasePlayerWeapon>();
if (!weapon.DesignerName.Contains("weapon"))
return HookResult.Continue;
var player = GetPlayerFromItemServices(itemServices);
if (player != null)
GivePlayerWeaponSkin(player, weapon);
var player = GetPlayerFromItemServices(itemServices);
if (player != null)
GivePlayerWeaponSkin(player, weapon);
}
catch { }
return HookResult.Continue;
}
*/
public void OnEntityCreated(CEntityInstance entity)
{
@@ -266,7 +275,7 @@ namespace WeaponPaints
Server.NextFrame(() =>
{
var weapon = new CBasePlayerWeapon(entity.Handle);
if (weapon == null || !weapon.IsValid || weapon.OwnerEntity.Value == null) return;
if (weapon == null || !weapon.IsValid) return;
try
{
@@ -305,6 +314,8 @@ namespace WeaponPaints
private void OnTick()
{
if (!Config.Additional.ShowSkinImage) return;
foreach (var player in Utilities.GetPlayers().Where(p =>
p is not null && p.IsValid && p.PlayerPawn != null && p.PlayerPawn.IsValid &&
(LifeState_t)p.LifeState == LifeState_t.LIFE_ALIVE && p.SteamID.ToString().Length == 17
@@ -312,7 +323,7 @@ namespace WeaponPaints
)
)
{
if (Config.Additional.ShowSkinImage && PlayerWeaponImage.TryGetValue(player.Slot, out string? value) && !string.IsNullOrEmpty(value))
if (PlayerWeaponImage.TryGetValue(player.Slot, out string? value) && !string.IsNullOrEmpty(value))
{
player.PrintToCenterHtml("<img src='{PATH}'</img>".Replace("{PATH}", value));
}
@@ -324,11 +335,14 @@ namespace WeaponPaints
RegisterListener<Listeners.OnMapStart>(OnMapStart);
RegisterEventHandler<EventPlayerSpawn>(OnPlayerSpawn);
RegisterEventHandler<EventRoundStart>(OnRoundStart, HookMode.Pre);
RegisterEventHandler<EventRoundStart>(OnRoundStart);
RegisterEventHandler<EventRoundEnd>(OnRoundEnd);
RegisterListener<Listeners.OnEntityCreated>(OnEntityCreated);
RegisterListener<Listeners.OnTick>(OnTick);
//VirtualFunctions.GiveNamedItemFunc.Hook(OnGiveNamedItemPost, HookMode.Post);
if (Config.Additional.ShowSkinImage)
RegisterListener<Listeners.OnTick>(OnTick);
VirtualFunctions.GiveNamedItemFunc.Hook(OnGiveNamedItemPost, HookMode.Post);
}
}
}

View File

@@ -8,6 +8,7 @@ public static class PlayerExtensions
public static void Print(this CCSPlayerController controller, string message)
{
if (WeaponPaints._localizer == null) return;
StringBuilder _message = new(WeaponPaints._localizer["wp_prefix"]);
_message.Append(message);
controller.PrintToChat(_message.ToString());

View File

@@ -1,11 +1,9 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using CounterStrikeSharp.API.Core.Translations;
using Dapper;
using Microsoft.Extensions.Logging;
using MySqlConnector;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Reflection;
namespace WeaponPaints
{
@@ -13,22 +11,6 @@ namespace WeaponPaints
{
internal static WeaponPaintsConfig? Config { get; set; }
internal static string BuildDatabaseConnectionString()
{
if (Config == null) return string.Empty;
var builder = new MySqlConnectionStringBuilder
{
Server = Config.DatabaseHost,
UserID = Config.DatabaseUser,
Password = Config.DatabasePassword,
Database = Config.DatabaseName,
Port = (uint)Config.DatabasePort,
Pooling = true
};
return builder.ConnectionString;
}
internal static async Task CheckDatabaseTables()
{
if (WeaponPaints._database is null) return;
@@ -41,8 +23,8 @@ namespace WeaponPaints
try
{
string[] createTableQueries = new[]
{
string[] createTableQueries =
[
@"CREATE TABLE IF NOT EXISTS `wp_player_skins` (
`steamid` varchar(18) NOT NULL,
`weapon_defindex` int(6) NOT NULL,
@@ -50,28 +32,28 @@ namespace WeaponPaints
`weapon_wear` float NOT NULL DEFAULT 0.000001,
`weapon_seed` int(16) NOT NULL DEFAULT 0
) ENGINE=InnoDB",
@"CREATE TABLE IF NOT EXISTS `wp_player_knife` (
@"CREATE TABLE IF NOT EXISTS `wp_player_knife` (
`steamid` varchar(18) NOT NULL,
`knife` varchar(64) NOT NULL,
UNIQUE (`steamid`)
) ENGINE = InnoDB",
@"CREATE TABLE IF NOT EXISTS `wp_player_gloves` (
@"CREATE TABLE IF NOT EXISTS `wp_player_gloves` (
`steamid` varchar(18) NOT NULL,
`weapon_defindex` int(11) NOT NULL,
UNIQUE (`steamid`)
) ENGINE=InnoDB",
@"CREATE TABLE IF NOT EXISTS `wp_player_agents` (
@"CREATE TABLE IF NOT EXISTS `wp_player_agents` (
`steamid` varchar(18) NOT NULL,
`agent_ct` varchar(64) DEFAULT NULL,
`agent_t` varchar(64) DEFAULT NULL,
UNIQUE (`steamid`)
) ENGINE=InnoDB",
@"CREATE TABLE IF NOT EXISTS `wp_player_music` (
@"CREATE TABLE IF NOT EXISTS `wp_player_music` (
`steamid` varchar(64) NOT NULL,
`music_id` int(11) NOT NULL,
UNIQUE (`steamid`)
) ENGINE=InnoDB",
};
];
foreach (var query in createTableQueries)
{
@@ -99,7 +81,7 @@ namespace WeaponPaints
return (player.IsValid && !player.IsBot && !player.IsHLTV && player.UserId.HasValue);
}
internal static void LoadSkinsFromFile(string filePath)
internal static void LoadSkinsFromFile(string filePath, ILogger logger)
{
try
{
@@ -109,11 +91,11 @@ namespace WeaponPaints
}
catch (FileNotFoundException)
{
throw;
logger?.LogError("Not found \"skins.json\" file");
}
}
internal static void LoadGlovesFromFile(string filePath)
internal static void LoadGlovesFromFile(string filePath, ILogger logger)
{
try
{
@@ -123,11 +105,11 @@ namespace WeaponPaints
}
catch (FileNotFoundException)
{
throw;
logger?.LogError("Not found \"gloves.json\" file");
}
}
internal static void LoadAgentsFromFile(string filePath)
internal static void LoadAgentsFromFile(string filePath, ILogger logger)
{
try
{
@@ -137,11 +119,11 @@ namespace WeaponPaints
}
catch (FileNotFoundException)
{
throw;
logger?.LogError("Not found \"agents.json\" file");
}
}
internal static void LoadMusicFromFile(string filePath)
internal static void LoadMusicFromFile(string filePath, ILogger logger)
{
try
{
@@ -151,7 +133,7 @@ namespace WeaponPaints
}
catch (FileNotFoundException)
{
throw;
logger?.LogError("Not found \"music.json\" file");
}
}
@@ -165,69 +147,50 @@ namespace WeaponPaints
internal static string ReplaceTags(string message)
{
if (message.Contains('{'))
{
string modifiedValue = message;
if (Config != null)
{
modifiedValue = modifiedValue.Replace("{WEBSITE}", Config.Website);
}
foreach (FieldInfo field in typeof(ChatColors).GetFields())
{
string pattern = $"{{{field.Name}}}";
if (message.Contains(pattern, StringComparison.OrdinalIgnoreCase))
{
modifiedValue = modifiedValue.Replace(pattern, field.GetValue(null)!.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
return modifiedValue;
}
return message;
return message.ReplaceColorTags();
}
internal static async Task CheckVersion(string version, ILogger logger)
{
using (HttpClient client = new HttpClient())
using HttpClient client = new();
try
{
try
HttpResponseMessage response = await client.GetAsync("https://raw.githubusercontent.com/Nereziel/cs2-WeaponPaints/main/VERSION").ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
HttpResponseMessage response = await client.GetAsync("https://raw.githubusercontent.com/Nereziel/cs2-WeaponPaints/main/VERSION").ConfigureAwait(false);
string remoteVersion = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
remoteVersion = remoteVersion.Trim();
if (response.IsSuccessStatusCode)
int comparisonResult = string.Compare(version, remoteVersion);
if (comparisonResult < 0)
{
string remoteVersion = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
remoteVersion = remoteVersion.Trim();
int comparisonResult = string.Compare(version, remoteVersion);
if (comparisonResult < 0)
{
logger.LogWarning("Plugin is outdated! Check https://github.com/Nereziel/cs2-WeaponPaints");
}
else if (comparisonResult > 0)
{
logger.LogInformation("Probably dev version detected");
}
else
{
logger.LogInformation("Plugin is up to date");
}
logger.LogWarning("Plugin is outdated! Check https://github.com/Nereziel/cs2-WeaponPaints");
}
else if (comparisonResult > 0)
{
logger.LogInformation("Probably dev version detected");
}
else
{
logger.LogWarning("Failed to check version");
logger.LogInformation("Plugin is up to date");
}
}
catch (HttpRequestException ex)
else
{
logger.LogError(ex, "Failed to connect to the version server.");
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred while checking version.");
logger.LogWarning("Failed to check version");
}
}
catch (HttpRequestException ex)
{
logger.LogError(ex, "Failed to connect to the version server.");
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred while checking version.");
}
}
internal static void ShowAd(string moduleVersion)

View File

@@ -1 +1 @@
2.3a
2.4b

View File

@@ -17,7 +17,7 @@ namespace WeaponPaints
if (PlayerHasKnife(player)) return;
string knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife";
//string knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife";
player.GiveNamedItem(CsItem.Knife);
}
@@ -99,12 +99,13 @@ namespace WeaponPaints
int clip1 = weapon.Value.Clip1;
int reservedAmmo = weapon.Value.ReserveAmmo[0];
if (!weaponsWithAmmo.ContainsKey(weaponByDefindex))
if (!weaponsWithAmmo.TryGetValue(weaponByDefindex, out List<(int, int)>? value))
{
weaponsWithAmmo.Add(weaponByDefindex, new List<(int, int)>());
value = new List<(int, int)>();
weaponsWithAmmo.Add(weaponByDefindex, value);
}
weaponsWithAmmo[weaponByDefindex].Add((clip1, reservedAmmo));
value.Add((clip1, reservedAmmo));
if (gun == null || gun.VData == null) return;

View File

@@ -10,7 +10,7 @@ using System.Collections.Concurrent;
namespace WeaponPaints;
[MinimumApiVersion(191)]
[MinimumApiVersion(201)]
public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig>
{
internal static WeaponPaints Instance { get; private set; } = new();
@@ -75,23 +75,23 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
{ "weapon_knife_kukri", "Kukri Knife" }
};
internal static WeaponPaintsConfig _config = new WeaponPaintsConfig();
internal static WeaponPaintsConfig _config = new();
internal static IStringLocalizer? _localizer;
internal static Dictionary<int, int> g_knifePickupCount = new Dictionary<int, int>();
internal static ConcurrentDictionary<int, string> g_playersKnife = new ConcurrentDictionary<int, string>();
internal static ConcurrentDictionary<int, ushort> g_playersGlove = new ConcurrentDictionary<int, ushort>();
internal static ConcurrentDictionary<int, ushort> g_playersMusic = new ConcurrentDictionary<int, ushort>();
internal static ConcurrentDictionary<int, (string? CT, string? T)> g_playersAgent = new ConcurrentDictionary<int, (string?, string?)>();
internal static ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>> gPlayerWeaponsInfo = new ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>>();
internal static List<JObject> skinsList = new List<JObject>();
internal static List<JObject> glovesList = new List<JObject>();
internal static List<JObject> agentsList = new List<JObject>();
internal static List<JObject> musicList = new List<JObject>();
internal static Dictionary<int, int> g_knifePickupCount = new();
internal static ConcurrentDictionary<int, string> g_playersKnife = new();
internal static ConcurrentDictionary<int, ushort> g_playersGlove = new();
internal static ConcurrentDictionary<int, ushort> g_playersMusic = new();
internal static ConcurrentDictionary<int, (string? CT, string? T)> g_playersAgent = new();
internal static ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>> gPlayerWeaponsInfo = new();
internal static List<JObject> skinsList = new();
internal static List<JObject> glovesList = new();
internal static List<JObject> agentsList = new();
internal static List<JObject> musicList = new();
internal static WeaponSynchronization? weaponSync;
public static bool g_bCommandsAllowed = true;
internal Dictionary<int, string> PlayerWeaponImage = new();
internal static Dictionary<int, DateTime> commandsCooldown = new Dictionary<int, DateTime>();
internal static Dictionary<int, DateTime> commandsCooldown = new();
internal static Database? _database;
internal static MemoryFunctionVoid<nint, string, float> CAttributeList_SetOrAddAttributeValueByName = new(GameData.GetSignature("CAttributeList_SetOrAddAttributeValueByName"));
@@ -160,7 +160,7 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
public override string ModuleAuthor => "Nereziel & daffyy";
public override string ModuleDescription => "Skin, gloves, agents and knife selector, standalone and web-based";
public override string ModuleName => "WeaponPaints";
public override string ModuleVersion => "2.3a";
public override string ModuleVersion => "2.4b";
public static WeaponPaintsConfig GetWeaponPaintsConfig()
{
@@ -177,7 +177,10 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
foreach (var player in Utilities.GetPlayers())
{
if (weaponSync == null || player is null || !player.IsValid || player.SteamID.ToString().Length != 17 || player.IsBot ||
if (weaponSync == null)
break;
if (player is null || !player.IsValid || player.SteamID.ToString().Length != 17 || string.IsNullOrEmpty(player.IpAddress) || player.IsBot ||
player.IsHLTV || player.Connected != PlayerConnectedState.PlayerConnected)
continue;
@@ -197,6 +200,9 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
IpAddress = player?.IpAddress?.Split(":")[0]
};
_ = Task.Run(async () => await weaponSync.GetPlayerData(playerInfo));
/*
if (Config.Additional.SkinEnabled)
{
_ = Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
@@ -217,13 +223,14 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
{
_ = Task.Run(async () => await weaponSync.GetMusicFromDatabase(playerInfo));
}
*/
}
}
Utility.LoadSkinsFromFile(ModuleDirectory + "/skins.json");
Utility.LoadGlovesFromFile(ModuleDirectory + "/gloves.json");
Utility.LoadAgentsFromFile(ModuleDirectory + "/agents.json");
Utility.LoadMusicFromFile(ModuleDirectory + "/music.json");
Utility.LoadSkinsFromFile(ModuleDirectory + "/skins.json", Logger);
Utility.LoadGlovesFromFile(ModuleDirectory + "/gloves.json", Logger);
Utility.LoadAgentsFromFile(ModuleDirectory + "/agents.json", Logger);
Utility.LoadMusicFromFile(ModuleDirectory + "/music.json", Logger);
if (Config.Additional.KnifeEnabled)
SetupKnifeMenu();
@@ -255,7 +262,9 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
Password = config.DatabasePassword,
Database = config.DatabaseName,
Port = (uint)config.DatabasePort,
Pooling = true
Pooling = true,
MaximumPoolSize = 640,
ConnectionReset = false
};
_database = new(builder.ConnectionString);

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@@ -9,9 +9,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.193" />
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.203" />
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="MySqlConnector" Version="2.3.5" />
<PackageReference Include="MySqlConnector" Version="2.3.6" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

View File

@@ -1,4 +1,5 @@
using Dapper;
using MySqlConnector;
using System.Collections.Concurrent;
namespace WeaponPaints
@@ -14,16 +15,39 @@ namespace WeaponPaints
_config = config;
}
internal async Task GetKnifeFromDatabase(PlayerInfo player)
internal async Task GetPlayerData(PlayerInfo player)
{
try
{
await using MySqlConnection connection = await _database.GetConnectionAsync();
if (_config.Additional.KnifeEnabled)
GetKnifeFromDatabase(player, connection);
if (_config.Additional.GloveEnabled)
GetGloveFromDatabase(player, connection);
if (_config.Additional.AgentEnabled)
GetAgentFromDatabase(player, connection);
if (_config.Additional.MusicEnabled)
GetMusicFromDatabase(player, connection);
if (_config.Additional.SkinEnabled)
GetWeaponPaintsFromDatabase(player, connection);
}
catch (Exception ex)
{
// Log the exception or handle it appropriately
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
internal void GetKnifeFromDatabase(PlayerInfo player, MySqlConnection connection)
{
try
{
if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player?.SteamId))
return;
await using var connection = await _database.GetConnectionAsync();
string query = "SELECT `knife` FROM `wp_player_knife` WHERE `steamid` = @steamid";
string? playerKnife = await connection.QueryFirstOrDefaultAsync<string>(query, new { steamid = player.SteamId });
string? playerKnife = connection.QueryFirstOrDefault<string>(query, new { steamid = player.SteamId });
if (!string.IsNullOrEmpty(playerKnife))
{
@@ -36,16 +60,15 @@ namespace WeaponPaints
}
}
internal async Task GetGloveFromDatabase(PlayerInfo player)
internal void GetGloveFromDatabase(PlayerInfo player, MySqlConnection connection)
{
try
{
if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player?.SteamId))
return;
await using var connection = await _database.GetConnectionAsync();
string query = "SELECT `weapon_defindex` FROM `wp_player_gloves` WHERE `steamid` = @steamid";
ushort? gloveData = await connection.QueryFirstOrDefaultAsync<ushort?>(query, new { steamid = player.SteamId });
ushort? gloveData = connection.QueryFirstOrDefault<ushort?>(query, new { steamid = player.SteamId });
if (gloveData != null)
{
@@ -58,16 +81,15 @@ namespace WeaponPaints
}
}
internal async Task GetAgentFromDatabase(PlayerInfo player)
internal void GetAgentFromDatabase(PlayerInfo player, MySqlConnection connection)
{
try
{
if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player?.SteamId))
return;
await using var connection = await _database.GetConnectionAsync();
string query = "SELECT `agent_ct`, `agent_t` FROM `wp_player_agents` WHERE `steamid` = @steamid";
var agentData = await connection.QueryFirstOrDefaultAsync<(string, string)>(query, new { steamid = player.SteamId });
var agentData = connection.QueryFirstOrDefault<(string, string)>(query, new { steamid = player.SteamId });
if (agentData != default)
{
@@ -85,11 +107,11 @@ namespace WeaponPaints
}
catch (Exception ex)
{
Utility.Log($"An error occurred in GetGloveFromDatabase: {ex.Message}");
Utility.Log($"An error occurred in GetAgentFromDatabase: {ex.Message}");
}
}
internal async Task GetWeaponPaintsFromDatabase(PlayerInfo player)
internal void GetWeaponPaintsFromDatabase(PlayerInfo player, MySqlConnection connection)
{
try
{
@@ -98,9 +120,8 @@ namespace WeaponPaints
var weaponInfos = new ConcurrentDictionary<int, WeaponInfo>();
await using var connection = await _database.GetConnectionAsync();
string query = "SELECT * FROM `wp_player_skins` WHERE `steamid` = @steamid";
var playerSkins = await connection.QueryAsync<dynamic>(query, new { steamid = player.SteamId });
var playerSkins = connection.Query<dynamic>(query, new { steamid = player.SteamId });
if (playerSkins == null)
{
@@ -133,16 +154,15 @@ namespace WeaponPaints
}
}
internal async Task GetMusicFromDatabase(PlayerInfo player)
internal void GetMusicFromDatabase(PlayerInfo player, MySqlConnection connection)
{
try
{
if (!_config.Additional.MusicEnabled || string.IsNullOrEmpty(player.SteamId))
return;
await using var connection = await _database.GetConnectionAsync();
string query = "SELECT `music_id` FROM `wp_player_music` WHERE `steamid` = @steamid";
ushort? musicData = await connection.QueryFirstOrDefaultAsync<ushort?>(query, new { steamid = player.SteamId });
ushort? musicData = connection.QueryFirstOrDefault<ushort?>(query, new { steamid = player.SteamId });
if (musicData != null)
{
@@ -155,6 +175,8 @@ namespace WeaponPaints
}
}
internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife)
{
if (!_config.Additional.KnifeEnabled || player == null || string.IsNullOrEmpty(player.SteamId) || string.IsNullOrEmpty(knife)) return;
@@ -233,6 +255,7 @@ namespace WeaponPaints
string query;
object parameters;
if (existingRecordCount > 0)
{
query = "UPDATE `wp_player_skins` SET `weapon_paint_id` = @paintId, `weapon_wear` = @wear, `weapon_seed` = @seed WHERE `steamid` = @steamid AND `weapon_defindex` = @weaponDefIndex";