This commit is contained in:
Nereziel
2024-05-26 19:28:36 +02:00
parent 771a832ae8
commit 322b1b425b
21 changed files with 1264 additions and 1093 deletions

View File

@@ -224,8 +224,8 @@ namespace WeaponPaints
if (firstSkin == null || if (firstSkin == null ||
!firstSkin.TryGetValue("weapon_defindex", out var weaponDefIndexObj) || !firstSkin.TryGetValue("weapon_defindex", out var weaponDefIndexObj) ||
!int.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) || !ushort.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) ||
!int.TryParse(selectedPaintId, out var paintId)) return; !ushort.TryParse(selectedPaintId, out var paintId)) return;
{ {
if (Config.Additional.ShowSkinImage && skinsList != null) if (Config.Additional.ShowSkinImage && skinsList != null)
{ {

View File

@@ -20,7 +20,10 @@ namespace WeaponPaints
[JsonPropertyName("SkinEnabled")] [JsonPropertyName("SkinEnabled")]
public bool SkinEnabled { get; set; } = true; public bool SkinEnabled { get; set; } = true;
[JsonPropertyName("CommandWpEnabled")] [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")]
@@ -62,7 +65,7 @@ namespace WeaponPaints
public class WeaponPaintsConfig : BasePluginConfig public class WeaponPaintsConfig : BasePluginConfig
{ {
public override int Version { get; set; } = 6; public override int Version { get; set; } = 7;
[JsonPropertyName("DatabaseHost")] [JsonPropertyName("DatabaseHost")]
public string DatabaseHost { get; set; } = ""; public string DatabaseHost { get; set; } = "";

View File

@@ -23,14 +23,14 @@ namespace WeaponPaints
UserId = player.UserId, UserId = player.UserId,
Slot = player.Slot, Slot = player.Slot,
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]
}; };
try try
{ {
_ = Task.Run(async () => await weaponSync.GetPlayerData(playerInfo)); _ = Task.Run(async () => await weaponSync.GetPlayerDatabaseIndex(playerInfo));
/* /*
if (Config.Additional.SkinEnabled) if (Config.Additional.SkinEnabled)
{ {
@@ -54,9 +54,10 @@ namespace WeaponPaints
} }
*/ */
} }
catch catch (Exception)
{ {
} return HookResult.Continue;
}
return HookResult.Continue; return HookResult.Continue;
} }
@@ -68,7 +69,9 @@ namespace WeaponPaints
if (player is null || !player.IsValid || player.IsBot) return HookResult.Continue; if (player is null || !player.IsValid || player.IsBot) return HookResult.Continue;
if (Config.Additional.SkinEnabled) g_playersDatabaseIndex.TryRemove(player.Slot, out _);
if (Config.Additional.SkinEnabled)
{ {
gPlayerWeaponsInfo.TryRemove(player.Slot, out _); gPlayerWeaponsInfo.TryRemove(player.Slot, out _);
} }

View File

@@ -5,7 +5,7 @@
public int Index { get; set; } public int Index { get; set; }
public int Slot { get; init; } public int Slot { get; init; }
public int? UserId { get; set; } public int? UserId { get; set; }
public string? SteamId { get; init; } public ulong? SteamId { get; init; }
public string? Name { get; set; } public string? Name { get; set; }
public string? IpAddress { get; set; } public string? IpAddress { get; set; }
} }

View File

