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
This commit is contained in:
Nereziel
2024-02-03 05:34:10 +01:00
parent 43e7a3183e
commit 56537971ad
10 changed files with 429 additions and 320 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
.vs/ .vs/
bin/ bin/
obj/ obj/
.test/

View File

@@ -8,7 +8,7 @@ namespace WeaponPaints
{ {
private void OnCommandRefresh(CCSPlayerController? player, CommandInfo command) 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 (!Utility.IsPlayerValid(player)) return;
if (player == null || player.Index <= 0) return; if (player == null || player.Index <= 0) return;
int playerIndex = (int)player!.Index; int playerIndex = (int)player!.Index;
@@ -17,7 +17,7 @@ namespace WeaponPaints
{ {
UserId = player.UserId, UserId = player.UserId,
Index = (int)player.Index, Index = (int)player.Index,
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(), SteamId = player?.AuthorizedSteamID?.SteamId64,
Name = player?.PlayerName, Name = player?.PlayerName,
IpAddress = player?.IpAddress?.Split(":")[0] IpAddress = player?.IpAddress?.Split(":")[0]
}; };
@@ -30,7 +30,7 @@ namespace WeaponPaints
commandsCooldown[(int)player.UserId] = DateTime.UtcNow.AddSeconds(Config.CmdRefreshCooldownSeconds); commandsCooldown[(int)player.UserId] = DateTime.UtcNow.AddSeconds(Config.CmdRefreshCooldownSeconds);
if (weaponSync != null) if (weaponSync != null)
Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo)); Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
if (Config.Additional.KnifeEnabled) if (Config.AdditionalSetting.KnifeEnabled)
{ {
if (weaponSync != null) if (weaponSync != null)
Task.Run(async () => await weaponSync.GetKnifeFromDatabase(playerInfo)); Task.Run(async () => await weaponSync.GetKnifeFromDatabase(playerInfo));
@@ -51,7 +51,7 @@ namespace WeaponPaints
private void OnCommandWS(CCSPlayerController? player, CommandInfo command) private void OnCommandWS(CCSPlayerController? player, CommandInfo command)
{ {
if (!Config.Additional.SkinEnabled) return; if (!Config.AdditionalSetting.SkinEnabled) return;
if (!Utility.IsPlayerValid(player)) return; if (!Utility.IsPlayerValid(player)) return;
if (!string.IsNullOrEmpty(Localizer["wp_info_website"])) if (!string.IsNullOrEmpty(Localizer["wp_info_website"]))
@@ -62,7 +62,7 @@ namespace WeaponPaints
{ {
player!.Print(Localizer["wp_info_refresh"]); player!.Print(Localizer["wp_info_refresh"]);
} }
if (!Config.Additional.KnifeEnabled) return; if (!Config.AdditionalSetting.KnifeEnabled) return;
if (!string.IsNullOrEmpty(Localizer["wp_info_knife"])) if (!string.IsNullOrEmpty(Localizer["wp_info_knife"]))
{ {
player!.Print(Localizer["wp_info_knife"]); player!.Print(Localizer["wp_info_knife"]);
@@ -71,19 +71,19 @@ namespace WeaponPaints
private void RegisterCommands() 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; if (!Utility.IsPlayerValid(player)) return;
OnCommandWS(player, info); 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; if (!Utility.IsPlayerValid(player) || !g_bCommandsAllowed) return;
OnCommandRefresh(player, info); 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; if (player == null || !Utility.IsPlayerValid(player) || player.PlayerPawn.Value == null || !player!.PlayerPawn.IsValid) return;
@@ -94,7 +94,7 @@ namespace WeaponPaints
private void SetupKnifeMenu() private void SetupKnifeMenu()
{ {
if (!Config.Additional.KnifeEnabled || !g_bCommandsAllowed) return; if (!Config.AdditionalSetting.KnifeEnabled || !g_bCommandsAllowed) return;
var knivesOnly = weaponList var knivesOnly = weaponList
.Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet")) .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]); 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"]); player!.Print(Localizer["wp_knife_menu_kill"]);
} }
@@ -124,7 +124,7 @@ namespace WeaponPaints
{ {
UserId = player.UserId, UserId = player.UserId,
Index = (int)player.Index, Index = (int)player.Index,
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(), SteamId = player?.AuthorizedSteamID?.SteamId64,
Name = player?.PlayerName, Name = player?.PlayerName,
IpAddress = player?.IpAddress?.Split(":")[0] IpAddress = player?.IpAddress?.Split(":")[0]
}; };
@@ -145,7 +145,7 @@ namespace WeaponPaints
{ {
giveItemMenu.AddMenuOption(knifePair.Value, handleGive); 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; if (!Utility.IsPlayerValid(player) || !g_bCommandsAllowed) return;
@@ -212,25 +212,25 @@ namespace WeaponPaints
if (firstSkin != null && if (firstSkin != null &&
firstSkin.TryGetValue("weapon_defindex", out var weaponDefIndexObj) && firstSkin.TryGetValue("weapon_defindex", out var weaponDefIndexObj) &&
weaponDefIndexObj != null && weaponDefIndexObj != null &&
int.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) && ushort.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) &&
int.TryParse(selectedPaintID, out var paintID)) ushort.TryParse(selectedPaintID, out var paintID))
{ {
p!.Print(Localizer["wp_skin_menu_select", selectedSkin]); p!.Print(Localizer["wp_skin_menu_select", selectedSkin]);
if (!gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex)) if (!gPlayerWeaponsInfo[playerIndex].TryGetValue(weaponDefIndex, out _))
{ {
gPlayerWeaponsInfo[playerIndex][weaponDefIndex] = new WeaponInfo(); gPlayerWeaponsInfo[playerIndex][weaponDefIndex] = new WeaponInfo();
} }
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Paint = paintID; gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Paint = paintID;
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.01f; gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.00001f;
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Seed = 0; gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Seed = 0;
PlayerInfo playerInfo = new PlayerInfo PlayerInfo playerInfo = new PlayerInfo
{ {
UserId = player.UserId, UserId = player.UserId,
Index = (int)player.Index, Index = (int)player.Index,
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(), SteamId = player?.AuthorizedSteamID?.SteamId64,
Name = player?.PlayerName, Name = player?.PlayerName,
IpAddress = player?.IpAddress?.Split(":")[0] IpAddress = player?.IpAddress?.Split(":")[0]
}; };
@@ -238,7 +238,7 @@ namespace WeaponPaints
if (!Config.GlobalShare) if (!Config.GlobalShare)
{ {
if (weaponSync != null) 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); weaponSelectionMenu.AddMenuOption(weaponName, handleWeaponSelection);
} }
// Command to open the weapon selection menu for players // 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; if (!Utility.IsPlayerValid(player)) return;

View File

@@ -3,9 +3,13 @@ using System.Text.Json.Serialization;
namespace WeaponPaints 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; public bool SkinVisibilityFix { get; set; } = true;
[JsonPropertyName("KnifeEnabled")] [JsonPropertyName("KnifeEnabled")]
@@ -14,7 +18,13 @@ namespace WeaponPaints
[JsonPropertyName("SkinEnabled")] [JsonPropertyName("SkinEnabled")]
public bool SkinEnabled { get; set; } = true; 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; public bool CommandWpEnabled { get; set; } = true;
[JsonPropertyName("CommandKillEnabled")] [JsonPropertyName("CommandKillEnabled")]
@@ -46,7 +56,7 @@ namespace WeaponPaints
public class WeaponPaintsConfig : BasePluginConfig public class WeaponPaintsConfig : BasePluginConfig
{ {
public override int Version { get; set; } = 4; public override int Version { get; set; } = 5;
[JsonPropertyName("DatabaseHost")] [JsonPropertyName("DatabaseHost")]
public string DatabaseHost { get; set; } = ""; public string DatabaseHost { get; set; } = "";
@@ -75,8 +85,8 @@ namespace WeaponPaints
[JsonPropertyName("Website")] [JsonPropertyName("Website")]
public string Website { get; set; } = "example.com/skins"; public string Website { get; set; } = "example.com/skins";
[JsonPropertyName("Additional")] [JsonPropertyName("AdditionalSetting")]
public Additional Additional { get; set; } = new Additional(); public AdditionalSetting AdditionalSetting { get; set; } = new AdditionalSetting();
} }
} }

152
Events.cs
View File

@@ -1,5 +1,7 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using System.Numerics;
namespace WeaponPaints namespace WeaponPaints
{ {
@@ -13,22 +15,18 @@ namespace WeaponPaints
{ {
UserId = player.UserId, UserId = player.UserId,
Index = (int)player.Index, Index = (int)player.Index,
SteamId = player.SteamID.ToString(), SteamId = player.SteamID,
Name = player?.PlayerName, Name = player?.PlayerName,
IpAddress = player?.IpAddress?.Split(":")[0] 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.GetPlayerDatabaseIndex(playerInfo);
await weaponSync.GetKnifeFromDatabase(playerInfo);
}); });
}
//if (Config.Additional.KnifeEnabled && weaponSync != null)
//_ = weaponSync.GetKnifeFromDatabase(playerIndex);
}
private void OnClientDisconnect(int playerSlot) 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 (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 _); g_playersKnife.TryRemove((int)player.Index, out _);
if (Config.Additional.SkinEnabled) if (Config.AdditionalSetting.SkinEnabled)
{ {
if (gPlayerWeaponsInfo.TryRemove((int)player.Index, out var innerDictionary)) if (gPlayerWeaponsInfo.TryRemove((int)player.Index, out var innerDictionary))
{ {
innerDictionary.Clear(); 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); commandsCooldown.Remove((int)player.UserId);
} }
@@ -53,7 +54,7 @@ namespace WeaponPaints
private void OnEntityCreated(CEntityInstance entity) 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; if (entity == null || !entity.IsValid || string.IsNullOrEmpty(entity.DesignerName)) return;
string designerName = entity.DesignerName; string designerName = entity.DesignerName;
if (!weaponList.ContainsKey(designerName)) return; if (!weaponList.ContainsKey(designerName)) return;
@@ -93,42 +94,41 @@ namespace WeaponPaints
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
/* /*
if (Config.Additional.SkinVisibilityFix) if (Config.AdditionalSetting.SkinVisibilityFix)
AddTimer(0.2f, () => RefreshSkins(player)); AddTimer(0.2f, () => RefreshSkins(player));
*/ */
return HookResult.Continue; return HookResult.Continue;
} }
/*
/* private HookResult OnItemPickup(EventItemPickup @event, GameEventInfo info)
private HookResult OnItemPickup(EventItemPickup @event, GameEventInfo info) {
{ if (@event.Defindex == 42 || @event.Defindex == 59)
if (@event.Defindex == 42 || @event.Defindex == 59) {
{ CCSPlayerController? player = @event.Userid;
CCSPlayerController? player = @event.Userid; if (player == null || !player.IsValid || !g_knifePickupCount.ContainsKey((int)player.Index) || player.IsBot || !g_playersKnife.ContainsKey((int)player.Index))
if (player == null || !player.IsValid || !g_knifePickupCount.ContainsKey((int)player.Index) || player.IsBot || !g_playersKnife.ContainsKey((int)player.Index)) return HookResult.Continue;
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) if (g_playersKnife.ContainsKey((int)player.Index)
&& &&
g_playersKnife[(int)player.Index] != "weapon_knife") g_playersKnife[(int)player.Index] != "weapon_knife")
{ {
g_knifePickupCount[(int)player.Index]++; g_knifePickupCount[(int)player.Index]++;
RemovePlayerKnife(player, true); RemovePlayerKnife(player, true);
if (!PlayerHasKnife(player) && Config.Additional.GiveKnifeAfterRemove) if (!PlayerHasKnife(player) && Config.AdditionalSetting.GiveKnifeAfterRemove)
AddTimer(0.3f, () => GiveKnifeToPlayer(player)); AddTimer(0.3f, () => GiveKnifeToPlayer(player));
} }
} }
return HookResult.Continue; 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<CCSPlayerPawn>((int)activator.Index).OriginalController.Value; CCSPlayerController? player = Utilities.GetEntityFromIndex<CCSPlayerPawn>((int)activator.Index).OriginalController.Value;
@@ -150,26 +150,25 @@ namespace WeaponPaints
{ {
g_knifePickupCount[(int)player.Index]++; g_knifePickupCount[(int)player.Index]++;
player.RemoveItemByDesignerName(weapon.DesignerName); player.RemoveItemByDesignerName(weapon.DesignerName);
if (Config.Additional.GiveKnifeAfterRemove) if (Config.AdditionalSetting.GiveKnifeAfterRemove)
AddTimer(0.2f, () => GiveKnifeToPlayer(player)); AddTimer(0.2f, () => GiveKnifeToPlayer(player));
} }
return HookResult.Continue; return HookResult.Continue;
} }
private void OnMapStart(string mapName)
private void OnMapStart(string mapName)
{ {
if (!Config.Additional.KnifeEnabled) return; if (!Config.AdditionalSetting.KnifeEnabled) return;
// TODO // TODO
// needed for now // needed for now
AddTimer(2.0f, () => AddTimer(2.0f, () =>
{ {
NativeAPI.IssueServerCommand("mp_t_default_melee \"\""); NativeAPI.IssueServerCommand("mp_t_default_melee \"\"");
NativeAPI.IssueServerCommand("mp_ct_default_melee \"\""); NativeAPI.IssueServerCommand("mp_ct_default_melee \"\"");
NativeAPI.IssueServerCommand("mp_equipment_reset_rounds 0"); NativeAPI.IssueServerCommand("mp_equipment_reset_rounds 0");
if (Config.GlobalShare) if (Config.GlobalShare)
GlobalShareConnect(); GlobalShareConnect();
weaponSync = new WeaponSynchronization(DatabaseConnectionString, Config, GlobalShareApi, GlobalShareServerId); weaponSync = new WeaponSynchronization(DatabaseConnectionString, Config, GlobalShareApi, GlobalShareServerId);
@@ -178,26 +177,24 @@ namespace WeaponPaints
g_hTimerCheckSkinsData = AddTimer(10.0f, () => g_hTimerCheckSkinsData = AddTimer(10.0f, () =>
{ {
List<CCSPlayerController> players = Utilities.GetPlayers(); List<CCSPlayerController> players = Utilities.GetPlayers();
HashSet<int> playerIndexes = new HashSet<int>(gPlayerWeaponsInfo.Keys);
foreach (CCSPlayerController player in players) foreach (CCSPlayerController player in players)
{ {
if (player.IsBot || player.IsHLTV || player.SteamID.ToString() == "") continue; 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, UserId = player.UserId,
Index = (int)player.Index, Index = (int)player.Index,
SteamId = player?.SteamID.ToString(), SteamId = player?.SteamID,
Name = player?.PlayerName, Name = player?.PlayerName,
IpAddress = player?.IpAddress?.Split(":")[0] IpAddress = player?.IpAddress?.Split(":")[0]
}; };
if (weaponSync != null)
if (Config.Additional.SkinEnabled && weaponSync != null) _ = weaponSync.GetKnifeFromDatabase(playerInfo);
_ = weaponSync.GetWeaponPaintsFromDatabase(playerInfo); }
if (Config.Additional.KnifeEnabled && weaponSync != null)
_ = weaponSync.GetKnifeFromDatabase(playerInfo);
}
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE | CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE | CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT);
} }
@@ -211,22 +208,19 @@ namespace WeaponPaints
{ {
UserId = player.UserId, UserId = player.UserId,
Index = (int)player.Index, Index = (int)player.Index,
SteamId = player?.SteamID.ToString(), SteamId = player?.SteamID,
Name = player?.PlayerName, Name = player?.PlayerName,
IpAddress = player?.IpAddress?.Split(":")[0] 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"); Console.WriteLine($"[WeaponPaints] Retrying to retrieve player {player.PlayerName} skins");
Task.Run(async () => Task.Run(async () =>
{ {
if (Config.Additional.SkinEnabled) await weaponSync.GetPlayerDatabaseIndex(playerInfo);
await weaponSync.GetWeaponPaintsFromDatabase(playerInfo); });
if (Config.Additional.KnifeEnabled) }
await weaponSync.GetKnifeFromDatabase(playerInfo);
});
}
return HookResult.Continue; return HookResult.Continue;
} }
@@ -239,7 +233,7 @@ namespace WeaponPaints
return HookResult.Continue; return HookResult.Continue;
} }
if (Config.Additional.KnifeEnabled && !PlayerHasKnife(player)) if (Config.AdditionalSetting.KnifeEnabled && !PlayerHasKnife(player))
{ {
g_knifePickupCount[(int)player.Index] = 0; g_knifePickupCount[(int)player.Index] = 0;
GiveKnifeToPlayer(player); GiveKnifeToPlayer(player);
@@ -247,7 +241,7 @@ namespace WeaponPaints
} }
/* /*
if (Config.Additional.SkinVisibilityFix) if (Config.AdditionalSetting.SkinVisibilityFix)
{ {
AddTimer(0.3f, () => RefreshSkins(player)); AddTimer(0.3f, () => RefreshSkins(player));
} }
@@ -298,11 +292,11 @@ namespace WeaponPaints
if ( if (
viewModel.Value.CBodyComponent != null viewModel.Value.CBodyComponent != null
&& viewModel.Value.CBodyComponent.SceneNode != null && viewModel.Value.CBodyComponent.SceneNode != null
) && weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2
)
{ {
var skeleton = GetSkeletonInstance(viewModel.Value.CBodyComponent.SceneNode); weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2;
skeleton.ModelState.MeshGroupMask = 2; }
}
Utilities.SetStateChanged(viewModel.Value, "CBaseEntity", "m_CBodyComponent"); Utilities.SetStateChanged(viewModel.Value, "CBaseEntity", "m_CBodyComponent");
} }
@@ -318,16 +312,18 @@ namespace WeaponPaints
RegisterListener<Listeners.OnClientPutInServer>(OnClientPutInServer); RegisterListener<Listeners.OnClientPutInServer>(OnClientPutInServer);
RegisterListener<Listeners.OnClientDisconnect>(OnClientDisconnect); RegisterListener<Listeners.OnClientDisconnect>(OnClientDisconnect);
RegisterListener<Listeners.OnMapStart>(OnMapStart); RegisterListener<Listeners.OnMapStart>(OnMapStart);
RegisterListener<Listeners.OnTick>(OnTick);
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull); if (!Config.AdditionalSetting.UseMetamodAlwaysLegacyModel)
RegisterListener<Listeners.OnTick>(OnTick);
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull);
RegisterEventHandler<EventPlayerSpawn>(OnPlayerSpawn); RegisterEventHandler<EventPlayerSpawn>(OnPlayerSpawn);
RegisterEventHandler<EventRoundStart>(OnRoundStart, HookMode.Pre); RegisterEventHandler<EventRoundStart>(OnRoundStart, HookMode.Pre);
RegisterEventHandler<EventRoundEnd>(OnRoundEnd); RegisterEventHandler<EventRoundEnd>(OnRoundEnd);
RegisterEventHandler<EventItemPurchase>(OnEventItemPurchasePost); RegisterEventHandler<EventItemPurchase>(OnEventItemPurchasePost);
//RegisterEventHandler<EventItemPickup>(OnItemPickup); //RegisterEventHandler<EventItemPickup>(OnItemPickup);
HookEntityOutput("weapon_knife", "OnPlayerPickup", OnPickup, HookMode.Pre); HookEntityOutput("weapon_knife", "OnPlayerPickup", OnPickup, HookMode.Pre);
} }
/* WORKAROUND FOR CLIENTS WITHOUT STEAMID ON AUTHORIZATION */ /* 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; if (player == null || !player.IsValid || !player.EntityIndex.HasValue || player.IsHLTV) return HookResult.Continue;
int playerIndex = (int)player.EntityIndex.Value.Value; int playerIndex = (int)player.EntityIndex.Value.Value;
if (Config.Additional.SkinEnabled && weaponSync != null) if (Config.AdditionalSetting.SkinEnabled && weaponSync != null)
_ = weaponSync.GetWeaponPaintsFromDatabase(playerIndex); _ = weaponSync.GetWeaponPaintsFromDatabase(playerIndex);
if (Config.Additional.KnifeEnabled && weaponSync != null) if (Config.AdditionalSetting.KnifeEnabled && weaponSync != null)
_ = weaponSync.GetKnifeFromDatabase(playerIndex); _ = weaponSync.GetKnifeFromDatabase(playerIndex);
Task.Run(async () => Task.Run(async () =>
{ {
if (Config.Additional.SkinEnabled && weaponSync != null) if (Config.AdditionalSetting.SkinEnabled && weaponSync != null)
if (Config.Additional.KnifeEnabled && weaponSync != null) if (Config.AdditionalSetting.KnifeEnabled && weaponSync != null)
}); });
return HookResult.Continue; return HookResult.Continue;

View File

@@ -4,8 +4,8 @@
{ {
public int Index { get; set; } public int Index { get; set; }
public int? UserId { get; set; } public int? UserId { get; set; }
public string? SteamId { get; set; } public ulong? SteamId { get; set; }
public string? Name { get; set; } public string? Name { get; set; }
public string? IpAddress { get; set; } public string? IpAddress { get; set; }
} }
} }

View File

@@ -27,8 +27,7 @@ namespace WeaponPaints
return builder.ConnectionString; return builder.ConnectionString;
} }
internal static async void CheckDatabaseTables()
internal static async void CheckDatabaseTables()
{ {
try try
{ {
@@ -37,15 +36,22 @@ namespace WeaponPaints
using var transaction = await connection.BeginTransactionAsync(); 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"; foreach (string command in sqlCommands)
string createTable2 = "CREATE TABLE IF NOT EXISTS `wp_player_knife` (`steamid` varchar(64) NOT NULL, `knife` varchar(64) NOT NULL, UNIQUE (`steamid`)) ENGINE = InnoDB"; {
await connection.ExecuteAsync(command, transaction: transaction);
}
await connection.ExecuteAsync(createTable1, transaction: transaction); await transaction.CommitAsync();
await connection.ExecuteAsync(createTable2, transaction: transaction);
await transaction.CommitAsync();
} }
catch (Exception) catch (Exception)
{ {

View File

@@ -19,15 +19,14 @@ namespace WeaponPaints
if (isKnife && !g_playersKnife.ContainsKey(playerIndex) || isKnife && g_playersKnife[playerIndex] == "weapon_knife") return; 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) if (isKnife)
{ {
weapon.AttributeManager.Item.EntityQuality = 3; weapon.AttributeManager.Item.EntityQuality = 3;
} }
if (_config.Additional.GiveRandomSkin && if (_config.AdditionalSetting.GiveRandomSkin &&
!gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex)) !gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex))
{ {
// Random skins // Random skins
@@ -36,13 +35,12 @@ namespace WeaponPaints
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32; weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex); weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex);
weapon.FallbackSeed = 0; weapon.FallbackSeed = 0;
weapon.FallbackWear = 0.000001f; weapon.FallbackWear = 0.00001f;
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 (weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2)
if (skeleton.ModelState.MeshGroupMask != 2)
{ {
skeleton.ModelState.MeshGroupMask = 2; weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2;
} }
} }
return; return;
@@ -58,25 +56,25 @@ namespace WeaponPaints
weapon.FallbackSeed = weaponInfo.Seed; weapon.FallbackSeed = weaponInfo.Seed;
weapon.FallbackWear = weaponInfo.Wear; 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 (weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2)
if (skeleton.ModelState.MeshGroupMask != 2)
{ {
skeleton.ModelState.MeshGroupMask = 2; weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2;
} }
} }
}
}
internal static void GiveKnifeToPlayer(CCSPlayerController? player) 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)) if (g_playersKnife.TryGetValue((int)player.Index, out var knife))
{ {
player.GiveNamedItem(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); 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) 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) if (player == null || !player.IsValid || player.PlayerPawn == null || !player.PlayerPawn.IsValid || !player.PawnIsAlive)
{ {
@@ -177,7 +175,7 @@ namespace WeaponPaints
} }
} }
} }
/*
internal void RefreshSkins(CCSPlayerController? player) internal void RefreshSkins(CCSPlayerController? player)
{ {
return; return;
@@ -187,8 +185,8 @@ namespace WeaponPaints
AddTimer(0.25f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot2")); AddTimer(0.25f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot2"));
AddTimer(0.38f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot1")); 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 == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PawnIsAlive) return;
if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null) return; if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null) return;
@@ -213,13 +211,13 @@ namespace WeaponPaints
} }
else else
{ {
if (!weaponDefindex.ContainsKey(weapon.Value.AttributeManager.Item.ItemDefinitionIndex)) continue; if (!WeaponDefindex.ContainsKey(weapon.Value.AttributeManager.Item.ItemDefinitionIndex)) continue;
int clip1, reservedAmmo; int clip1, reservedAmmo;
clip1 = weapon.Value.Clip1; clip1 = weapon.Value.Clip1;
reservedAmmo = weapon.Value.ReserveAmmo[0]; 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); player.RemoveItemByDesignerName(weapon.Value.DesignerName, true);
CBasePlayerWeapon newWeapon = new(player.GiveNamedItem(weaponByDefindex)); CBasePlayerWeapon newWeapon = new(player.GiveNamedItem(weaponByDefindex));
@@ -246,7 +244,7 @@ namespace WeaponPaints
} }
/* /*
if (Config.Additional.SkinVisibilityFix) if (Config.AdditionalSetting.SkinVisibilityFix)
RefreshSkins(player); RefreshSkins(player);
*/ */
} }
@@ -321,13 +319,6 @@ namespace WeaponPaints
} }
return 0; return 0;
} }
private static CSkeletonInstance GetSkeletonInstance(CGameSceneNode node)
{
Func<nint, nint> GetSkeletonInstance = VirtualFunction.Create<nint, nint>(node.Handle, 8);
return new CSkeletonInstance(GetSkeletonInstance(node.Handle));
}
private static unsafe CHandle<CBaseViewModel>[]? GetPlayerViewModels(CCSPlayerController player) private static unsafe CHandle<CBaseViewModel>[]? GetPlayerViewModels(CCSPlayerController player)
{ {
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null; if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null;
@@ -348,6 +339,5 @@ namespace WeaponPaints
return values; return values;
} }
} }
} }