@@ -22,46 +22,16 @@ namespace WeaponPaints
await using var transaction = await connection.BeginTransactionAsync(); await using var transaction = await connection.BeginTransactionAsync();
try try
{ {
string[] createTableQueries = var createTableQueries = new[]
[ {
""" "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_player_skins` ( "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.001, `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;",
`steamid` varchar(18) NOT NULL, "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;",
`weapon_defindex` int(6) NOT NULL, "CREATE TABLE IF NOT EXISTS `wp_users_gloves` (`user_id` INT UNSIGNED NOT NULL, `weapon_defindex` SMALLINT UNSIGNED DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
`weapon_paint_id` int(6) NOT NULL, "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;",
`weapon_wear` float NOT NULL DEFAULT 0.000001, "CREATE TABLE IF NOT EXISTS `wp_users_agents` (`user_id` INT UNSIGNED NOT NULL,`agent_ct` varchar(64) DEFAULT NULL,`agent_t` varchar(64) DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"
`weapon_seed` int(16) NOT NULL DEFAULT 0 };
) ENGINE=InnoDB
""",
@"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` (
`steamid` varchar(18) NOT NULL,
`weapon_defindex` int(11) NOT NULL,
UNIQUE (`steamid`)
) ENGINE=InnoDB
""",
"""
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` (
`steamid` varchar(64) NOT NULL,
`music_id` int(11) NOT NULL,
UNIQUE (`steamid`)
) ENGINE=InnoDB
""",
];
foreach (var query in createTableQueries) foreach (var query in createTableQueries)
{ {

View File

@@ -1,451 +1,457 @@
using CounterStrikeSharp.API; using System.Diagnostics;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.InteropServices;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Runtime.InteropServices;
namespace WeaponPaints namespace WeaponPaints;
public partial class WeaponPaints
{ {
public partial class WeaponPaints private void GivePlayerWeaponSkin(CCSPlayerController player, CBasePlayerWeapon weapon)
{ {
private void GivePlayerWeaponSkin(CCSPlayerController player, CBasePlayerWeapon weapon) if (!Config.Additional.SkinEnabled) return;
{ if (!gPlayerWeaponsInfo.TryGetValue(player.Slot, out _)) return;
if (!Config.Additional.SkinEnabled) return;
if (!gPlayerWeaponsInfo.TryGetValue(player.Slot, out _)) return; var isKnife = weapon.DesignerName.Contains("knife") || weapon.DesignerName.Contains("bayonet");
bool isKnife = weapon.DesignerName.Contains("knife") || weapon.DesignerName.Contains("bayonet"); if ((isKnife && !g_playersKnife.ContainsKey(player.Slot)) ||
(isKnife && g_playersKnife[player.Slot] == "weapon_knife")) return;
if (isKnife && !g_playersKnife.ContainsKey(player.Slot) || isKnife && g_playersKnife[player.Slot] == "weapon_knife") return;
int[] newPaints =
int[] newPaints = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 }; [1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173];
if (isKnife) if (isKnife)
{ {
var newDefIndex = WeaponDefindex.FirstOrDefault(x => x.Value == g_playersKnife[player.Slot]); var newDefIndex = WeaponDefindex.FirstOrDefault(x => x.Value == g_playersKnife[player.Slot]);
if (newDefIndex.Key == 0) return; if (newDefIndex.Key == 0) return;
if (weapon.AttributeManager.Item.ItemDefinitionIndex != newDefIndex.Key) if (weapon.AttributeManager.Item.ItemDefinitionIndex != newDefIndex.Key)
{ SubclassChange(weapon, (ushort)newDefIndex.Key);
SubclassChange(weapon, (ushort)newDefIndex.Key);
} weapon.AttributeManager.Item.ItemDefinitionIndex = (ushort)newDefIndex.Key;
weapon.AttributeManager.Item.EntityQuality = 3;
weapon.AttributeManager.Item.ItemDefinitionIndex = (ushort)newDefIndex.Key; }
weapon.AttributeManager.Item.EntityQuality = 3;
} UpdatePlayerEconItemId(weapon.AttributeManager.Item);
UpdatePlayerEconItemId(weapon.AttributeManager.Item); int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
var fallbackPaintKit = 0;
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
int fallbackPaintKit = 0; weapon.AttributeManager.Item.AccountID = (uint)player.SteamID;
weapon.AttributeManager.Item.AccountID = (uint)player.SteamID; if (_config.Additional.GiveRandomSkin &&
!gPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex))
if (_config.Additional.GiveRandomSkin && {
!gPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex)) // Random skins
{ weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex);
// Random skins weapon.FallbackSeed = 0;
weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex); weapon.FallbackWear = 0.01f;
weapon.FallbackSeed = 0;
weapon.FallbackWear = 0.01f; weapon.AttributeManager.Item.NetworkedDynamicAttributes.Attributes.RemoveAll();
CAttributeListSetOrAddAttributeValueByName.Invoke(
weapon.AttributeManager.Item.NetworkedDynamicAttributes.Attributes.RemoveAll(); weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab",
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", GetRandomPaint(weaponDefIndex)); GetRandomPaint(weaponDefIndex));
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture seed", 0); CAttributeListSetOrAddAttributeValueByName.Invoke(
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture wear", 0.01f); weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture seed", 0);
CAttributeListSetOrAddAttributeValueByName.Invoke(
weapon.AttributeManager.Item.AttributeList.Attributes.RemoveAll(); weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture wear", 0.01f);
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture prefab", GetRandomPaint(weaponDefIndex));
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture seed", 0); weapon.AttributeManager.Item.AttributeList.Attributes.RemoveAll();
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture wear", 0.01f); CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle,
"set item texture prefab", GetRandomPaint(weaponDefIndex));
fallbackPaintKit = weapon.FallbackPaintKit; CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle,
"set item texture seed", 0);
if (fallbackPaintKit == 0) CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle,
return; "set item texture wear", 0.01f);
if (isKnife) return; fallbackPaintKit = weapon.FallbackPaintKit;
UpdatePlayerWeaponMeshGroupMask(player, weapon, !newPaints.Contains(fallbackPaintKit));
return; if (fallbackPaintKit == 0)
} return;
if (!gPlayerWeaponsInfo[player.Slot].TryGetValue(weaponDefIndex, out var value) || value.Paint == 0) return; if (isKnife) return;
UpdatePlayerWeaponMeshGroupMask(player, weapon, !newPaints.Contains(fallbackPaintKit));
var weaponInfo = value; return;
//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; if (!gPlayerWeaponsInfo[player.Slot].TryGetValue(weaponDefIndex, out var value) || value.Paint == 0) return;
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
weapon.FallbackPaintKit = weaponInfo.Paint; var weaponInfo = value;
weapon.FallbackSeed = weaponInfo.Seed; //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.FallbackWear = weaponInfo.Wear; weapon.AttributeManager.Item.ItemID = 16384;
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit); weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF;
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
fallbackPaintKit = weapon.FallbackPaintKit; weapon.FallbackPaintKit = weaponInfo.Paint;
weapon.FallbackSeed = weaponInfo.Seed;
if (fallbackPaintKit == 0) weapon.FallbackWear = weaponInfo.Wear;
return; CAttributeListSetOrAddAttributeValueByName.Invoke(
weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab",
if (isKnife) return; weapon.FallbackPaintKit);
UpdatePlayerWeaponMeshGroupMask(player, weapon, !newPaints.Contains(fallbackPaintKit));
} fallbackPaintKit = weapon.FallbackPaintKit;
private static void GiveKnifeToPlayer(CCSPlayerController? player) if (fallbackPaintKit == 0)
{ return;
if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return;
if (isKnife) return;
if (PlayerHasKnife(player)) return; UpdatePlayerWeaponMeshGroupMask(player, weapon, !newPaints.Contains(fallbackPaintKit));
}
//string knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife";
player.GiveNamedItem(CsItem.Knife); private static void GiveKnifeToPlayer(CCSPlayerController? player)
} {
if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return;
private static bool PlayerHasKnife(CCSPlayerController? player)
{ if (PlayerHasKnife(player)) return;
if (!_config.Additional.KnifeEnabled) return false;
//string knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife";
if (player == null || !player.IsValid || !player.PlayerPawn.IsValid) player.GiveNamedItem(CsItem.Knife);
{ }
return false;
} private static bool PlayerHasKnife(CCSPlayerController? player)
{
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null) if (!_config.Additional.KnifeEnabled) return false;
return false;
if (player == null || !player.IsValid || !player.PlayerPawn.IsValid) return false;
var weapons = player.PlayerPawn.Value.WeaponServices?.MyWeapons;
if (weapons == null) return false; if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.WeaponServices == null ||
foreach (var weapon in weapons) player.PlayerPawn.Value.ItemServices == null)
{ return false;
if (!weapon.IsValid || weapon.Value == null || !weapon.Value.IsValid) continue;
if (weapon.Value.DesignerName.Contains("knife") || weapon.Value.DesignerName.Contains("bayonet")) var weapons = player.PlayerPawn.Value.WeaponServices?.MyWeapons;
{ if (weapons == null) return false;
return true; foreach (var weapon in weapons)
} {
} if (!weapon.IsValid || weapon.Value == null || !weapon.Value.IsValid) continue;
return false; if (weapon.Value.DesignerName.Contains("knife") || weapon.Value.DesignerName.Contains("bayonet"))
} return true;
}
private void RefreshWeapons(CCSPlayerController? player)
{ return false;
if (!g_bCommandsAllowed) return; }
if (player == null || !player.IsValid || player.PlayerPawn?.Value == null || (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE)
return; private void RefreshWeapons(CCSPlayerController? player)
if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null) {
return; if (!g_bCommandsAllowed) return;
if (player == null || !player.IsValid || player.PlayerPawn?.Value == null ||
var weapons = player.PlayerPawn.Value.WeaponServices.MyWeapons; (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE)
return;
if (weapons.Count == 0) if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null)
return; return;
if (player.Team is CsTeam.None or CsTeam.Spectator)
return; var weapons = player.PlayerPawn.Value.WeaponServices.MyWeapons;
int playerTeam = player.TeamNum; if (weapons.Count == 0)
return;
Dictionary<string, List<(int, int)>> weaponsWithAmmo = []; if (player.Team is CsTeam.None or CsTeam.Spectator)
return;
foreach (var weapon in weapons)
{ int playerTeam = player.TeamNum;
if (!weapon.IsValid || weapon.Value == null ||
!weapon.Value.IsValid || !weapon.Value.DesignerName.Contains("weapon_")) Dictionary<string, List<(int, int)>> weaponsWithAmmo = [];
continue;
foreach (var weapon in weapons)
CCSWeaponBaseGun gun = weapon.Value.As<CCSWeaponBaseGun>(); {
if (!weapon.IsValid || weapon.Value == null ||
if (weapon.Value.Entity == null) continue; !weapon.Value.IsValid || !weapon.Value.DesignerName.Contains("weapon_"))
if (!weapon.Value.OwnerEntity.IsValid) continue; continue;
if (gun.Entity == null) continue;
if (!gun.IsValid) continue; var gun = weapon.Value.As<CCSWeaponBaseGun>();
if (!gun.VisibleinPVS) continue;
if (weapon.Value.Entity == null) continue;
try if (!weapon.Value.OwnerEntity.IsValid) continue;
{ if (gun.Entity == null) continue;
CCSWeaponBaseVData? weaponData = weapon.Value.As<CCSWeaponBase>().VData; if (!gun.IsValid) continue;
if (!gun.VisibleinPVS) continue;
if (weaponData == null) continue;
try
if (weaponData.GearSlot == gear_slot_t.GEAR_SLOT_RIFLE || weaponData.GearSlot == gear_slot_t.GEAR_SLOT_PISTOL) {
{ var weaponData = weapon.Value.As<CCSWeaponBase>().VData;
if (!WeaponDefindex.TryGetValue(weapon.Value.AttributeManager.Item.ItemDefinitionIndex, out var weaponByDefindex))
continue; if (weaponData == null) continue;
int clip1 = weapon.Value.Clip1; if (weaponData.GearSlot == gear_slot_t.GEAR_SLOT_RIFLE ||
int reservedAmmo = weapon.Value.ReserveAmmo[0]; weaponData.GearSlot == gear_slot_t.GEAR_SLOT_PISTOL)
{
if (!weaponsWithAmmo.TryGetValue(weaponByDefindex, out var value)) if (!WeaponDefindex.TryGetValue(weapon.Value.AttributeManager.Item.ItemDefinitionIndex,
{ out var weaponByDefindex))
value = []; continue;
weaponsWithAmmo.Add(weaponByDefindex, value);
} var clip1 = weapon.Value.Clip1;
var reservedAmmo = weapon.Value.ReserveAmmo[0];
value.Add((clip1, reservedAmmo));
if (!weaponsWithAmmo.TryGetValue(weaponByDefindex, out var value))
if (gun.VData == null) return; {
value = [];
weapon.Value.Remove(); weaponsWithAmmo.Add(weaponByDefindex, value);
} }
}
catch (Exception ex) value.Add((clip1, reservedAmmo));
{
Logger.LogWarning(ex.Message); if (gun.VData == null) return;
continue;
} weapon.Value.Remove();
} }
}
try catch (Exception ex)
{ {
player.ExecuteClientCommand("slot 3"); Logger.LogWarning(ex.Message);
player.ExecuteClientCommand("slot 3"); }
}
var weapon = player.PlayerPawn.Value.WeaponServices.ActiveWeapon;
if (!weapon.IsValid || weapon.Value == null) return; try
CCSWeaponBaseVData? weaponData = weapon.Value.As<CCSWeaponBase>().VData; {
player.ExecuteClientCommand("slot 3");
if (weapon.Value.DesignerName.Contains("knife") || weaponData?.GearSlot == gear_slot_t.GEAR_SLOT_KNIFE) player.ExecuteClientCommand("slot 3");
{
CCSWeaponBaseGun gun; var weapon = player.PlayerPawn.Value.WeaponServices.ActiveWeapon;
if (!weapon.IsValid || weapon.Value == null) return;
AddTimer(0.3f, () => var weaponData = weapon.Value.As<CCSWeaponBase>().VData;
{
if (player.TeamNum != playerTeam) return; if (weapon.Value.DesignerName.Contains("knife") || weaponData?.GearSlot == gear_slot_t.GEAR_SLOT_KNIFE)
{
player.ExecuteClientCommand("slot 3"); CCSWeaponBaseGun gun;
gun = weapon.Value.As<CCSWeaponBaseGun>();
player.DropActiveWeapon(); AddTimer(0.3f, () =>
{
AddTimer(0.7f, () => if (player.TeamNum != playerTeam) return;
{
if (player.TeamNum != playerTeam) return; player.ExecuteClientCommand("slot 3");
gun = weapon.Value.As<CCSWeaponBaseGun>();
if (!gun.IsValid || gun.State != CSWeaponState_t.WEAPON_NOT_CARRIED) return; player.DropActiveWeapon();
gun.Remove(); AddTimer(0.7f, () =>
}); {
if (player.TeamNum != playerTeam) return;
GiveKnifeToPlayer(player);
}); if (!gun.IsValid || gun.State != CSWeaponState_t.WEAPON_NOT_CARRIED) return;
}
} gun.Remove();
catch (Exception ex) });
{
Logger.LogWarning($"Cannot remove knife: {ex.Message}"); GiveKnifeToPlayer(player);
} });
}
AddTimer(0.6f, () => }
{ catch (Exception ex)
if (!g_bCommandsAllowed) return; {
Logger.LogWarning($"Cannot remove knife: {ex.Message}");
foreach (var entry in weaponsWithAmmo) }
{
foreach (var ammo in entry.Value) AddTimer(0.6f, () =>
{ {
var newWeapon = new CBasePlayerWeapon(player.GiveNamedItem(entry.Key)); if (!g_bCommandsAllowed) return;
Server.NextFrame(() =>
{ foreach (var entry in weaponsWithAmmo)
try foreach (var ammo in entry.Value)
{ {
newWeapon.Clip1 = ammo.Item1; var newWeapon = new CBasePlayerWeapon(player.GiveNamedItem(entry.Key));
newWeapon.ReserveAmmo[0] = ammo.Item2; Server.NextFrame(() =>
} {
catch (Exception ex) try
{ {
Logger.LogWarning("Error setting weapon properties: " + ex.Message); newWeapon.Clip1 = ammo.Item1;
} newWeapon.ReserveAmmo[0] = ammo.Item2;
}); }
} catch (Exception ex)
} {
}, TimerFlags.STOP_ON_MAPCHANGE); Logger.LogWarning("Error setting weapon properties: " + ex.Message);
} }
});
private void GivePlayerGloves(CCSPlayerController player) }
{ }, TimerFlags.STOP_ON_MAPCHANGE);
if (!Utility.IsPlayerValid(player) || (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE) return; }
CCSPlayerPawn? pawn = player.PlayerPawn.Value; private void GivePlayerGloves(CCSPlayerController player)
if (pawn == null || !pawn.IsValid) {
return; if (!Utility.IsPlayerValid(player) || (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE) return;
var model = pawn.CBodyComponent?.SceneNode?.GetSkeletonInstance()?.ModelState.ModelName ?? string.Empty; var pawn = player.PlayerPawn.Value;
if (!string.IsNullOrEmpty(model)) if (pawn == null || !pawn.IsValid)
{ return;
pawn.SetModel("characters/models/tm_jumpsuit/tm_jumpsuit_varianta.vmdl");
pawn.SetModel(model); var model = pawn.CBodyComponent?.SceneNode?.GetSkeletonInstance()?.ModelState.ModelName ?? string.Empty;
} if (!string.IsNullOrEmpty(model))
{
Instance.AddTimer(0.06f, () => pawn.SetModel("characters/models/tm_jumpsuit/tm_jumpsuit_varianta.vmdl");
{ pawn.SetModel(model);
CEconItemView item = pawn.EconGloves; }
try
{ Instance.AddTimer(0.06f, () =>
if (!player.IsValid) {
return; var item = pawn.EconGloves;
try
if (!player.PawnIsAlive) {
return; if (!player.IsValid)
return;
if (!g_playersGlove.TryGetValue(player.Slot, out var gloveInfo) || gloveInfo == 0) return;
if (!player.PawnIsAlive)
WeaponInfo weaponInfo = gPlayerWeaponsInfo[player.Slot][gloveInfo]; return;
item.ItemDefinitionIndex = gloveInfo; if (!g_playersGlove.TryGetValue(player.Slot, out var gloveInfo) || gloveInfo == 0) return;
item.ItemIDLow = 16384 & 0xFFFFFFFF;
item.ItemIDHigh = 16384; var weaponInfo = gPlayerWeaponsInfo[player.Slot][gloveInfo];
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weaponInfo.Paint); item.ItemDefinitionIndex = gloveInfo;
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture seed", weaponInfo.Seed); item.ItemIDLow = 16384 & 0xFFFFFFFF;
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture wear", weaponInfo.Wear); item.ItemIDHigh = 16384;
item.Initialized = true; CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle,
"set item texture prefab", weaponInfo.Paint);
SetBodygroup(pawn.Handle, "default_gloves", 1); CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle,
} "set item texture seed", weaponInfo.Seed);
catch (Exception) { } CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle,
}, TimerFlags.STOP_ON_MAPCHANGE); "set item texture wear", weaponInfo.Wear);
}
item.Initialized = true;
private static int GetRandomPaint(int defindex)
{ SetBodygroup(pawn.Handle, "default_gloves", 1);
if (skinsList.Count == 0) }
return 0; catch (Exception)
{
Random rnd = new Random(); }
}, TimerFlags.STOP_ON_MAPCHANGE);
// Filter weapons by the provided defindex }
var filteredWeapons = skinsList.Where(w => w["weapon_defindex"]?.ToString() == defindex.ToString()).ToList();
private static int GetRandomPaint(int defindex)
if (filteredWeapons.Count == 0) {
return 0; if (skinsList.Count == 0)
return 0;
var randomWeapon = filteredWeapons[rnd.Next(filteredWeapons.Count)];
var rnd = new Random();
return int.TryParse(randomWeapon["paint"]?.ToString(), out var paintValue) ? paintValue : 0;
} // Filter weapons by the provided defindex
var filteredWeapons = skinsList.Where(w => w["weapon_defindex"]?.ToString() == defindex.ToString()).ToList();
private static void SubclassChange(CBasePlayerWeapon weapon, ushort itemD)
{ if (filteredWeapons.Count == 0)
var subclassChangeFunc = VirtualFunction.Create<nint, string, int>( return 0;
GameData.GetSignature("ChangeSubclass")
); var randomWeapon = filteredWeapons[rnd.Next(filteredWeapons.Count)];
subclassChangeFunc(weapon.Handle, itemD.ToString()); return int.TryParse(randomWeapon["paint"]?.ToString(), out var paintValue) ? paintValue : 0;
} }
private static void UpdateWeaponMeshGroupMask(CBaseEntity weapon, bool isLegacy = false) private static void SubclassChange(CBasePlayerWeapon weapon, ushort itemD)
{ {
if (weapon.CBodyComponent?.SceneNode == null) return; var subclassChangeFunc = VirtualFunction.Create<nint, string, int>(
var skeleton = weapon.CBodyComponent.SceneNode.GetSkeletonInstance(); GameData.GetSignature("ChangeSubclass")
var value = (ulong)(isLegacy ? 2 : 1); );
if (skeleton.ModelState.MeshGroupMask != value) subclassChangeFunc(weapon.Handle, itemD.ToString());
{ }
skeleton.ModelState.MeshGroupMask = value;
} private static void UpdateWeaponMeshGroupMask(CBaseEntity weapon, bool isLegacy = false)
} {
if (weapon.CBodyComponent?.SceneNode == null) return;
private static void UpdatePlayerWeaponMeshGroupMask(CCSPlayerController player, CBasePlayerWeapon weapon, bool isLegacy) var skeleton = weapon.CBodyComponent.SceneNode.GetSkeletonInstance();
{ var value = (ulong)(isLegacy ? 2 : 1);
UpdateWeaponMeshGroupMask(weapon, isLegacy);
if (skeleton.ModelState.MeshGroupMask != value) skeleton.ModelState.MeshGroupMask = value;
var viewModel = GetPlayerViewModel(player); }
if (viewModel == null || viewModel.Weapon.Value == null ||
viewModel.Weapon.Value.Index != weapon.Index) return; private static void UpdatePlayerWeaponMeshGroupMask(CCSPlayerController player, CBasePlayerWeapon weapon,
UpdateWeaponMeshGroupMask(viewModel, isLegacy); bool isLegacy)
Utilities.SetStateChanged(viewModel, "CBaseEntity", "m_CBodyComponent"); {
} UpdateWeaponMeshGroupMask(weapon, isLegacy);
private static void GivePlayerAgent(CCSPlayerController player) var viewModel = GetPlayerViewModel(player);
{ if (viewModel == null || viewModel.Weapon.Value == null ||
if (!g_playersAgent.TryGetValue(player.Slot, out var value)) return; viewModel.Weapon.Value.Index != weapon.Index) return;
UpdateWeaponMeshGroupMask(viewModel, isLegacy);
var model = player.TeamNum == 3 ? value.CT : value.T; Utilities.SetStateChanged(viewModel, "CBaseEntity", "m_CBodyComponent");
if (string.IsNullOrEmpty(model)) return; }
if (player.PlayerPawn.Value == null) private static void GivePlayerAgent(CCSPlayerController player)
return; {
if (!g_playersAgent.TryGetValue(player.Slot, out var value)) return;
try
{ var model = player.TeamNum == 3 ? value.CT : value.T;
Server.NextFrame(() => if (string.IsNullOrEmpty(model)) return;
{
player.PlayerPawn.Value.SetModel( if (player.PlayerPawn.Value == null)
$"characters/models/{model}.vmdl" return;
);
}); try
} {
catch (Exception) Server.NextFrame(() =>
{ {
} player.PlayerPawn.Value.SetModel(
} $"characters/models/{model}.vmdl"
);
private static void GivePlayerMusicKit(CCSPlayerController player) });
{ }
if (!g_playersMusic.TryGetValue(player.Slot, out var value)) return; catch (Exception)
if (player.InventoryServices == null) return; {
}
player.InventoryServices.MusicID = value; }
Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInventoryServices");
player.MusicKitID = value; private static void GivePlayerMusicKit(CCSPlayerController player)
Utilities.SetStateChanged(player, "CCSPlayerController", "m_iMusicKitID"); {
} if (!g_playersMusic.TryGetValue(player.Slot, out var value)) return;
if (player.InventoryServices == null) return;
private void GiveOnItemPickup(CCSPlayerController player)
{ player.InventoryServices.MusicID = value;
var pawn = player.PlayerPawn.Value; Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInventoryServices");
if (pawn == null) return; player.MusicKitID = value;
Utilities.SetStateChanged(player, "CCSPlayerController", "m_iMusicKitID");
var myWeapons = pawn.WeaponServices?.MyWeapons; }
if (myWeapons == null) return;
foreach (var handle in myWeapons) private void GiveOnItemPickup(CCSPlayerController player)
{ {
var weapon = handle.Value; var pawn = player.PlayerPawn.Value;
if (weapon != null && weapon.DesignerName.Contains("knife")) if (pawn == null) return;
{
GivePlayerWeaponSkin(player, weapon); var myWeapons = pawn.WeaponServices?.MyWeapons;
} if (myWeapons == null) return;
} foreach (var handle in myWeapons)
} {
var weapon = handle.Value;
private void UpdatePlayerEconItemId(CEconItemView econItemView) if (weapon != null && weapon.DesignerName.Contains("knife")) GivePlayerWeaponSkin(player, weapon);
{ }
var itemId = _nextItemId++; }
econItemView.ItemID = itemId;
private void UpdatePlayerEconItemId(CEconItemView econItemView)
econItemView.ItemIDLow = (uint)itemId & 0xFFFFFFFF; {
econItemView.ItemIDHigh = (uint)itemId >> 32; var itemId = _nextItemId++;
} econItemView.ItemID = itemId;
private static CCSPlayerController? GetPlayerFromItemServices(CCSPlayer_ItemServices itemServices) econItemView.ItemIDLow = (uint)itemId & 0xFFFFFFFF;
{ econItemView.ItemIDHigh = (uint)itemId >> 32;
var pawn = itemServices.Pawn.Value; }
if (!pawn.IsValid || !pawn.Controller.IsValid || pawn.Controller.Value == null) return null;
var player = new CCSPlayerController(pawn.Controller.Value.Handle); private static CCSPlayerController? GetPlayerFromItemServices(CCSPlayer_ItemServices itemServices)
return !Utility.IsPlayerValid(player) ? null : player; {
} var pawn = itemServices.Pawn.Value;
if (!pawn.IsValid || !pawn.Controller.IsValid || pawn.Controller.Value == null) return null;
private static unsafe CBaseViewModel? GetPlayerViewModel(CCSPlayerController player) var player = new CCSPlayerController(pawn.Controller.Value.Handle);
{ return !Utility.IsPlayerValid(player) ? null : player;
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null; }
CCSPlayer_ViewModelServices viewModelServices = new(player.PlayerPawn.Value.ViewModelServices!.Handle);
var ptr = viewModelServices.Handle + Schema.GetSchemaOffset("CCSPlayer_ViewModelServices", "m_hViewModel"); private static CBaseViewModel? GetPlayerViewModel(CCSPlayerController player)
var references = MemoryMarshal.CreateSpan(ref ptr, 3); {
var viewModel = (CHandle<CBaseViewModel>)Activator.CreateInstance(typeof(CHandle<CBaseViewModel>), references[0])!; if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null;
return viewModel.Value == null ? null : viewModel.Value; CCSPlayer_ViewModelServices viewModelServices = new(player.PlayerPawn.Value.ViewModelServices!.Handle);
} var ptr = viewModelServices.Handle + Schema.GetSchemaOffset("CCSPlayer_ViewModelServices", "m_hViewModel");
var references = MemoryMarshal.CreateSpan(ref ptr, 3);
public static unsafe T[] GetFixedArray<T>(nint pointer, string @class, string member, int length) where T : CHandle<CBaseViewModel> var viewModel =
{ (CHandle<CBaseViewModel>)Activator.CreateInstance(typeof(CHandle<CBaseViewModel>), references[0])!;
var ptr = pointer + Schema.GetSchemaOffset(@class, member); return viewModel.Value == null ? null : viewModel.Value;
var references = MemoryMarshal.CreateSpan(ref ptr, length); }
var values = new T[length];
public static T[] GetFixedArray<T>(nint pointer, string @class, string member, int length)
for (var i = 0; i < length; i++) where T : CHandle<CBaseViewModel>
{ {
values[i] = (T)Activator.CreateInstance(typeof(T), references[i])!; var ptr = pointer + Schema.GetSchemaOffset(@class, member);
} var references = MemoryMarshal.CreateSpan(ref ptr, length);
var values = new T[length];
return values;
} for (var i = 0; i < length; i++) values[i] = (T)Activator.CreateInstance(typeof(T), references[i])!;
}
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; } = 0; public ushort Seed { get; set; } = 0;
public float Wear { get; set; } = 0f; public float Wear { get; set; } = 0f;
} public string? NameTag { get; set; }
public ushort Quality { get; set; }
public uint StatTrack { get; set; }
public bool StatTrackEnabled { get; set; }
}
} }

View File

@@ -83,8 +83,10 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
internal static ConcurrentDictionary<int, ushort> g_playersGlove = new(); internal static ConcurrentDictionary<int, ushort> g_playersGlove = new();
internal static ConcurrentDictionary<int, ushort> g_playersMusic = new(); internal static ConcurrentDictionary<int, ushort> g_playersMusic = new();
internal static ConcurrentDictionary<int, (string? CT, string? T)> g_playersAgent = new(); internal static ConcurrentDictionary<int, (string? CT, string? T)> g_playersAgent = new();
internal static ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>> gPlayerWeaponsInfo = new(); internal static ConcurrentDictionary<int, ConcurrentDictionary<ushort, WeaponInfo>> gPlayerWeaponsInfo = new();
internal static List<JObject> skinsList = new(); internal static ConcurrentDictionary<int, int> g_playersDatabaseIndex = new();
internal static List<JObject> skinsList = new();
internal static List<JObject> glovesList = new(); internal static List<JObject> glovesList = new();
internal static List<JObject> agentsList = new(); internal static List<JObject> agentsList = new();
internal static List<JObject> musicList = new(); internal static List<JObject> musicList = new();
@@ -196,14 +198,14 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
UserId = player.UserId, UserId = player.UserId,
Slot = player.Slot, Slot = player.Slot,
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]
}; };
_ = Task.Run(async () => _ = Task.Run(async () =>
{ {
if (weaponSync != null) await weaponSync.GetPlayerData(playerInfo); if (weaponSync != null) await weaponSync.GetPlayerDatabaseIndex(playerInfo);
}); });
} }
} }

View File

@@ -1,287 +1,322 @@
using Dapper; using System.Collections.Concurrent;
using Dapper;
using MySqlConnector; using MySqlConnector;
using System.Collections.Concurrent;
namespace WeaponPaints namespace WeaponPaints;
internal class WeaponSynchronization
{ {
internal class WeaponSynchronization private readonly WeaponPaintsConfig _config;
{ private readonly Database _database;
private readonly WeaponPaintsConfig _config;
private readonly Database _database;
internal WeaponSynchronization(Database database, WeaponPaintsConfig config) internal WeaponSynchronization(Database database, WeaponPaintsConfig config)
{ {
_database = database; _database = database;
_config = config; _config = config;
} }
internal async Task GetPlayerData(PlayerInfo? player) internal async Task GetPlayerDatabaseIndex(PlayerInfo playerInfo)
{ {
try if (playerInfo.SteamId == null || playerInfo.Slot == 0) return;
{ try
await using var connection = await _database.GetConnectionAsync(); {
await using var connection = await _database.GetConnectionAsync();
if (_config.Additional.KnifeEnabled) const string query = "SELECT `id` FROM `wp_users` WHERE `steamid` = @steamid";
GetKnifeFromDatabase(player, connection); var databaseIndex =
if (_config.Additional.GloveEnabled) await connection.QueryFirstOrDefaultAsync<int?>(query, new { steamid = playerInfo.SteamId });
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}");
}
}
private void GetKnifeFromDatabase(PlayerInfo? player, MySqlConnection connection) if (databaseIndex != null)
{ {
try WeaponPaints.g_playersDatabaseIndex[playerInfo.Slot] = (int)databaseIndex;
{ }
if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player?.SteamId)) else
return; {
const string insertQuery = "INSERT INTO `wp_users` (`steamid`) VALUES (@steamid)";
await connection.ExecuteAsync(insertQuery, new { steamid = playerInfo.SteamId });
Console.WriteLine("SQL Insert Query: " + insertQuery);
databaseIndex =
await connection.QueryFirstOrDefaultAsync<int?>(query, new { steamid = playerInfo.SteamId });
WeaponPaints.g_playersDatabaseIndex[playerInfo.Slot] = (int)databaseIndex;
}
const string query = "SELECT `knife` FROM `wp_player_knife` WHERE `steamid` = @steamid"; await GetPlayerData(playerInfo, connection);
var playerKnife = connection.QueryFirstOrDefault<string>(query, new { steamid = player.SteamId }); }
catch (Exception ex)
{
Utility.Log($"An error occurred in GetPlayerDatabaseIndex: {ex.Message}");
}
}
if (!string.IsNullOrEmpty(playerKnife)) internal async Task GetPlayerData(PlayerInfo? player, MySqlConnection connection)
{ {
WeaponPaints.g_playersKnife[player.Slot] = playerKnife; try
} {
} if (_config.Additional.KnifeEnabled)
catch (Exception ex) GetKnifeFromDatabase(player, connection);
{ if (_config.Additional.GloveEnabled)
Utility.Log($"An error occurred in GetKnifeFromDatabase: {ex.Message}"); 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}");
}
}
private void GetGloveFromDatabase(PlayerInfo? player, MySqlConnection connection) private void GetKnifeFromDatabase(PlayerInfo? player, MySqlConnection connection)
{ {
try try
{ {
if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player?.SteamId)) if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player?.SteamId.ToString()))
return; return;
const string query = "SELECT `weapon_defindex` FROM `wp_player_gloves` WHERE `steamid` = @steamid"; const string query = "SELECT `knife` FROM `wp_users_knife` WHERE `user_id` = @userId";
var gloveData = connection.QueryFirstOrDefault<ushort?>(query, new { steamid = player.SteamId }); var playerKnife = connection.QueryFirstOrDefault<string>(query,
new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot] });
if (gloveData != null) if (!string.IsNullOrEmpty(playerKnife)) WeaponPaints.g_playersKnife[player.Slot] = playerKnife;
{ }
WeaponPaints.g_playersGlove[player.Slot] = gloveData.Value; catch (Exception ex)
} {
} Utility.Log($"An error occurred in GetKnifeFromDatabase: {ex.Message}");
catch (Exception ex) }
{ }
Utility.Log($"An error occurred in GetGloveFromDatabase: {ex.Message}");
}
}
private void GetAgentFromDatabase(PlayerInfo? player, MySqlConnection connection) private void GetGloveFromDatabase(PlayerInfo? player, MySqlConnection connection)
{ {
try try
{ {
if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player?.SteamId)) if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player?.SteamId.ToString()))
return; return;
const string query = "SELECT `agent_ct`, `agent_t` FROM `wp_player_agents` WHERE `steamid` = @steamid"; const string query = "SELECT `weapon_defindex` FROM `wp_users_gloves` WHERE `userId` = @userId";
var agentData = connection.QueryFirstOrDefault<(string, string)>(query, new { steamid = player.SteamId }); var gloveData = connection.QueryFirstOrDefault<ushort?>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot] });
if (agentData == default) return; if (gloveData != null) WeaponPaints.g_playersGlove[player.Slot] = gloveData.Value;
var agentCT = agentData.Item1; }
var agentT = agentData.Item2; catch (Exception ex)
{
Utility.Log($"An error occurred in GetGloveFromDatabase: {ex.Message}");
}
}
if (!string.IsNullOrEmpty(agentCT) || !string.IsNullOrEmpty(agentT)) private void GetAgentFromDatabase(PlayerInfo? player, MySqlConnection connection)
{ {
WeaponPaints.g_playersAgent[player.Slot] = ( try
agentCT, {
agentT if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player?.SteamId.ToString()))
); return;
}
}
catch (Exception ex)
{
Utility.Log($"An error occurred in GetAgentFromDatabase: {ex.Message}");
}
}
private void GetWeaponPaintsFromDatabase(PlayerInfo? player, MySqlConnection connection) const string query = "SELECT `agent_ct`, `agent_t` FROM `wp_users_agents` WHERE `user_id` = @userId";
{ var agentData = connection.QueryFirstOrDefault<(string, string)>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot] });
try
{
if (!_config.Additional.SkinEnabled || player == null || string.IsNullOrEmpty(player.SteamId))
return;
var weaponInfos = new ConcurrentDictionary<int, WeaponInfo>(); if (agentData == default) return;
var agentCT = agentData.Item1;
var agentT = agentData.Item2;
const string query = "SELECT * FROM `wp_player_skins` WHERE `steamid` = @steamid"; if (!string.IsNullOrEmpty(agentCT) || !string.IsNullOrEmpty(agentT))
var playerSkins = connection.Query<dynamic>(query, new { steamid = player.SteamId }); WeaponPaints.g_playersAgent[player.Slot] = (
agentCT,
agentT
);
}
catch (Exception ex)
{
Utility.Log($"An error occurred in GetAgentFromDatabase: {ex.Message}");
}
}
foreach (var row in playerSkins) private void GetWeaponPaintsFromDatabase(PlayerInfo? player, MySqlConnection connection)
{ {
int weaponDefIndex = row?.weapon_defindex ?? 0; try
int weaponPaintId = row?.weapon_paint_id ?? 0; {
float weaponWear = row?.weapon_wear ?? 0f; if (!_config.Additional.SkinEnabled || player == null || string.IsNullOrEmpty(player.SteamId.ToString()))
int weaponSeed = row?.weapon_seed ?? 0; return;
WeaponInfo weaponInfo = new WeaponInfo var weaponInfos = new ConcurrentDictionary<ushort, WeaponInfo>();
{
Paint = weaponPaintId,
Seed = weaponSeed,
Wear = weaponWear
};
weaponInfos[weaponDefIndex] = weaponInfo;
}
WeaponPaints.gPlayerWeaponsInfo[player.Slot] = weaponInfos;
}
catch (Exception ex)
{
Utility.Log($"An error occurred in GetWeaponPaintsFromDatabase: {ex.Message}");
}
}
private void GetMusicFromDatabase(PlayerInfo? player, MySqlConnection connection)
{
try
{
if (!_config.Additional.MusicEnabled || string.IsNullOrEmpty(player?.SteamId))
return;
const string query = "SELECT `music_id` FROM `wp_player_music` WHERE `steamid` = @steamid";
var musicData = connection.QueryFirstOrDefault<ushort?>(query, new { steamid = player.SteamId });
if (musicData != null)
{
WeaponPaints.g_playersMusic[player.Slot] = musicData.Value;
}
}
catch (Exception ex)
{
Utility.Log($"An error occurred in GetMusicFromDatabase: {ex.Message}");
}
}
const string query = "SELECT `weapon`, `paint`, `wear`, `seed`, `nametag` FROM `wp_users_items` WHERE `user_id` = @userId";
var playerSkins = connection.Query<dynamic>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] });
internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife) foreach (var row in playerSkins)
{ {
if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player.SteamId) || string.IsNullOrEmpty(knife)) return; ushort weaponDefIndex = row?.weapon_defindex ?? 0;
ushort weaponPaintId = row?.weapon_paint_id ?? 0;
float weaponWear = row?.weapon_wear ?? 0f;
ushort weaponSeed = row?.weapon_seed ?? 0;
string weaponNameTag = row?.nametag ?? string.Empty;
const string query = "INSERT INTO `wp_player_knife` (`steamid`, `knife`) VALUES(@steamid, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife"; var weaponInfo = new WeaponInfo
{
try Paint = weaponPaintId,
{ Seed = weaponSeed,
await using var connection = await _database.GetConnectionAsync(); Wear = weaponWear,
await connection.ExecuteAsync(query, new { steamid = player.SteamId, newKnife = knife }); NameTag = weaponNameTag
} };
catch (Exception e)
{
Utility.Log($"Error syncing knife to database: {e.Message}");
}
}
internal async Task SyncGloveToDatabase(PlayerInfo player, int defindex) weaponInfos[weaponDefIndex] = weaponInfo;
{ }
if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player.SteamId)) return;
try WeaponPaints.gPlayerWeaponsInfo[player.Slot] = weaponInfos;
{ }
await using var connection = await _database.GetConnectionAsync(); catch (Exception ex)
const string query = "INSERT INTO `wp_player_gloves` (`steamid`, `weapon_defindex`) VALUES(@steamid, @weapon_defindex) ON DUPLICATE KEY UPDATE `weapon_defindex` = @weapon_defindex"; {
await connection.ExecuteAsync(query, new { steamid = player.SteamId, weapon_defindex = defindex }); Utility.Log($"An error occurred in GetWeaponPaintsFromDatabase: {ex.Message}");
} }
catch (Exception e) }
{
Utility.Log($"Error syncing glove to database: {e.Message}");
}
}
internal async Task SyncAgentToDatabase(PlayerInfo player) private void GetMusicFromDatabase(PlayerInfo? player, MySqlConnection connection)
{ {
if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player.SteamId)) return; try
{
if (!_config.Additional.MusicEnabled || string.IsNullOrEmpty(player?.SteamId.ToString()))
return;
const string query = """ const string query = "SELECT `music` FROM `wp_users_music` WHERE `user_id` = @userId";
INSERT INTO `wp_player_agents` (`steamid`, `agent_ct`, `agent_t`) var musicData = connection.QueryFirstOrDefault<ushort?>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot] });
VALUES(@steamid, @agent_ct, @agent_t)
ON DUPLICATE KEY UPDATE
`agent_ct` = @agent_ct,
`agent_t` = @agent_t
""";
try
{
await using var connection = await _database.GetConnectionAsync();
await connection.ExecuteAsync(query, new { steamid = player.SteamId, agent_ct = WeaponPaints.g_playersAgent[player.Slot].CT, agent_t = WeaponPaints.g_playersAgent[player.Slot].T }); if (musicData != null) WeaponPaints.g_playersMusic[player.Slot] = musicData.Value;
} }
catch (Exception e) catch (Exception ex)
{ {
Utility.Log($"Error syncing agents to database: {e.Message}"); Utility.Log($"An error occurred in GetMusicFromDatabase: {ex.Message}");
} }
} }
internal async Task SyncWeaponPaintsToDatabase(PlayerInfo player)
{
if (string.IsNullOrEmpty(player.SteamId) || !WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Slot, out var weaponsInfo))
return;
try internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife)
{ {
await using var connection = await _database.GetConnectionAsync(); if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player.SteamId.ToString()) ||
string.IsNullOrEmpty(knife)) return;
foreach (var (weaponDefIndex, weaponInfo) in weaponsInfo) const string query =
{ "INSERT INTO `wp_users_knife` (`user_id`, `knife`) VALUES(@userId, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife";
var paintId = weaponInfo.Paint;
var wear = weaponInfo.Wear;
var seed = weaponInfo.Seed;
const string queryCheckExistence = "SELECT COUNT(*) FROM `wp_player_skins` WHERE `steamid` = @steamid AND `weapon_defindex` = @weaponDefIndex"; try
{
await using var connection = await _database.GetConnectionAsync();
await connection.ExecuteAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], newKnife = knife });
}
catch (Exception e)
{
Utility.Log($"Error syncing knife to database: {e.Message}");
}
}
var existingRecordCount = await connection.ExecuteScalarAsync<int>(queryCheckExistence, new { steamid = player.SteamId, weaponDefIndex = weaponDefIndex }); internal async Task SyncGloveToDatabase(PlayerInfo player, int defindex)
{
if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player.SteamId.ToString())) return;
string query; try
object parameters; {
await using var connection = await _database.GetConnectionAsync();
const string query =
"INSERT INTO `wp_users_gloves` (`user_id`, `weapon_defindex`) VALUES(@userId, @weapon_defindex) ON DUPLICATE KEY UPDATE `weapon_defindex` = @weapon_defindex";
await connection.ExecuteAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], weapon_defindex = defindex });
}
catch (Exception e)
{
Utility.Log($"Error syncing glove to database: {e.Message}");
}
}
if (existingRecordCount > 0) internal async Task SyncAgentToDatabase(PlayerInfo player)
{ {
query = "UPDATE `wp_player_skins` SET `weapon_paint_id` = @paintId, `weapon_wear` = @wear, `weapon_seed` = @seed WHERE `steamid` = @steamid AND `weapon_defindex` = @weaponDefIndex"; if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player.SteamId.ToString())) return;
parameters = new { steamid = player.SteamId, weaponDefIndex = weaponDefIndex, paintId, wear, seed };
}
else
{
query = "INSERT INTO `wp_player_skins` (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`) " +
"VALUES (@steamid, @weaponDefIndex, @paintId, @wear, @seed)";
parameters = new { steamid = player.SteamId, weaponDefIndex = weaponDefIndex, paintId, wear, seed };
}
await connection.ExecuteAsync(query, parameters); const string query = """
} INSERT INTO `wp_users_agents` (`user_id`, `agent_ct`, `agent_t`)
} VALUES(@userId, @agent_ct, @agent_t)
catch (Exception e) ON DUPLICATE KEY UPDATE
{ `agent_ct` = @agent_ct,
Utility.Log($"Error syncing weapon paints to database: {e.Message}"); `agent_t` = @agent_t
} """;
} try
{
await using var connection = await _database.GetConnectionAsync();
internal async Task SyncMusicToDatabase(PlayerInfo player, ushort music) await connection.ExecuteAsync(query,
{ new
if (!_config.Additional.MusicEnabled || string.IsNullOrEmpty(player.SteamId)) return; {
userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], agent_ct = WeaponPaints.g_playersAgent[player.Slot].CT,
agent_t = WeaponPaints.g_playersAgent[player.Slot].T
});
}
catch (Exception e)
{
Utility.Log($"Error syncing agents to database: {e.Message}");
}
}
try internal async Task SyncWeaponPaintsToDatabase(PlayerInfo player)
{ {
await using var connection = await _database.GetConnectionAsync(); if (string.IsNullOrEmpty(player.SteamId.ToString()) ||
const string query = "INSERT INTO `wp_player_music` (`steamid`, `music_id`) VALUES(@steamid, @newMusic) ON DUPLICATE KEY UPDATE `music_id` = @newMusic"; !WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Slot, out var weaponsInfo))
await connection.ExecuteAsync(query, new { steamid = player.SteamId, newMusic = music }); return;
}
catch (Exception e) try
{ {
Utility.Log($"Error syncing music kit to database: {e.Message}"); await using var connection = await _database.GetConnectionAsync();
}
} foreach (var (weaponDefIndex, weaponInfo) in weaponsInfo)
} {
var paintId = weaponInfo.Paint;
var wear = weaponInfo.Wear;
var seed = weaponInfo.Seed;
const string queryCheckExistence =
"SELECT COUNT(*) FROM `wp_users_items` WHERE `user_id` = @userId AND `weapon_defindex` = @weaponDefIndex";
var existingRecordCount = await connection.ExecuteScalarAsync<int>(queryCheckExistence,
new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], weaponDefIndex });
string query;
object parameters;
if (existingRecordCount > 0)
{
query =
"UPDATE `wp_users_items` SET `weapon_paint_id` = @paintId, `weapon_wear` = @wear, `weapon_seed` = @seed WHERE `user_id` = @userId AND `weapon_defindex` = @weaponDefIndex";
parameters = new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], weaponDefIndex, paintId, wear, seed };
}
else
{
query =
"INSERT INTO `wp_users_items` (`user_id`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`) " +
"VALUES (@userId, @weaponDefIndex, @paintId, @wear, @seed)";
parameters = new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], weaponDefIndex, paintId, wear, seed };
}
await connection.ExecuteAsync(query, parameters);
}
}
catch (Exception e)
{
Utility.Log($"Error syncing weapon paints to database: {e.Message}");
}
}
internal async Task SyncMusicToDatabase(PlayerInfo player, ushort music)
{
if (!_config.Additional.MusicEnabled || string.IsNullOrEmpty(player.SteamId.ToString())) return;
try
{
await using var connection = await _database.GetConnectionAsync();
const string query =
"INSERT INTO `wp_users_music` (`user_id`, `music_id`) VALUES(@userId, @newMusic) ON DUPLICATE KEY UPDATE `music_id` = @newMusic";
await connection.ExecuteAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Slot], newMusic = music });
}
catch (Exception e)
{
Utility.Log($"Error syncing music kit to database: {e.Message}");
}
}
} }

View File

@@ -1,29 +1,66 @@
<?php <?php
/**
* Class DataBase
*
* This class handles database operations using PDO.
*/
class DataBase { class DataBase {
/**
* @var PDO The PDO instance for database connection.
*/
private $PDO; private $PDO;
/**
* Constructor method to initialize the database connection.
*/
public function __construct() { public function __construct() {
try { try {
$this->PDO = new PDO("mysql:host=".DB_HOST."; port=".DB_PORT."; dbname=".DB_NAME, DB_USER, DB_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); // Establish a connection to the database using PDO
$this->PDO = new PDO(
"mysql:host=".DB_HOST.";port=".DB_PORT.";dbname=".DB_NAME,
DB_USER,
DB_PASS
);
// Set the connection to use utf8 encoding
$this->PDO->exec("SET NAMES utf8");
} }
catch(PDOException $ex) catch(PDOException $ex) {
{ // Display error message if connection fails
echo "<div style='display: flex; flex-direction: column;align-items: center;justify-content: center;text-align: center;'><h2>Problem with database!</h2>"; echo "<div style='display: flex; flex-direction: column;align-items: center;justify-content: center;text-align: center;'><h2>Problem with database!</h2>";
die("<pre style='padding: 10px;text-wrap: balance; border: 2px solid #ed6bd3;background: #252525; color: #ed6bd3; width: 50%;'>" . $ex . "</pre>"); die("<pre style='padding: 10px;text-wrap: balance; border: 2px solid #ed6bd3;background: #252525; color: #ed6bd3; width: 50%;'>" . $ex . "</pre>");
} }
} }
public function select($query, $bindings = []) {
/**
* Perform a SELECT query on the database.
*
* @param string $query The SQL query to execute.
* @param array $bindings An associative array of parameters and their values.
* @return array|false Returns an array of rows as associative arrays or false if no results are found.
*/
public function select($query, $bindings = array()) {
// Prepare and execute the SQL query
$STH = $this->PDO->prepare($query); $STH = $this->PDO->prepare($query);
$STH->execute($bindings); $STH->execute($bindings);
// Fetch the results as associative arrays
$result = $STH->fetchAll(PDO::FETCH_ASSOC); $result = $STH->fetchAll(PDO::FETCH_ASSOC);
$result ??= false; if ($result === false) {
return $result; $result = array(); // Set $result to an empty array if no results found
}
return $result;
} }
public function query($query, $bindings = []){ /**
* Perform a non-query SQL statement on the database.
*
* @param string $query The SQL query to execute.
* @param array $bindings An associative array of parameters and their values.
* @return bool Returns true on success or false on failure.
*/
public function query($query, $bindings = array()) {
// Prepare and execute the SQL query
$STH = $this->PDO->prepare($query); $STH = $this->PDO->prepare($query);
return $STH->execute($bindings); return $STH->execute($bindings);
} }
}
}