View File

@@ -2,8 +2,12 @@
{ {
public class WeaponInfo public class WeaponInfo
{ {
public int Paint { get; set; } public ushort Paint { get; set; }
public int Seed { get; set; } public ushort Seed { get; set; }
public float Wear { 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; }
}
} }

View File

@@ -9,7 +9,7 @@ using System.Collections.Concurrent;
namespace WeaponPaints; namespace WeaponPaints;
[MinimumApiVersion(144)] [MinimumApiVersion(155)]
public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig> public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig>
{ {
internal static readonly Dictionary<string, string> weaponList = new() internal static readonly Dictionary<string, string> weaponList = new()
@@ -69,12 +69,70 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
{ "weapon_knife_outdoor", "Nomad Knife" }, { "weapon_knife_outdoor", "Nomad Knife" },
{ "weapon_knife_skeleton", "Skeleton Knife" } { "weapon_knife_skeleton", "Skeleton Knife" }
}; };
public static Dictionary<int, string> WeaponDefindex { get; } = new Dictionary<int, string>
{
{ 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 IStringLocalizer? _localizer;
internal static Dictionary<int, int> g_knifePickupCount = new Dictionary<int, int>(); 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, int> g_playersDatabaseIndex = new ConcurrentDictionary<int, int>();
internal static ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>> gPlayerWeaponsInfo = new ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>>(); internal static ConcurrentDictionary<int, string> g_playersKnife = new ConcurrentDictionary<int, string>();
internal static ConcurrentDictionary<int, int?> g_playersMusicKit = new ConcurrentDictionary<int, int?>();
internal static ConcurrentDictionary<int, ConcurrentDictionary<ushort, WeaponInfo>> gPlayerWeaponsInfo = new ConcurrentDictionary<int, ConcurrentDictionary<ushort, WeaponInfo>>();
internal static List<JObject> skinsList = new List<JObject>(); internal static List<JObject> skinsList = new List<JObject>();
internal static WeaponSynchronization? weaponSync; internal static WeaponSynchronization? weaponSync;
internal bool g_bCommandsAllowed = true; internal bool g_bCommandsAllowed = true;
@@ -84,68 +142,11 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
internal static Dictionary<int, DateTime> commandsCooldown = new Dictionary<int, DateTime>(); internal static Dictionary<int, DateTime> commandsCooldown = new Dictionary<int, DateTime>();
private string DatabaseConnectionString = string.Empty; private string DatabaseConnectionString = string.Empty;
private CounterStrikeSharp.API.Modules.Timers.Timer? g_hTimerCheckSkinsData = null; private CounterStrikeSharp.API.Modules.Timers.Timer? g_hTimerCheckSkinsData = null;
public static Dictionary<int, string> weaponDefindex { get; } = new Dictionary<int, string> public WeaponPaintsConfig Config { get; set; } = new();
{
{ 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 override string ModuleAuthor => "Nereziel & daffyy"; public override string ModuleAuthor => "Nereziel & daffyy";
public override string ModuleDescription => "Skin and knife selector, standalone and web-based"; public override string ModuleDescription => "Skin and knife selector, standalone and web-based";
public override string ModuleName => "WeaponPaints"; public override string ModuleName => "WeaponPaints";
public override string ModuleVersion => "1.4b"; public override string ModuleVersion => "1.5.0";
public static WeaponPaintsConfig GetWeaponPaintsConfig() public static WeaponPaintsConfig GetWeaponPaintsConfig()
{ {
@@ -169,23 +170,21 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
foreach (CCSPlayerController player in players) foreach (CCSPlayerController player in players)
{ {
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.SteamID.ToString() == "") continue; if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.SteamID.ToString() == "") continue;
if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue; if (g_playersDatabaseIndex.ContainsKey((int)player.Index)) continue;
PlayerInfo playerInfo = new PlayerInfo PlayerInfo playerInfo = new PlayerInfo
{ {
UserId = player.UserId, UserId = player.UserId,
Index = (int)player.Index, Index = (int)player.Index,
SteamId = player?.SteamID.ToString(), SteamId = player?.SteamID,
Name = player?.PlayerName, Name = player?.PlayerName,
IpAddress = player?.IpAddress?.Split(":")[0] IpAddress = player?.IpAddress?.Split(":")[0]
}; };
if (weaponSync != null)
if (Config.Additional.SkinEnabled && weaponSync != null) {
_ = weaponSync.GetWeaponPaintsFromDatabase(playerInfo); _ = weaponSync!.GetPlayerDatabaseIndex(playerInfo);
if (Config.Additional.KnifeEnabled && weaponSync != null) }
_ = weaponSync.GetKnifeFromDatabase(playerInfo); g_knifePickupCount[(int)player!.Index] = 0;
g_knifePickupCount[(int)player!.Index] = 0;
} }
/* /*
RegisterListeners(); RegisterListeners();
@@ -193,9 +192,9 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
*/ */
} }
if (Config.Additional.KnifeEnabled) if (Config.AdditionalSetting.KnifeEnabled)
SetupKnifeMenu(); SetupKnifeMenu();
if (Config.Additional.SkinEnabled) if (Config.AdditionalSetting.SkinEnabled)
SetupSkinsMenu(); SetupSkinsMenu();
RegisterListeners(); RegisterListeners();
@@ -210,16 +209,37 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
{ {
if (config.DatabaseHost.Length < 1 || config.DatabaseName.Length < 1 || config.DatabaseUser.Length < 1) if (config.DatabaseHost.Length < 1 || config.DatabaseName.Length < 1 || config.DatabaseUser.Length < 1)
{ {
Logger.LogError("You need to setup Database credentials in config!"); // maybe more spam to get attention?
throw new Exception("[WeaponPaints] You need to setup Database credentials in config!"); for (int i = 1; i <= 30; i++)
} {
Console.WriteLine("[WeaponPaints] You need to setup Database credentials in config!");
}
Logger.LogError("You need to setup Database credentials in config!");
throw new Exception("[WeaponPaints] You need to setup Database credentials in config!");
}
} }
else
{
// maybe more spam to get attention?
for (int i = 1; i <= 30; i++)
{
Console.WriteLine("[WeaponPaints] GLOBAL SHARE IS NOT SUPPORTED NOW !!");
}
Logger.LogError("GLOBAL SHARE IS NOT SUPPORTED NOW !!");
throw new Exception("[WeaponPaints] GLOBAL SHARE IS NOT SUPPORTED NOW !!");
}
Config = config; Config = config;
_config = config; _config = config;
_localizer = Localizer; _localizer = Localizer;
Utility.Config = config; /*
* GLOBAL SHARE IS NOT SUPPORTED NOW!
*/
if (Config.GlobalShare)
Config.GlobalShare = false;
Utility.Config = config;
Utility.ShowAd(ModuleVersion); Utility.ShowAd(ModuleVersion);
Task.Run(async () => await Utility.CheckVersion(ModuleVersion, Logger)); Task.Run(async () => await Utility.CheckVersion(ModuleVersion, Logger));
} }

View File

@@ -1,4 +1,6 @@
using Dapper; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using Dapper;
using MySqlConnector; using MySqlConnector;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@@ -19,21 +21,64 @@ namespace WeaponPaints
_globalShareApi = globalShareApi; _globalShareApi = globalShareApi;
_globalShareServerId = globalShareServerId; _globalShareServerId = globalShareServerId;
} }
internal async Task GetPlayerDatabaseIndex(PlayerInfo player)
internal async Task GetKnifeFromDatabase(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<int?>(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<int?>(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; if (player.SteamId == null || player.Index == 0) return;
try try
{ {
if (_config.GlobalShare) if (_config.GlobalShare)
{ {
var values = new Dictionary<string, string> var values = new Dictionary<string, string>
{ {
{ "server_id", _globalShareServerId.ToString() }, { "server_id", _globalShareServerId.ToString() },
{ "steamid", player.SteamId }, { "steamid", player.SteamId.ToString()! },
{ "knife", "1" } { "knife", "1" }
}; };
UriBuilder builder = new UriBuilder(_globalShareApi); UriBuilder builder = new UriBuilder(_globalShareApi);
builder.Query = string.Join("&", values.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}")); builder.Query = string.Join("&", values.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}"));
@@ -64,13 +109,17 @@ namespace WeaponPaints
return; 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(); await connection.OpenAsync();
string query = "SELECT `knife` FROM `wp_player_knife` WHERE `steamid` = @steamid"; string query = "SELECT `knife` FROM `wp_users_knife` WHERE `user_id` = @userId";
string? PlayerKnife = await connection.QueryFirstOrDefaultAsync<string>(query, new { steamid = player.SteamId }); string? PlayerKnife = await connection.QueryFirstOrDefaultAsync<string>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] });
if (PlayerKnife != null)
if (PlayerKnife != null)
{ {
WeaponPaints.g_playersKnife[player.Index] = PlayerKnife; WeaponPaints.g_playersKnife[player.Index] = PlayerKnife;
} }
@@ -83,30 +132,63 @@ namespace WeaponPaints
} }
catch (Exception e) catch (Exception e)
{ {
Utility.Log(e.Message); Utility.Log("GetKnifeFromDatabase: " + e.Message);
return; 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<int?>(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 (player.SteamId == null || player.Index == 0) return;
if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out _)) if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out _))
{ {
WeaponPaints.gPlayerWeaponsInfo[player.Index] = new ConcurrentDictionary<int, WeaponInfo>(); WeaponPaints.gPlayerWeaponsInfo[player.Index] = new ConcurrentDictionary<ushort, WeaponInfo>();
} }
try
try
{ {
if (_config.GlobalShare) if (_config.GlobalShare)
{ {
var values = new Dictionary<string, string> var values = new Dictionary<string, string>
{ {
{ "server_id", _globalShareServerId.ToString() }, { "server_id", _globalShareServerId.ToString() },
{ "steamid", player.SteamId }, { "steamid", player.SteamId.ToString()! },
{ "skins", "1" } { "skins", "1" }
}; };
UriBuilder builder = new UriBuilder(_globalShareApi); UriBuilder builder = new UriBuilder(_globalShareApi);
builder.Query = string.Join("&", values.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}")); 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) foreach (var weapon in jsonArray)
{ {
int? weaponDefIndex = weapon["weapon_defindex"]?.Value<int>(); ushort? weaponDefIndex = weapon["weapon_defindex"]?.Value<ushort>();
int? weaponPaintId = weapon["weapon_paint_id"]?.Value<int>(); ushort? weaponPaintId = weapon["weapon_paint_id"]?.Value<ushort>();
float? weaponWear = weapon["weapon_wear"]?.Value<float>(); float? weaponWear = weapon["weapon_wear"]?.Value<float>();
int? weaponSeed = weapon["weapon_seed"]?.Value<int>(); ushort? weaponSeed = weapon["weapon_seed"]?.Value<ushort>();
if (weaponDefIndex != null && weaponPaintId != null && weaponWear != null && weaponSeed != null) if (weaponDefIndex != null && weaponPaintId != null && weaponWear != null && weaponSeed != null)
{ {
WeaponInfo weaponInfo = new WeaponInfo WeaponInfo weaponInfo = new WeaponInfo
{ {
Paint = weaponPaintId.Value, Paint = weaponPaintId.Value,
Seed = weaponSeed.Value, Seed = weaponSeed.Value,
Wear = weaponWear.Value Wear = weaponWear.Value,
}; NameTag = null
};
WeaponPaints.gPlayerWeaponsInfo[player.Index][weaponDefIndex.Value] = weaponInfo; 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(); await connection.OpenAsync();
string query = "SELECT `weapon`, `paint`, `wear`, `seed`, `nametag` FROM `wp_users_items` WHERE `user_id` = @userId";
string query = "SELECT * FROM `wp_player_skins` WHERE `steamid` = @steamid"; IEnumerable<dynamic> PlayerSkins = await connection.QueryAsync<dynamic>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] });
IEnumerable<dynamic> PlayerSkins = await connection.QueryAsync<dynamic>(query, new { steamid = player.SteamId }); if (PlayerSkins != null && PlayerSkins.Any())
if (PlayerSkins != null && PlayerSkins.AsList().Count > 0)
{ {
PlayerSkins.ToList().ForEach(row => PlayerSkins.ToList().ForEach(row =>
{ {
int weaponDefIndex = row.weapon_defindex ?? default(int); ushort weaponDefIndex = row.weapon ?? default(ushort);
int weaponPaintId = row.weapon_paint_id ?? default(int); ushort weaponPaintId = row.paint ?? default(ushort);
float weaponWear = row.weapon_wear ?? default(float); float weaponWear = row.wear ?? default(float);
int weaponSeed = row.weapon_seed ?? default(int); ushort weaponSeed = row.seed ?? default(ushort);
string weaponNameTag = row.nametag;
WeaponInfo weaponInfo = new WeaponInfo WeaponInfo weaponInfo = new WeaponInfo
{ {
Paint = weaponPaintId, Paint = weaponPaintId,
Seed = weaponSeed, Seed = weaponSeed,
Wear = weaponWear Wear = weaponWear,
}; NameTag = weaponNameTag
};
WeaponPaints.gPlayerWeaponsInfo[player.Index][weaponDefIndex] = weaponInfo; WeaponPaints.gPlayerWeaponsInfo[player.Index][weaponDefIndex] = weaponInfo;
}); });
} }
@@ -184,22 +272,24 @@ namespace WeaponPaints
} }
catch (Exception e) catch (Exception e)
{ {
Utility.Log(e.Message); Utility.Log("GetWeaponPaintsFromDatabase: " + e.Message);
return; return;
} }
} }
internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife) internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife)
{ {
if (!_config.Additional.KnifeEnabled) return; if (!_config.AdditionalSetting.KnifeEnabled) return;
try 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(); await connection.OpenAsync();
string query = "INSERT INTO `wp_player_knife` (`steamid`, `knife`) VALUES(@steamid, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife"; string query = "INSERT INTO `wp_users_knife` (`user_id`, `knife`) VALUES(@userId, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife";
await connection.ExecuteAsync(query, new { steamid = player.SteamId, newKnife = knife }); await connection.ExecuteAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index], newKnife = knife });
await connection.CloseAsync(); await connection.CloseAsync();
} }
catch (Exception e) catch (Exception e)
@@ -208,42 +298,34 @@ namespace WeaponPaints
return; 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); if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out var playerDatabaseIndex))
await connection.OpenAsync(); return;
if (!WeaponPaints.gPlayerWeaponsInfo.ContainsKey(player.Index)) if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out var playerSavedWeapons))
return; return;
foreach (var weaponInfoPair in WeaponPaints.gPlayerWeaponsInfo[player.Index]) if (!playerSavedWeapons.TryGetValue(weaponDefIndex, out var weaponInfo))
{ return;
int weaponDefIndex = weaponInfoPair.Key;
WeaponInfo weaponInfo = weaponInfoPair.Value;
int paintId = weaponInfo.Paint; using var connection = new MySqlConnection(_databaseConnectionString);
float wear = weaponInfo.Wear; string querySql = @"
int seed = weaponInfo.Seed; 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();
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();
} }
} }
} }