71
website/class/header.php Normal file
View File

@@ -0,0 +1,71 @@
<?php
// Set security headers to enhance security
header("X-Frame-Options: SAMEORIGIN");
header("X-XSS-Protection: 1; mode=block");
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: no-referrer-when-downgrade");
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://code.jquery.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https://cdn.jsdelivr.net https://steamcommunity-a.akamaihd.net https://raw.githubusercontent.com;");
// Include necessary classes and files
require 'class/config.php';
require 'class/database.php';
require 'steamauth/steamauth.php';
require 'class/utils.php';
// Create a database instance
$db = new DataBase();
// Check if the user is logged in
if (isset($_SESSION['steamid'])) {
// Insert or update user's Steam ID in the database
$steamid = $_SESSION['steamid'];
$db->query("INSERT INTO `wp_users` (`steamid`) VALUES ('{$steamid}') ON DUPLICATE KEY UPDATE `updated_at` = CURRENT_TIMESTAMP");
// Get user's database index
$userInfoQuery = $db->select("SELECT `id` FROM `wp_users` WHERE `steamid` = :steamid", ["steamid" => $steamid]);
$_SESSION['userDbIndex'] = $userDbIndex = (int)$userInfoQuery[0]['id'];
// Get weapons and skins information
$weapons = UtilsClass::getWeaponsFromArray();
$skins = UtilsClass::skinsFromJson();
// Retrieve user's selected skins and knife
$querySelected = $db->select("SELECT `weapon`, `paint`, `wear`, `seed`, `nametag` FROM `wp_users_items` WHERE `user_id` = :user_id", ["user_id" => $userDbIndex]);
$selectedSkins = UtilsClass::getSelectedSkins($querySelected);
$selectedKnifeResult = $db->select("SELECT `knife` FROM `wp_users_knife` WHERE `user_id` = :user_id", ["user_id" => $userDbIndex]);
// Determine user's selected knife or set default knife
if (!empty($selectedKnifeResult)) {
$selectedKnife = $selectedKnifeResult[0]['knife'];
} else {
$selectedKnife = "weapon_knife";
}
$knifes = UtilsClass::getKnifeTypes();
// Handle form submission
if (isset($_POST['forma'])) {
$ex = explode("-", $_POST['forma']);
// Handle knife selection
if ($ex[0] == "knife") {
$db->query("INSERT INTO `wp_users_knife` (`user_id`, `knife`) VALUES(:user_id, :knife) ON DUPLICATE KEY UPDATE `knife` = :knife", ["user_id" => $userDbIndex, "knife" => $knifes[$ex[1]]['weapon_name']]);
} else {
// Handle skin selection
if (array_key_exists($ex[1], $skins[$ex[0]]) && isset($_POST['wear']) && $_POST['wear'] >= 0.00 && $_POST['wear'] <= 1.00 && isset($_POST['seed'])) {
$wear = floatval($_POST['wear']); // wear
$seed = intval($_POST['seed']); // seed
// Check if the skin is already selected and update or insert accordingly
if (array_key_exists($ex[0], $selectedSkins)) {
$db->query("UPDATE wp_users_items SET paint = :weapon_paint_id, wear = :weapon_wear, seed = :weapon_seed WHERE user_id = :user_id AND weapon = :weapon_defindex", ["user_id" => $userDbIndex, "weapon_defindex" => $ex[0], "weapon_paint_id" => $ex[1], "weapon_wear" => $wear, "weapon_seed" => $seed]);
} else {
$db->query("INSERT INTO wp_users_items (`user_id`, `weapon`, `paint`, `wear`, `seed`) VALUES (:user_id, :weapon_defindex, :weapon_paint_id, :weapon_wear, :weapon_seed)", ["user_id" => $userDbIndex, "weapon_defindex" => $ex[0], "weapon_paint_id" => $ex[1], "weapon_wear" => $wear, "weapon_seed" => $seed]);
}
}
}
// Redirect to the same page after form submission
header("Location: {$_SERVER['PHP_SELF']}");
}
}
?>

View File

@@ -1,99 +1,112 @@
<?php <?php
/**
* Class UtilsClass
*
* Provides utility methods for handling skin and weapon data.
*/
class UtilsClass class UtilsClass
{ {
public static function skinsFromJson(): array /**
* Retrieve skins data from the JSON file.
*
* @return array An associative array containing skin data.
*/
public static function skinsFromJson()
{ {
$skins = []; $skins = array();
$json = json_decode(file_get_contents(__DIR__ . "/../data/skins.json"), true); $jsonFilePath = __DIR__ . "/../data/skins.json";
foreach ($json as $skin) { if (file_exists($jsonFilePath) && is_readable($jsonFilePath)) {
$skins[(int) $skin['weapon_defindex']][(int) $skin['paint']] = [ $json = json_decode(file_get_contents($jsonFilePath), true);
'weapon_name' => $skin['weapon_name'],
'paint_name' => $skin['paint_name'], foreach ($json as $skin) {
'image_url' => $skin['image'], $skins[(int) $skin['weapon_defindex']][(int) $skin['paint']] = array(
]; 'weapon_name' => $skin['weapon_name'],
'paint_name' => $skin['paint_name'],
'image_url' => $skin['image'],
);
}
} else {
// Handle file not found or unreadable error
// You can throw an exception or log an error message
} }
return $skins; return $skins;
} }
/**
* Retrieve weapons data from the skin data array.
*
* @return array An associative array containing weapon data.
*/
public static function getWeaponsFromArray() public static function getWeaponsFromArray()
{ {
$weapons = []; $weapons = array();
$temp = self::skinsFromJson(); $skinsData = self::skinsFromJson();
foreach ($temp as $key => $value) { foreach ($skinsData as $key => $value) {
if (key_exists($key, $weapons)) $weapons[$key] = array(
continue;
$weapons[$key] = [
'weapon_name' => $value[0]['weapon_name'], 'weapon_name' => $value[0]['weapon_name'],
'paint_name' => $value[0]['paint_name'], 'paint_name' => $value[0]['paint_name'],
'image_url' => $value[0]['image_url'], 'image_url' => $value[0]['image_url'],
]; );
} }
return $weapons; return $weapons;
} }
/**
* Retrieve knife types from the weapon data array.
*
* @return array An associative array containing knife types data.
*/
public static function getKnifeTypes() public static function getKnifeTypes()
{ {
$knifes = []; $knifes = array();
$temp = self::getWeaponsFromArray(); $weaponsData = self::getWeaponsFromArray();
foreach ($temp as $key => $weapon) { $allowedKnifeKeys = array(
if ( 500, 503, 505, 506, 507, 508, 509, 512, 514, 515,
!in_array($key, [ 516, 517, 518, 519, 520, 521, 522, 523, 525
500, );
503,
505,
506,
507,
508,
509,
512,
514,
515,
516,
517,
518,
519,
520,
521,
522,
523,
525,
526
])
)
continue;
$knifes[$key] = [ foreach ($weaponsData as $key => $weapon) {
'weapon_name' => $weapon['weapon_name'], if (in_array($key, $allowedKnifeKeys)) {
'paint_name' => rtrim(explode("|", $weapon['paint_name'])[0]), $knifes[$key] = array(
'image_url' => $weapon['image_url'], 'weapon_name' => $weapon['weapon_name'],
]; 'paint_name' => rtrim(explode("|", $weapon['paint_name'])[0]),
$knifes[0] = [ 'image_url' => $weapon['image_url'],
'weapon_name' => "weapon_knife", );
'paint_name' => "Default knife", }
'image_url' => "https://raw.githubusercontent.com/Nereziel/cs2-WeaponPaints/main/website/img/skins/weapon_knife.png",
];
} }
// Add default knife
$knifes[0] = array(
'weapon_name' => "weapon_knife",
'paint_name' => "Default knife",
'image_url' => "https://raw.githubusercontent.com/Nereziel/cs2-WeaponPaints/main/website/img/skins/weapon_knife.png",
);
ksort($knifes); ksort($knifes);
return $knifes; return $knifes;
} }
public static function getSelectedSkins(array $temp) /**
* Retrieve selected skins data from the database result.
*
* @param array $temp An array containing the selected skins data.
* @return array An associative array containing selected skins data.
*/
public static function getSelectedSkins($temp)
{ {
$selected = []; $selected = array();
foreach ($temp as $weapon) { foreach ($temp as $weapon) {
$selected[$weapon['weapon_defindex']] = [ $selected[$weapon['weapon']] = array(
'weapon_paint_id' => $weapon['weapon_paint_id'], 'weapon_paint_id' => $weapon['paint'],
'weapon_seed' => $weapon['weapon_seed'], 'weapon_seed' => $weapon['seed'],
'weapon_wear' => $weapon['weapon_wear'], 'weapon_wear' => $weapon['wear'],
]; );
} }
return $selected; return $selected;

View File

@@ -8,7 +8,7 @@ $weapons = array (
"weapon_aug" => 8, "weapon_aug" => 8,
"weapon_awp" => 9, "weapon_awp" => 9,
"weapon_famas" => 10, "weapon_famas" => 10,
"weapon_g3sg1" => 11, "weapon_g3sg1" => 10,
"weapon_galilar" => 13, "weapon_galilar" => 13,
"weapon_m249" => 14, "weapon_m249" => 14,
"weapon_m4a1" => 16, "weapon_m4a1" => 16,
@@ -53,14 +53,7 @@ $weapons = array (
"weapon_knife_stiletto" => 522, "weapon_knife_stiletto" => 522,
"weapon_knife_widowmaker" => 523, "weapon_knife_widowmaker" => 523,
"weapon_knife_skeleton" => 525); "weapon_knife_skeleton" => 525);
$json = json_decode(file_get_contents('skins.json'));
$
$json = json_decode(file_get_contents('https://bymykel.github.io/CSGO-API/api/en/skins.json'));
die(var_dump($json));
echo "<pre>"; echo "<pre>";
foreach($json as $skin) foreach($json as $skin)
{ {

View File

@@ -1,261 +1,36 @@
<?php <?php
require_once 'class/config.php'; require 'class/header.php';
require_once 'class/database.php';
require_once 'steamauth/steamauth.php';
require_once 'class/utils.php';
$db = new DataBase();
if (isset($_SESSION['steamid'])) {
$steamid = $_SESSION['steamid'];
$weapons = UtilsClass::getWeaponsFromArray();
$skins = UtilsClass::skinsFromJson();
$querySelected = $db->select("SELECT `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed` FROM `wp_player_skins` WHERE `wp_player_skins`.`steamid` = :steamid", ["steamid" => $steamid]);
$selectedSkins = UtilsClass::getSelectedSkins($querySelected);
$selectedKnife = $db->select("SELECT * FROM `wp_player_knife` WHERE `wp_player_knife`.`steamid` = :steamid", ["steamid" => $steamid]);
$knifes = UtilsClass::getKnifeTypes();
if (isset($_POST['forma'])) {
$ex = explode("-", $_POST['forma']);
if ($ex[0] == "knife") {
$db->query("INSERT INTO `wp_player_knife` (`steamid`, `knife`) VALUES(:steamid, :knife) ON DUPLICATE KEY UPDATE `knife` = :knife", ["steamid" => $steamid, "knife" => $knifes[$ex[1]]['weapon_name']]);
} else {
if (array_key_exists($ex[1], $skins[$ex[0]]) && isset($_POST['wear']) && $_POST['wear'] >= 0.00 && $_POST['wear'] <= 1.00 && isset($_POST['seed'])) {
$wear = floatval($_POST['wear']); // wear
$seed = intval($_POST['seed']); // seed
if (array_key_exists($ex[0], $selectedSkins)) {
$db->query("UPDATE wp_player_skins SET weapon_paint_id = :weapon_paint_id, weapon_wear = :weapon_wear, weapon_seed = :weapon_seed WHERE steamid = :steamid AND weapon_defindex = :weapon_defindex", ["steamid" => $steamid, "weapon_defindex" => $ex[0], "weapon_paint_id" => $ex[1], "weapon_wear" => $wear, "weapon_seed" => $seed]);
} else {
$db->query("INSERT INTO wp_player_skins (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`) VALUES (:steamid, :weapon_defindex, :weapon_paint_id, :weapon_wear, :weapon_seed)", ["steamid" => $steamid, "weapon_defindex" => $ex[0], "weapon_paint_id" => $ex[1], "weapon_wear" => $wear, "weapon_seed" => $seed]);
}
}
}
header("Location: {$_SERVER['PHP_SELF']}");
}
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"<?php if(WEB_STYLE_DARK) echo 'data-bs-theme="dark"'?>> <html lang="en" <?php if (WEB_STYLE_DARK) echo 'data-bs-theme="dark"' ?>>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<title>CS2 Simple Weapon Paints</title> <title>CS2 Simple Weapon Paints</title>
</head> </head>
<body> <body>
<?php if (!isset($_SESSION['steamid'])) : ?>
<?php <div class='bg-primary'><h2>To choose weapon paints loadout, you need to <?php loginbutton("rectangle"); ?></h2></div>
if (!isset($_SESSION['steamid'])) { <?php else : ?>
echo "<div class='bg-primary'><h2>To choose weapon paints loadout, you need to "; <div class='bg-primary'><h2>Your current weapon skin loadout <a class='btn btn-danger' href='<?php echo $_SERVER['PHP_SELF']; ?>?logout'>Logout</a></h2> </div>
loginbutton("rectangle"); <div class='card-group mt-2'>
echo "</h2></div>"; <!-- Display user's selected knife -->
} else { <?php require_once 'view/display_knife.php'; ?>
echo "<div class='bg-primary'><h2>Your current weapon skin loadout <a class='btn btn-danger' href='{$_SERVER['PHP_SELF']}?logout'>Logout</a></h2> </div>"; <!-- Display user's selected skins for different weapons -->
echo "<div class='card-group mt-2'>"; <?php require_once 'view/display_weapons.php'; ?>
?> </div>
<?php endif; ?>
<div class="col-sm-2"> <!-- Footer section -->
<div class="card text-center mb-3 border border-primary"> <div class="container">
<div class="card-body"> <footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<?php <div class="col-md-4 d-flex align-items-center">
$actualKnife = $knifes[0]; <span class="mb-3 mb-md-0 text-body-secondary">© 2024 <a href="https://github.com/Nereziel/cs2-WeaponPaints">Nereziel/cs2-WeaponPaints</a></span>
if ($selectedKnife != null) </div>
{ </footer>
foreach ($knifes as $knife) { </div>
if ($selectedKnife[0]['knife'] == $knife['weapon_name']) {
$actualKnife = $knife;
break;
}
}
}
echo "<div class='card-header'>";
echo "<h6 class='card-title item-name'>Knife type</h6>";
echo "<h5 class='card-title item-name'>{$actualKnife["paint_name"]}</h5>";
echo "</div>";
echo "<img src='{$actualKnife["image_url"]}' class='skin-image'>";
?>
</div>
<div class="card-footer">
<form action="" method="POST">
<select name="forma" class="form-control select" onchange="this.form.submit()" class="SelectWeapon">
<option disabled>Select knife</option>
<?php
foreach ($knifes as $knifeKey => $knife) {
if ($selectedKnife[0]['knife'] == $knife['weapon_name'])
echo "<option selected value=\"knife-{$knifeKey}\">{$knife['paint_name']}</option>";
else
echo "<option value=\"knife-{$knifeKey}\">{$knife['paint_name']}</option>";
}
?>
</select>
</form>
</div>
</div>
</div>
<?php
foreach ($weapons as $defindex => $default) { ?>
<div class="col-sm-2">
<div class="card text-center mb-3">
<div class="card-body">
<?php
if (array_key_exists($defindex, $selectedSkins)) {
echo "<div class='card-header'>";
echo "<h5 class='card-title item-name'>{$skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]["paint_name"]}</h5>";
echo "</div>";
echo "<img src='{$skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]['image_url']}' class='skin-image'>";
} else {
echo "<div class='card-header'>";
echo "<h5 class='card-title item-name'>{$default["paint_name"]}</h5>";
echo "</div>";
echo "<img src='{$default["image_url"]}' class='skin-image'>";
}
?>
</div>
<div class="card-footer">
<form action="" method="POST">
<select name="forma" class="form-control select" onchange="this.form.submit()" class="SelectWeapon">
<option disabled>Select skin</option>
<?php
foreach ($skins[$defindex] as $paintKey => $paint) {
if (array_key_exists($defindex, $selectedSkins) && $selectedSkins[$defindex]['weapon_paint_id'] == $paintKey)
echo "<option selected value=\"{$defindex}-{$paintKey}\">{$paint['paint_name']}</option>";
else
echo "<option value=\"{$defindex}-{$paintKey}\">{$paint['paint_name']}</option>";
}
?>
</select>
<br></br>
<?php
$selectedSkinInfo = isset($selectedSkins[$defindex]) ? $selectedSkins[$defindex] : null;
$steamid = $_SESSION['steamid'];
if ($selectedSkinInfo) :
?>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#weaponModal<?php echo $defindex ?>">
Settings
</button>
<?php else : ?>
<button type="button" class="btn btn-primary" onclick="showSkinSelectionAlert()">
Settings
</button>
<script>
function showSkinSelectionAlert() {
alert("You need to select a skin first.");
}
</script>
<?php endif; ?>
</div>
<?php
// wear value
$selectedSkinInfo = isset($selectedSkins[$defindex]['weapon_paint_id']) ? $selectedSkins[$defindex] : null;
$queryWear = $selectedSkins[$defindex]['weapon_wear'] ?? 1.0;
$initialWearValue = isset($selectedSkinInfo['weapon_wear']) ? $selectedSkinInfo['weapon_wear'] : (isset($queryWear[0]['weapon_wear']) ? $queryWear[0] : 0.0);
// seed value
$querySeed = $selectedSkins[$defindex]['weapon_seed'] ?? 0;
$initialSeedValue = isset($selectedSkinInfo['weapon_seed']) ? $selectedSkinInfo['weapon_seed'] : 0;
?>
<div class="modal fade" id="weaponModal<?php echo $defindex ?>" tabindex="-1" role="dialog" aria-labelledby="weaponModalLabel<?php echo $defindex ?>" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class='card-title item-name'>
<?php
if (array_key_exists($defindex, $selectedSkins)) {
echo "{$skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]["paint_name"]} Settings";
} else {
echo "{$default["paint_name"]} Settings";
}
?>
</h5>
</div>
<div class="modal-body">
<div class="form-group">
<select class="form-select" id="wearSelect<?php echo $defindex ?>" name="wearSelect" onchange="updateWearValue<?php echo $defindex ?>(this.value)">
<option disabled>Select Wear</option>
<option value="0.00" <?php echo ($initialWearValue == 0.00) ? 'selected' : ''; ?>>Factory New</option>
<option value="0.07" <?php echo ($initialWearValue == 0.07) ? 'selected' : ''; ?>>Minimal Wear</option>
<option value="0.15" <?php echo ($initialWearValue == 0.15) ? 'selected' : ''; ?>>Field-Tested</option>
<option value="0.38" <?php echo ($initialWearValue == 0.38) ? 'selected' : ''; ?>>Well-Worn</option>
<option value="0.45" <?php echo ($initialWearValue == 0.45) ? 'selected' : ''; ?>>Battle-Scarred</option>
</select>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="wear">Wear:</label>
<input type="text" value="<?php echo $initialWearValue; ?>" class="form-control" id="wear<?php echo $defindex ?>" name="wear">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="seed">Seed:</label>
<input type="text" value="<?php echo $initialSeedValue; ?>" class="form-control" id="seed<?php echo $defindex ?>" name="seed" oninput="validateSeed(this)">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-danger">Use</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// wear
function updateWearValue<?php echo $defindex ?>(selectedValue) {
var wearInputElement = document.getElementById("wear<?php echo $defindex ?>");
wearInputElement.value = selectedValue;
}
function validateWear(inputElement) {
inputElement.value = inputElement.value.replace(/[^0-9]/g, '');
}
// seed
function validateSeed(input) {
// Check entered value
var inputValue = input.value.replace(/[^0-9]/g, ''); // Just get the numbers
if (inputValue === "") {
input.value = 0; // Set to 0 if empty or no numbers
} else {
var numericValue = parseInt(inputValue);
numericValue = Math.min(1000, Math.max(1, numericValue)); // Interval control
input.value = numericValue;
}
}
</script>
<?php } ?>
<?php } ?>
</div>
</div>
<div class="container">
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<div class="col-md-4 d-flex align-items-center">
<span class="mb-3 mb-md-0 text-body-secondary">© 2023 <a href="https://github.com/Nereziel/cs2-WeaponPaints">Nereziel/cs2-WeaponPaints</a></span>
</div>
</footer>
</div>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Benjamin Smith
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,9 +1,11 @@
<?php <?php
ob_start(); //ob_start();
session_start(); if (session_status() === PHP_SESSION_NONE) {
session_start();
}
function logoutbutton() { function logoutbutton() {
echo "<form action='' method='get'><button class='btn btn-secondary' name='logout' type='submit'>Logout</button></form>"; //logout button echo "<form><button class='btn btn-secondary' name='logout' type='submit'>Logout</button></form>"; //logout button
} }
function loginbutton($buttonstyle = "square") { function loginbutton($buttonstyle = "square") {

View File

@@ -7,7 +7,6 @@ if (empty($_SESSION['steam_uptodate']) or empty($_SESSION['steam_personaname']))
$_SESSION['steam_communityvisibilitystate'] = $content['response']['players'][0]['communityvisibilitystate']; $_SESSION['steam_communityvisibilitystate'] = $content['response']['players'][0]['communityvisibilitystate'];
$_SESSION['steam_profilestate'] = $content['response']['players'][0]['profilestate']; $_SESSION['steam_profilestate'] = $content['response']['players'][0]['profilestate'];
$_SESSION['steam_personaname'] = $content['response']['players'][0]['personaname']; $_SESSION['steam_personaname'] = $content['response']['players'][0]['personaname'];
$_SESSION['steam_lastlogoff'] = $content['response']['players'][0]['lastlogoff'];
$_SESSION['steam_profileurl'] = $content['response']['players'][0]['profileurl']; $_SESSION['steam_profileurl'] = $content['response']['players'][0]['profileurl'];
$_SESSION['steam_avatar'] = $content['response']['players'][0]['avatar']; $_SESSION['steam_avatar'] = $content['response']['players'][0]['avatar'];
$_SESSION['steam_avatarmedium'] = $content['response']['players'][0]['avatarmedium']; $_SESSION['steam_avatarmedium'] = $content['response']['players'][0]['avatarmedium'];
@@ -27,7 +26,6 @@ $steamprofile['steamid'] = $_SESSION['steam_steamid'];
$steamprofile['communityvisibilitystate'] = $_SESSION['steam_communityvisibilitystate']; $steamprofile['communityvisibilitystate'] = $_SESSION['steam_communityvisibilitystate'];
$steamprofile['profilestate'] = $_SESSION['steam_profilestate']; $steamprofile['profilestate'] = $_SESSION['steam_profilestate'];
$steamprofile['personaname'] = $_SESSION['steam_personaname']; $steamprofile['personaname'] = $_SESSION['steam_personaname'];
$steamprofile['lastlogoff'] = $_SESSION['steam_lastlogoff'];
$steamprofile['profileurl'] = $_SESSION['steam_profileurl']; $steamprofile['profileurl'] = $_SESSION['steam_profileurl'];
$steamprofile['avatar'] = $_SESSION['steam_avatar']; $steamprofile['avatar'] = $_SESSION['steam_avatar'];
$steamprofile['avatarmedium'] = $_SESSION['steam_avatarmedium']; $steamprofile['avatarmedium'] = $_SESSION['steam_avatarmedium'];

View File

@@ -1,16 +1,16 @@
.bg-primary { .bg-primary {
padding: 15px; padding: 15px;
} }
.card-title item-name { .card-title item-name{
//text-align:center; //text-align:center;
font-weight: bold; font-weight:bold;
} }
.skin-image { .skin-image {
margin: 0 auto; margin: 0 auto;
display: block; display:block;
text-align: center; text-align:center;
width: 50%; width:50%;
//border-bottom: solid 1px #eee; //border-bottom: solid 1px #eee;
} }

View File

@@ -0,0 +1,42 @@
<div class="col-sm-2">
<div class="card text-center mb-3 border border-primary">
<div class="card-body">
<?php
// Determine the user's selected knife
$actualGloves = $gloves[0];
if ($selectedGloves != null) {
foreach ($gloves as $glove) {
if ($selectedGloves == $glove['weapon_defindex']) {
$actualGloves = $glove;
break;
}
}
}
// Display user's selected knife information
echo "<div class='card-header'>";
echo "<h6 class='card-title item-name'>Knife type</h6>";
echo "<h5 class='card-title item-name'>{$actualGloves["paint_name"]}</h5>";
echo "</div>";
echo "<img src='{$actualGloves["image_url"]}' class='skin-image'>";
?>
</div>
<div class="card-footer">
<!-- Form for selecting user's knife -->
<form action="" method="POST">
<select name="forma" class="form-control select" onchange="this.form.submit()" class="SelectWeapon">
<option disabled>Select knife</option>
<?php
// Display options for selecting different knives
foreach ($gloves as $gloveKey => $glove) {
if ($selectedGlove == $glove['weapon_defindex'])
echo "<option selected value=\"knife-{$gloveKey}\">{$glove['paint_name']}</option>";
else
echo "<option value=\"knife-{$gloveKey}\">{$glove['paint_name']}</option>";
}
?>
</select>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,42 @@
<div class="col-sm-2">
<div class="card text-center mb-3 border border-primary">
<div class="card-body">
<?php
// Determine the user's selected knife
$actualKnife = $knifes[0];
if ($selectedKnife != null) {
foreach ($knifes as $knife) {
if ($selectedKnife == $knife['weapon_name']) {
$actualKnife = $knife;
break;
}
}
}
// Display user's selected knife information
echo "<div class='card-header'>";
echo "<h6 class='card-title item-name'>Knife type</h6>";
echo "<h5 class='card-title item-name'>{$actualKnife["paint_name"]}</h5>";
echo "</div>";
echo "<img src='{$actualKnife["image_url"]}' class='skin-image'>";
?>
</div>
<div class="card-footer">
<!-- Form for selecting user's knife -->
<form action="" method="POST">
<select name="forma" class="form-control select" onchange="this.form.submit()" class="SelectWeapon">
<option disabled>Select knife</option>
<?php
// Display options for selecting different knives
foreach ($knifes as $knifeKey => $knife) {
if ($selectedKnife == $knife['weapon_name'])
echo "<option selected value=\"knife-{$knifeKey}\">{$knife['paint_name']}</option>";
else
echo "<option value=\"knife-{$knifeKey}\">{$knife['paint_name']}</option>";
}
?>
</select>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,154 @@
<?php
// Display user's selected skins for different weapons
foreach ($weapons as $defindex => $default) {
?>
<div class="col-sm-2">
<div class="card text-center mb-3">
<div class="card-body">
<?php
// Determine the skin to display for the current weapon
if (array_key_exists($defindex, $selectedSkins)) {
echo "<div class='card-header'>";
echo "<h5 class='card-title item-name'>{$skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]["paint_name"]}</h5>";
echo "</div>";
echo "<img src='{$skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]['image_url']}' class='skin-image'>";
} else {
echo "<div class='card-header'>";
echo "<h5 class='card-title item-name'>{$default["paint_name"]}</h5>";
echo "</div>";
echo "<img src='{$default["image_url"]}' class='skin-image'>";
}
?>
</div>
<div class="card-footer">
<!-- Form for selecting user's skin and settings -->
<form action="" method="POST">
<select name="forma" class="form-control select" onchange="this.form.submit()" class="SelectWeapon">
<option disabled>Select skin</option>
<?php
// Display options for selecting different skins
foreach ($skins[$defindex] as $paintKey => $paint) {
if (array_key_exists($defindex, $selectedSkins) && $selectedSkins[$defindex]['weapon_paint_id'] == $paintKey)
echo "<option selected value=\"{$defindex}-{$paintKey}\">{$paint['paint_name']}</option>";
else
echo "<option value=\"{$defindex}-{$paintKey}\">{$paint['paint_name']}</option>";
}
?>
</select>
<br></br>
<?php
// Display settings button for selected skin
$selectedSkinInfo = isset($selectedSkins[$defindex]) ? $selectedSkins[$defindex] : null;
$steamid = $_SESSION['steamid'];
if ($selectedSkinInfo) :
?>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#weaponModal<?php echo $defindex ?>">
Settings
</button>
<?php else : ?>
<!-- Display message if skin is not selected -->
<button type="button" class="btn btn-primary" onclick="showSkinSelectionAlert()">
Settings
</button>
<script>
function showSkinSelectionAlert() {
alert("You need to select a skin first.");
}
</script>
<?php endif; ?>
</div>
<?php
// Display modal for adjusting wear and seed values
$selectedSkinInfo = isset($selectedSkins[$defindex]['weapon_paint_id']) ? $selectedSkins[$defindex] : null;
$queryWear = $selectedSkins[$defindex]['weapon_wear'] ?? 1.0;
$initialWearValue = isset($selectedSkinInfo['weapon_wear']) ? $selectedSkinInfo['weapon_wear'] : (isset($queryWear[0]['weapon_wear']) ? $queryWear[0] : 0.0);
$querySeed = $selectedSkins[$defindex]['weapon_seed'] ?? 0;
$initialSeedValue = isset($selectedSkinInfo['weapon_seed']) ? $selectedSkinInfo['weapon_seed'] : 0;
?>
<!-- Modal for adjusting wear and seed values -->
<div class="modal fade" id="weaponModal<?php echo $defindex ?>" tabindex="-1" role="dialog" aria-labelledby="weaponModalLabel<?php echo $defindex ?>" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<!-- Modal header -->
<div class="modal-header">
<h5 class='card-title item-name'>
<?php
if (array_key_exists($defindex, $selectedSkins)) {
echo "{$skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]["paint_name"]} Settings";
} else {
echo "{$default["paint_name"]} Settings";
}
?>
</h5>
</div>
<!-- Modal body -->
<div class="modal-body">
<!-- Form for adjusting wear and seed values -->
<div class="form-group">
<select class="form-select" id="wearSelect<?php echo $defindex ?>" name="wearSelect" onchange="updateWearValue<?php echo $defindex ?>(this.value)">
<option disabled>Select Wear</option>
<option value="0.00" <?php echo ($initialWearValue == 0.00) ? 'selected' : ''; ?>>Factory New</option>
<option value="0.07" <?php echo ($initialWearValue == 0.07) ? 'selected' : ''; ?>>Minimal Wear</option>
<option value="0.15" <?php echo ($initialWearValue == 0.15) ? 'selected' : ''; ?>>Field-Tested</option>
<option value="0.38" <?php echo ($initialWearValue == 0.38) ? 'selected' : ''; ?>>Well-Worn</option>
<option value="0.45" <?php echo ($initialWearValue == 0.45) ? 'selected' : ''; ?>>Battle-Scarred</option>
</select>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="wear">Wear:</label>
<input type="text" value="<?php echo $initialWearValue; ?>" class="form-control" id="wear<?php echo $defindex ?>" name="wear">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="seed">Seed:</label>
<input type="text" value="<?php echo $initialSeedValue; ?>" class="form-control" id="seed<?php echo $defindex ?>" name="seed" oninput="validateSeed(this)">
</div>
</div>
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-danger">Use</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- JavaScript functions for updating wear and seed values -->
<script>
// wear
function updateWearValue<?php echo $defindex ?>(selectedValue) {
var wearInputElement = document.getElementById("wear<?php echo $defindex ?>");
wearInputElement.value = selectedValue;
}
function validateWear(inputElement) {
inputElement.value = inputElement.value.replace(/[^0-9]/g, '');
}
// seed
function validateSeed(input) {
// Check entered value
var inputValue = input.value.replace(/[^0-9]/g, ''); // Just get the numbers
if (inputValue === "") {
input.value = 0; // Set to 0 if empty or no numbers
} else {
var numericValue = parseInt(inputValue);
numericValue = Math.min(1000, Math.max(1, numericValue)); // Interval control
input.value = numericValue;
}
}
</script>
<?php
}
?>