mirror of
https://github.com/Nereziel/cs2-WeaponPaints.git
synced 2026-02-19 02:51:50 +00:00
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:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
||||
.vs/
|
||||
bin/
|
||||
obj/
|
||||
.test/
|
||||
|
||||
48
Commands.cs
48
Commands.cs
@@ -8,7 +8,7 @@ namespace WeaponPaints
|
||||
{
|
||||
private void OnCommandRefresh(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
if (!Config.Additional.CommandWpEnabled || !Config.Additional.SkinEnabled || !g_bCommandsAllowed) return;
|
||||
if (!Config.AdditionalSetting.CommandWpEnabled || !Config.AdditionalSetting.SkinEnabled || !g_bCommandsAllowed) return;
|
||||
if (!Utility.IsPlayerValid(player)) return;
|
||||
if (player == null || player.Index <= 0) return;
|
||||
int playerIndex = (int)player!.Index;
|
||||
@@ -17,7 +17,7 @@ namespace WeaponPaints
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64,
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
@@ -30,7 +30,7 @@ namespace WeaponPaints
|
||||
commandsCooldown[(int)player.UserId] = DateTime.UtcNow.AddSeconds(Config.CmdRefreshCooldownSeconds);
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
if (Config.AdditionalSetting.KnifeEnabled)
|
||||
{
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.GetKnifeFromDatabase(playerInfo));
|
||||
@@ -51,7 +51,7 @@ namespace WeaponPaints
|
||||
|
||||
private void OnCommandWS(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
if (!Config.Additional.SkinEnabled) return;
|
||||
if (!Config.AdditionalSetting.SkinEnabled) return;
|
||||
if (!Utility.IsPlayerValid(player)) return;
|
||||
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_info_website"]))
|
||||
@@ -62,7 +62,7 @@ namespace WeaponPaints
|
||||
{
|
||||
player!.Print(Localizer["wp_info_refresh"]);
|
||||
}
|
||||
if (!Config.Additional.KnifeEnabled) return;
|
||||
if (!Config.AdditionalSetting.KnifeEnabled) return;
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_info_knife"]))
|
||||
{
|
||||
player!.Print(Localizer["wp_info_knife"]);
|
||||
@@ -71,19 +71,19 @@ namespace WeaponPaints
|
||||
|
||||
private void RegisterCommands()
|
||||
{
|
||||
AddCommand($"css_{Config.Additional.CommandSkin}", "Skins info", (player, info) =>
|
||||
AddCommand($"css_{Config.AdditionalSetting.CommandSkin}", "Skins info", (player, info) =>
|
||||
{
|
||||
if (!Utility.IsPlayerValid(player)) return;
|
||||
OnCommandWS(player, info);
|
||||
});
|
||||
AddCommand($"css_{Config.Additional.CommandRefresh}", "Skins refresh", (player, info) =>
|
||||
AddCommand($"css_{Config.AdditionalSetting.CommandRefresh}", "Skins refresh", (player, info) =>
|
||||
{
|
||||
if (!Utility.IsPlayerValid(player) || !g_bCommandsAllowed) return;
|
||||
OnCommandRefresh(player, info);
|
||||
});
|
||||
if (Config.Additional.CommandKillEnabled)
|
||||
if (Config.AdditionalSetting.CommandKillEnabled)
|
||||
{
|
||||
AddCommand($"css_{Config.Additional.CommandKill}", "kill yourself", (player, info) =>
|
||||
AddCommand($"css_{Config.AdditionalSetting.CommandKill}", "kill yourself", (player, info) =>
|
||||
{
|
||||
if (player == null || !Utility.IsPlayerValid(player) || player.PlayerPawn.Value == null || !player!.PlayerPawn.IsValid) return;
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace WeaponPaints
|
||||
|
||||
private void SetupKnifeMenu()
|
||||
{
|
||||
if (!Config.Additional.KnifeEnabled || !g_bCommandsAllowed) return;
|
||||
if (!Config.AdditionalSetting.KnifeEnabled || !g_bCommandsAllowed) return;
|
||||
|
||||
var knivesOnly = weaponList
|
||||
.Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet"))
|
||||
@@ -115,7 +115,7 @@ namespace WeaponPaints
|
||||
player!.Print(Localizer["wp_knife_menu_select", knifeName]);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_knife_menu_kill"]) && Config.Additional.CommandKillEnabled)
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_knife_menu_kill"]) && Config.AdditionalSetting.CommandKillEnabled)
|
||||
{
|
||||
player!.Print(Localizer["wp_knife_menu_kill"]);
|
||||
}
|
||||
@@ -124,7 +124,7 @@ namespace WeaponPaints
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64,
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
@@ -145,7 +145,7 @@ namespace WeaponPaints
|
||||
{
|
||||
giveItemMenu.AddMenuOption(knifePair.Value, handleGive);
|
||||
}
|
||||
AddCommand($"css_{Config.Additional.CommandKnife}", "Knife Menu", (player, info) =>
|
||||
AddCommand($"css_{Config.AdditionalSetting.CommandKnife}", "Knife Menu", (player, info) =>
|
||||
{
|
||||
if (!Utility.IsPlayerValid(player) || !g_bCommandsAllowed) return;
|
||||
|
||||
@@ -212,25 +212,25 @@ namespace WeaponPaints
|
||||
if (firstSkin != null &&
|
||||
firstSkin.TryGetValue("weapon_defindex", out var weaponDefIndexObj) &&
|
||||
weaponDefIndexObj != null &&
|
||||
int.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) &&
|
||||
int.TryParse(selectedPaintID, out var paintID))
|
||||
ushort.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) &&
|
||||
ushort.TryParse(selectedPaintID, out var paintID))
|
||||
{
|
||||
p!.Print(Localizer["wp_skin_menu_select", selectedSkin]);
|
||||
|
||||
if (!gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex))
|
||||
{
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex] = new WeaponInfo();
|
||||
}
|
||||
if (!gPlayerWeaponsInfo[playerIndex].TryGetValue(weaponDefIndex, out _))
|
||||
{
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex] = new WeaponInfo();
|
||||
}
|
||||
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Paint = paintID;
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.01f;
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Paint = paintID;
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.00001f;
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Seed = 0;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64,
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
@@ -238,7 +238,7 @@ namespace WeaponPaints
|
||||
if (!Config.GlobalShare)
|
||||
{
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.SyncWeaponPaintsToDatabase(playerInfo));
|
||||
Task.Run(async () => await weaponSync.SyncWeaponPaintToDatabase(playerInfo, weaponDefIndex));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -273,7 +273,7 @@ namespace WeaponPaints
|
||||
weaponSelectionMenu.AddMenuOption(weaponName, handleWeaponSelection);
|
||||
}
|
||||
// Command to open the weapon selection menu for players
|
||||
AddCommand($"css_{Config.Additional.CommandSkinSelection}", "Skins selection menu", (player, info) =>
|
||||
AddCommand($"css_{Config.AdditionalSetting.CommandSkinSelection}", "Skins selection menu", (player, info) =>
|
||||
{
|
||||
if (!Utility.IsPlayerValid(player)) return;
|
||||
|
||||
|
||||
22
Config.cs
22
Config.cs
@@ -3,9 +3,13 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace WeaponPaints
|
||||
{
|
||||
public class Additional
|
||||
public class AdditionalSetting
|
||||
{
|
||||
[JsonPropertyName("SkinVisibilityFix")]
|
||||
|
||||
[JsonPropertyName("UseMetamodAlwaysLegacyModel")]
|
||||
public bool UseMetamodAlwaysLegacyModel { get; set; } = false;
|
||||
|
||||
[JsonPropertyName("SkinVisibilityFix")]
|
||||
public bool SkinVisibilityFix { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("KnifeEnabled")]
|
||||
@@ -14,7 +18,13 @@ namespace WeaponPaints
|
||||
[JsonPropertyName("SkinEnabled")]
|
||||
public bool SkinEnabled { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("CommandWpEnabled")]
|
||||
[JsonPropertyName("MusicKitEnabled")]
|
||||
public bool MusicKitEnabled { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("NameTagEnabled")]
|
||||
public bool NameTagEnabled { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("CommandWpEnabled")]
|
||||
public bool CommandWpEnabled { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("CommandKillEnabled")]
|
||||
@@ -46,7 +56,7 @@ namespace WeaponPaints
|
||||
|
||||
public class WeaponPaintsConfig : BasePluginConfig
|
||||
{
|
||||
public override int Version { get; set; } = 4;
|
||||
public override int Version { get; set; } = 5;
|
||||
|
||||
[JsonPropertyName("DatabaseHost")]
|
||||
public string DatabaseHost { get; set; } = "";
|
||||
@@ -75,8 +85,8 @@ namespace WeaponPaints
|
||||
[JsonPropertyName("Website")]
|
||||
public string Website { get; set; } = "example.com/skins";
|
||||
|
||||
[JsonPropertyName("Additional")]
|
||||
public Additional Additional { get; set; } = new Additional();
|
||||
[JsonPropertyName("AdditionalSetting")]
|
||||
public AdditionalSetting AdditionalSetting { get; set; } = new AdditionalSetting();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
152
Events.cs
152
Events.cs
@@ -1,5 +1,7 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using System.Numerics;
|
||||
|
||||
namespace WeaponPaints
|
||||
{
|
||||
@@ -13,22 +15,18 @@ namespace WeaponPaints
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player.SteamID.ToString(),
|
||||
SteamId = player.SteamID,
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || weaponSync == null) return;
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || weaponSync == null) return;
|
||||
|
||||
Task.Run(async () =>
|
||||
Task.Run(async () =>
|
||||
{
|
||||
if (Config.Additional.SkinEnabled)
|
||||
await weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
await weaponSync.GetPlayerDatabaseIndex(playerInfo);
|
||||
});
|
||||
|
||||
//if (Config.Additional.KnifeEnabled && weaponSync != null)
|
||||
//_ = weaponSync.GetKnifeFromDatabase(playerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClientDisconnect(int playerSlot)
|
||||
{
|
||||
@@ -36,16 +34,19 @@ namespace WeaponPaints
|
||||
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.UserId == null) return;
|
||||
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
g_playersDatabaseIndex.TryRemove((int)player.Index, out _);
|
||||
if (Config.AdditionalSetting.KnifeEnabled)
|
||||
g_playersKnife.TryRemove((int)player.Index, out _);
|
||||
if (Config.Additional.SkinEnabled)
|
||||
if (Config.AdditionalSetting.SkinEnabled)
|
||||
{
|
||||
if (gPlayerWeaponsInfo.TryRemove((int)player.Index, out var innerDictionary))
|
||||
{
|
||||
innerDictionary.Clear();
|
||||
}
|
||||
}
|
||||
if (commandsCooldown.ContainsKey((int)player.UserId))
|
||||
if (Config.AdditionalSetting.MusicKitEnabled)
|
||||
g_playersMusicKit.TryRemove((int)player.Index, out _);
|
||||
if (commandsCooldown.ContainsKey((int)player.UserId))
|
||||
{
|
||||
commandsCooldown.Remove((int)player.UserId);
|
||||
}
|
||||
@@ -53,7 +54,7 @@ namespace WeaponPaints
|
||||
|
||||
private void OnEntityCreated(CEntityInstance entity)
|
||||
{
|
||||
if (!Config.Additional.SkinEnabled) return;
|
||||
if (!Config.AdditionalSetting.SkinEnabled) return;
|
||||
if (entity == null || !entity.IsValid || string.IsNullOrEmpty(entity.DesignerName)) return;
|
||||
string designerName = entity.DesignerName;
|
||||
if (!weaponList.ContainsKey(designerName)) return;
|
||||
@@ -93,42 +94,41 @@ namespace WeaponPaints
|
||||
if (player == null || !player.IsValid) return HookResult.Continue;
|
||||
|
||||
/*
|
||||
if (Config.Additional.SkinVisibilityFix)
|
||||
if (Config.AdditionalSetting.SkinVisibilityFix)
|
||||
AddTimer(0.2f, () => RefreshSkins(player));
|
||||
*/
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
private HookResult OnItemPickup(EventItemPickup @event, GameEventInfo info)
|
||||
{
|
||||
if (@event.Defindex == 42 || @event.Defindex == 59)
|
||||
{
|
||||
CCSPlayerController? player = @event.Userid;
|
||||
if (player == null || !player.IsValid || !g_knifePickupCount.ContainsKey((int)player.Index) || player.IsBot || !g_playersKnife.ContainsKey((int)player.Index))
|
||||
return HookResult.Continue;
|
||||
/*
|
||||
private HookResult OnItemPickup(EventItemPickup @event, GameEventInfo info)
|
||||
{
|
||||
if (@event.Defindex == 42 || @event.Defindex == 59)
|
||||
{
|
||||
CCSPlayerController? player = @event.Userid;
|
||||
if (player == null || !player.IsValid || !g_knifePickupCount.ContainsKey((int)player.Index) || player.IsBot || !g_playersKnife.ContainsKey((int)player.Index))
|
||||
return HookResult.Continue;
|
||||
|
||||
|
||||
if (g_knifePickupCount[(int)player.Index] >= 2) return HookResult.Continue;
|
||||
if (g_knifePickupCount[(int)player.Index] >= 2) return HookResult.Continue;
|
||||
|
||||
if (g_playersKnife.ContainsKey((int)player.Index)
|
||||
&&
|
||||
g_playersKnife[(int)player.Index] != "weapon_knife")
|
||||
{
|
||||
g_knifePickupCount[(int)player.Index]++;
|
||||
if (g_playersKnife.ContainsKey((int)player.Index)
|
||||
&&
|
||||
g_playersKnife[(int)player.Index] != "weapon_knife")
|
||||
{
|
||||
g_knifePickupCount[(int)player.Index]++;
|
||||
|
||||
RemovePlayerKnife(player, true);
|
||||
RemovePlayerKnife(player, true);
|
||||
|
||||
if (!PlayerHasKnife(player) && Config.Additional.GiveKnifeAfterRemove)
|
||||
AddTimer(0.3f, () => GiveKnifeToPlayer(player));
|
||||
}
|
||||
}
|
||||
return HookResult.Continue;
|
||||
}
|
||||
*/
|
||||
if (!PlayerHasKnife(player) && Config.AdditionalSetting.GiveKnifeAfterRemove)
|
||||
AddTimer(0.3f, () => GiveKnifeToPlayer(player));
|
||||
}
|
||||
}
|
||||
return HookResult.Continue;
|
||||
}
|
||||
*/
|
||||
|
||||
public HookResult OnPickup(CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay)
|
||||
public HookResult OnPickup(CEntityIOOutput output, string name, CEntityInstance activator, CEntityInstance caller, CVariant value, float delay)
|
||||
{
|
||||
CCSPlayerController? player = Utilities.GetEntityFromIndex<CCSPlayerPawn>((int)activator.Index).OriginalController.Value;
|
||||
|
||||
@@ -150,26 +150,25 @@ namespace WeaponPaints
|
||||
{
|
||||
g_knifePickupCount[(int)player.Index]++;
|
||||
player.RemoveItemByDesignerName(weapon.DesignerName);
|
||||
if (Config.Additional.GiveKnifeAfterRemove)
|
||||
if (Config.AdditionalSetting.GiveKnifeAfterRemove)
|
||||
AddTimer(0.2f, () => GiveKnifeToPlayer(player));
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
private void OnMapStart(string mapName)
|
||||
private void OnMapStart(string mapName)
|
||||
{
|
||||
if (!Config.Additional.KnifeEnabled) return;
|
||||
// TODO
|
||||
// needed for now
|
||||
AddTimer(2.0f, () =>
|
||||
if (!Config.AdditionalSetting.KnifeEnabled) return;
|
||||
// TODO
|
||||
// needed for now
|
||||
AddTimer(2.0f, () =>
|
||||
{
|
||||
|
||||
NativeAPI.IssueServerCommand("mp_t_default_melee \"\"");
|
||||
NativeAPI.IssueServerCommand("mp_ct_default_melee \"\"");
|
||||
NativeAPI.IssueServerCommand("mp_equipment_reset_rounds 0");
|
||||
|
||||
if (Config.GlobalShare)
|
||||
if (Config.GlobalShare)
|
||||
GlobalShareConnect();
|
||||
|
||||
weaponSync = new WeaponSynchronization(DatabaseConnectionString, Config, GlobalShareApi, GlobalShareServerId);
|
||||
@@ -178,26 +177,24 @@ namespace WeaponPaints
|
||||
g_hTimerCheckSkinsData = AddTimer(10.0f, () =>
|
||||
{
|
||||
List<CCSPlayerController> players = Utilities.GetPlayers();
|
||||
|
||||
foreach (CCSPlayerController player in players)
|
||||
HashSet<int> playerIndexes = new HashSet<int>(gPlayerWeaponsInfo.Keys);
|
||||
foreach (CCSPlayerController player in players)
|
||||
{
|
||||
if (player.IsBot || player.IsHLTV || player.SteamID.ToString() == "") continue;
|
||||
if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue;
|
||||
//if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue;
|
||||
if (playerIndexes.Contains((int)player.Index)) continue;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.SteamID.ToString(),
|
||||
SteamId = player?.SteamID,
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
|
||||
if (Config.Additional.SkinEnabled && weaponSync != null)
|
||||
_ = weaponSync.GetWeaponPaintsFromDatabase(playerInfo);
|
||||
if (Config.Additional.KnifeEnabled && weaponSync != null)
|
||||
_ = weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
}
|
||||
if (weaponSync != null)
|
||||
_ = weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
}
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE | CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT);
|
||||
}
|
||||
|
||||
@@ -211,22 +208,19 @@ namespace WeaponPaints
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.SteamID.ToString(),
|
||||
SteamId = player?.SteamID,
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
|
||||
if (!gPlayerWeaponsInfo.ContainsKey((int)player!.Index))
|
||||
if (!g_playersDatabaseIndex.ContainsKey((int)player!.Index))
|
||||
{
|
||||
Console.WriteLine($"[WeaponPaints] Retrying to retrieve player {player.PlayerName} skins");
|
||||
Task.Run(async () =>
|
||||
{
|
||||
if (Config.Additional.SkinEnabled)
|
||||
await weaponSync.GetWeaponPaintsFromDatabase(playerInfo);
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
await weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
});
|
||||
}
|
||||
await weaponSync.GetPlayerDatabaseIndex(playerInfo);
|
||||
});
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
@@ -239,7 +233,7 @@ namespace WeaponPaints
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
if (Config.Additional.KnifeEnabled && !PlayerHasKnife(player))
|
||||
if (Config.AdditionalSetting.KnifeEnabled && !PlayerHasKnife(player))
|
||||
{
|
||||
g_knifePickupCount[(int)player.Index] = 0;
|
||||
GiveKnifeToPlayer(player);
|
||||
@@ -247,7 +241,7 @@ namespace WeaponPaints
|
||||
}
|
||||
|
||||
/*
|
||||
if (Config.Additional.SkinVisibilityFix)
|
||||
if (Config.AdditionalSetting.SkinVisibilityFix)
|
||||
{
|
||||
AddTimer(0.3f, () => RefreshSkins(player));
|
||||
}
|
||||
@@ -298,11 +292,11 @@ namespace WeaponPaints
|
||||
if (
|
||||
viewModel.Value.CBodyComponent != null
|
||||
&& viewModel.Value.CBodyComponent.SceneNode != null
|
||||
)
|
||||
&& weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2
|
||||
)
|
||||
{
|
||||
var skeleton = GetSkeletonInstance(viewModel.Value.CBodyComponent.SceneNode);
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
|
||||
Utilities.SetStateChanged(viewModel.Value, "CBaseEntity", "m_CBodyComponent");
|
||||
}
|
||||
@@ -318,16 +312,18 @@ namespace WeaponPaints
|
||||
RegisterListener<Listeners.OnClientPutInServer>(OnClientPutInServer);
|
||||
RegisterListener<Listeners.OnClientDisconnect>(OnClientDisconnect);
|
||||
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<EventRoundStart>(OnRoundStart, HookMode.Pre);
|
||||
RegisterEventHandler<EventRoundEnd>(OnRoundEnd);
|
||||
RegisterEventHandler<EventItemPurchase>(OnEventItemPurchasePost);
|
||||
//RegisterEventHandler<EventItemPickup>(OnItemPickup);
|
||||
HookEntityOutput("weapon_knife", "OnPlayerPickup", OnPickup, HookMode.Pre);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* WORKAROUND FOR CLIENTS WITHOUT STEAMID ON AUTHORIZATION */
|
||||
@@ -338,15 +334,15 @@ namespace WeaponPaints
|
||||
if (player == null || !player.IsValid || !player.EntityIndex.HasValue || player.IsHLTV) return HookResult.Continue;
|
||||
|
||||
int playerIndex = (int)player.EntityIndex.Value.Value;
|
||||
if (Config.Additional.SkinEnabled && weaponSync != null)
|
||||
if (Config.AdditionalSetting.SkinEnabled && weaponSync != null)
|
||||
_ = weaponSync.GetWeaponPaintsFromDatabase(playerIndex);
|
||||
if (Config.Additional.KnifeEnabled && weaponSync != null)
|
||||
if (Config.AdditionalSetting.KnifeEnabled && weaponSync != null)
|
||||
_ = weaponSync.GetKnifeFromDatabase(playerIndex);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
if (Config.Additional.SkinEnabled && weaponSync != null)
|
||||
if (Config.Additional.KnifeEnabled && weaponSync != null)
|
||||
if (Config.AdditionalSetting.SkinEnabled && weaponSync != null)
|
||||
if (Config.AdditionalSetting.KnifeEnabled && weaponSync != null)
|
||||
});
|
||||
|
||||
return HookResult.Continue;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public int? UserId { get; set; }
|
||||
public string? SteamId { get; set; }
|
||||
public ulong? SteamId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? IpAddress { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
Utility.cs
24
Utility.cs
@@ -27,8 +27,7 @@ namespace WeaponPaints
|
||||
|
||||
return builder.ConnectionString;
|
||||
}
|
||||
|
||||
internal static async void CheckDatabaseTables()
|
||||
internal static async void CheckDatabaseTables()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -37,15 +36,22 @@ namespace WeaponPaints
|
||||
|
||||
using var transaction = await connection.BeginTransactionAsync();
|
||||
|
||||
try
|
||||
// Minimal version for MySQL 5.6.5
|
||||
string[] sqlCommands = new string[]
|
||||
{
|
||||
"CREATE TABLE IF NOT EXISTS `wp_users` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `steamid` BIGINT UNSIGNED NOT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `unique_steamid` (`steamid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
|
||||
"CREATE TABLE IF NOT EXISTS `wp_users_items` (`user_id` INT UNSIGNED NOT NULL, `weapon` SMALLINT UNSIGNED NOT NULL, `paint` SMALLINT UNSIGNED NOT NULL, `wear` FLOAT NOT NULL DEFAULT 0.00001, `seed` SMALLINT UNSIGNED NOT NULL DEFAULT 0, `nametag` VARCHAR(20) DEFAULT NULL, `stattrack` INT UNSIGNED NOT NULL DEFAULT 0, `stattrack_enabled` SMALLINT NOT NULL DEFAULT 0, `quality` SMALLINT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`user_id`,`weapon`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
|
||||
"CREATE TABLE IF NOT EXISTS `wp_users_knife` (`user_id` INT UNSIGNED NOT NULL, `knife` VARCHAR(32) DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
|
||||
"CREATE TABLE IF NOT EXISTS `wp_users_music` (`user_id` INT UNSIGNED NOT NULL, `music` SMALLINT UNSIGNED DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"
|
||||
};
|
||||
try
|
||||
{
|
||||
string createTable1 = "CREATE TABLE IF NOT EXISTS `wp_player_skins` (`steamid` varchar(64) NOT NULL, `weapon_defindex` int(6) NOT NULL, `weapon_paint_id` int(6) NOT NULL, `weapon_wear` float NOT NULL DEFAULT 0.000001, `weapon_seed` int(16) NOT NULL DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci";
|
||||
string createTable2 = "CREATE TABLE IF NOT EXISTS `wp_player_knife` (`steamid` varchar(64) NOT NULL, `knife` varchar(64) NOT NULL, UNIQUE (`steamid`)) ENGINE = InnoDB";
|
||||
foreach (string command in sqlCommands)
|
||||
{
|
||||
await connection.ExecuteAsync(command, transaction: transaction);
|
||||
}
|
||||
|
||||
await connection.ExecuteAsync(createTable1, transaction: transaction);
|
||||
await connection.ExecuteAsync(createTable2, transaction: transaction);
|
||||
|
||||
await transaction.CommitAsync();
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -19,15 +19,14 @@ namespace WeaponPaints
|
||||
|
||||
if (isKnife && !g_playersKnife.ContainsKey(playerIndex) || isKnife && g_playersKnife[playerIndex] == "weapon_knife") return;
|
||||
|
||||
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||
|
||||
ushort weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||
|
||||
if (isKnife)
|
||||
{
|
||||
weapon.AttributeManager.Item.EntityQuality = 3;
|
||||
}
|
||||
|
||||
if (_config.Additional.GiveRandomSkin &&
|
||||
if (_config.AdditionalSetting.GiveRandomSkin &&
|
||||
!gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex))
|
||||
{
|
||||
// Random skins
|
||||
@@ -36,13 +35,12 @@ namespace WeaponPaints
|
||||
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
|
||||
weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex);
|
||||
weapon.FallbackSeed = 0;
|
||||
weapon.FallbackWear = 0.000001f;
|
||||
weapon.FallbackWear = 0.00001f;
|
||||
if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null)
|
||||
{
|
||||
var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode);
|
||||
if (skeleton.ModelState.MeshGroupMask != 2)
|
||||
if (weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2)
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -58,25 +56,25 @@ namespace WeaponPaints
|
||||
weapon.FallbackSeed = weaponInfo.Seed;
|
||||
weapon.FallbackWear = weaponInfo.Wear;
|
||||
|
||||
if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null)
|
||||
if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null)
|
||||
{
|
||||
var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode);
|
||||
if (skeleton.ModelState.MeshGroupMask != 2)
|
||||
if (weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask != 2)
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
weapon.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal static void GiveKnifeToPlayer(CCSPlayerController? player)
|
||||
{
|
||||
if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return;
|
||||
if (!_config.AdditionalSetting.KnifeEnabled || player == null || !player.IsValid) return;
|
||||
|
||||
if (g_playersKnife.TryGetValue((int)player.Index, out var knife))
|
||||
{
|
||||
player.GiveNamedItem(knife);
|
||||
}
|
||||
else if (_config.Additional.GiveRandomKnife)
|
||||
else if (_config.AdditionalSetting.GiveRandomKnife)
|
||||
{
|
||||
var knifeTypes = weaponList.Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet")).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
|
||||
@@ -95,7 +93,7 @@ namespace WeaponPaints
|
||||
|
||||
internal static bool PlayerHasKnife(CCSPlayerController? player)
|
||||
{
|
||||
if (!_config.Additional.KnifeEnabled) return false;
|
||||
if (!_config.AdditionalSetting.KnifeEnabled) return false;
|
||||
|
||||
if (player == null || !player.IsValid || player.PlayerPawn == null || !player.PlayerPawn.IsValid || !player.PawnIsAlive)
|
||||
{
|
||||
@@ -177,7 +175,7 @@ namespace WeaponPaints
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
internal void RefreshSkins(CCSPlayerController? player)
|
||||
{
|
||||
return;
|
||||
@@ -187,8 +185,8 @@ namespace WeaponPaints
|
||||
AddTimer(0.25f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot2"));
|
||||
AddTimer(0.38f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot1"));
|
||||
}
|
||||
|
||||
internal void RefreshWeapons(CCSPlayerController? player)
|
||||
*/
|
||||
internal void RefreshWeapons(CCSPlayerController? player)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PawnIsAlive) return;
|
||||
if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null) return;
|
||||
@@ -213,13 +211,13 @@ namespace WeaponPaints
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!weaponDefindex.ContainsKey(weapon.Value.AttributeManager.Item.ItemDefinitionIndex)) continue;
|
||||
if (!WeaponDefindex.ContainsKey(weapon.Value.AttributeManager.Item.ItemDefinitionIndex)) continue;
|
||||
int clip1, reservedAmmo;
|
||||
|
||||
clip1 = weapon.Value.Clip1;
|
||||
reservedAmmo = weapon.Value.ReserveAmmo[0];
|
||||
|
||||
string weaponByDefindex = weaponDefindex[weapon.Value.AttributeManager.Item.ItemDefinitionIndex];
|
||||
string weaponByDefindex = WeaponDefindex[weapon.Value.AttributeManager.Item.ItemDefinitionIndex];
|
||||
player.RemoveItemByDesignerName(weapon.Value.DesignerName, true);
|
||||
CBasePlayerWeapon newWeapon = new(player.GiveNamedItem(weaponByDefindex));
|
||||
|
||||
@@ -246,7 +244,7 @@ namespace WeaponPaints
|
||||
}
|
||||
|
||||
/*
|
||||
if (Config.Additional.SkinVisibilityFix)
|
||||
if (Config.AdditionalSetting.SkinVisibilityFix)
|
||||
RefreshSkins(player);
|
||||
*/
|
||||
}
|
||||
@@ -321,13 +319,6 @@ namespace WeaponPaints
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static CSkeletonInstance GetSkeletonInstance(CGameSceneNode node)
|
||||
{
|
||||
Func<nint, nint> GetSkeletonInstance = VirtualFunction.Create<nint, nint>(node.Handle, 8);
|
||||
return new CSkeletonInstance(GetSkeletonInstance(node.Handle));
|
||||
}
|
||||
|
||||
private static unsafe CHandle<CBaseViewModel>[]? GetPlayerViewModels(CCSPlayerController player)
|
||||
{
|
||||
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null;
|
||||
@@ -348,6 +339,5 @@ namespace WeaponPaints
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,12 @@
|
||||
{
|
||||
public class WeaponInfo
|
||||
{
|
||||
public int Paint { get; set; }
|
||||
public int Seed { get; set; }
|
||||
public ushort Paint { get; set; }
|
||||
public ushort Seed { get; set; }
|
||||
public float Wear { get; set; }
|
||||
}
|
||||
public string? NameTag { get; set; }
|
||||
public ushort Quality { get; set; }
|
||||
public uint StatTrack { get; set; }
|
||||
public bool StatTrackEnabled { get; set; }
|
||||
}
|
||||
}
|
||||
180
WeaponPaints.cs
180
WeaponPaints.cs
@@ -9,7 +9,7 @@ using System.Collections.Concurrent;
|
||||
|
||||
namespace WeaponPaints;
|
||||
|
||||
[MinimumApiVersion(144)]
|
||||
[MinimumApiVersion(155)]
|
||||
public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig>
|
||||
{
|
||||
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_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 Dictionary<int, int> g_knifePickupCount = new Dictionary<int, int>();
|
||||
internal static ConcurrentDictionary<int, string> g_playersKnife = new ConcurrentDictionary<int, string>();
|
||||
internal static ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>> gPlayerWeaponsInfo = new ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>>();
|
||||
internal static ConcurrentDictionary<int, int> g_playersDatabaseIndex = new ConcurrentDictionary<int, int>();
|
||||
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 WeaponSynchronization? weaponSync;
|
||||
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>();
|
||||
private string DatabaseConnectionString = string.Empty;
|
||||
private CounterStrikeSharp.API.Modules.Timers.Timer? g_hTimerCheckSkinsData = null;
|
||||
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" }
|
||||
};
|
||||
|
||||
public WeaponPaintsConfig Config { get; set; } = new();
|
||||
public WeaponPaintsConfig Config { get; set; } = new();
|
||||
public override string ModuleAuthor => "Nereziel & daffyy";
|
||||
public override string ModuleDescription => "Skin and knife selector, standalone and web-based";
|
||||
public override string ModuleName => "WeaponPaints";
|
||||
public override string ModuleVersion => "1.4b";
|
||||
public override string ModuleVersion => "1.5.0";
|
||||
|
||||
public static WeaponPaintsConfig GetWeaponPaintsConfig()
|
||||
{
|
||||
@@ -169,23 +170,21 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
foreach (CCSPlayerController player in players)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.SteamID.ToString() == "") continue;
|
||||
if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
if (g_playersDatabaseIndex.ContainsKey((int)player.Index)) continue;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.SteamID.ToString(),
|
||||
SteamId = player?.SteamID,
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
|
||||
if (Config.Additional.SkinEnabled && weaponSync != null)
|
||||
_ = weaponSync.GetWeaponPaintsFromDatabase(playerInfo);
|
||||
if (Config.Additional.KnifeEnabled && weaponSync != null)
|
||||
_ = weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
|
||||
g_knifePickupCount[(int)player!.Index] = 0;
|
||||
if (weaponSync != null)
|
||||
{
|
||||
_ = weaponSync!.GetPlayerDatabaseIndex(playerInfo);
|
||||
}
|
||||
g_knifePickupCount[(int)player!.Index] = 0;
|
||||
}
|
||||
/*
|
||||
RegisterListeners();
|
||||
@@ -193,9 +192,9 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
*/
|
||||
}
|
||||
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
if (Config.AdditionalSetting.KnifeEnabled)
|
||||
SetupKnifeMenu();
|
||||
if (Config.Additional.SkinEnabled)
|
||||
if (Config.AdditionalSetting.SkinEnabled)
|
||||
SetupSkinsMenu();
|
||||
|
||||
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)
|
||||
{
|
||||
Logger.LogError("You need to setup Database credentials in config!");
|
||||
throw new Exception("[WeaponPaints] You need to setup Database credentials in config!");
|
||||
}
|
||||
// maybe more spam to get attention?
|
||||
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;
|
||||
_localizer = Localizer;
|
||||
|
||||
Utility.Config = config;
|
||||
/*
|
||||
* GLOBAL SHARE IS NOT SUPPORTED NOW!
|
||||
*/
|
||||
if (Config.GlobalShare)
|
||||
Config.GlobalShare = false;
|
||||
|
||||
Utility.Config = config;
|
||||
Utility.ShowAd(ModuleVersion);
|
||||
Task.Run(async () => await Utility.CheckVersion(ModuleVersion, Logger));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Dapper;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using Dapper;
|
||||
using MySqlConnector;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Concurrent;
|
||||
@@ -19,21 +21,64 @@ namespace WeaponPaints
|
||||
_globalShareApi = globalShareApi;
|
||||
_globalShareServerId = globalShareServerId;
|
||||
}
|
||||
|
||||
internal async Task GetKnifeFromDatabase(PlayerInfo player)
|
||||
internal async Task GetPlayerDatabaseIndex(PlayerInfo player)
|
||||
{
|
||||
if (!_config.Additional.KnifeEnabled) return;
|
||||
if (player.SteamId == null || player.Index == 0) return;
|
||||
|
||||
try
|
||||
{
|
||||
using (var connection = new MySqlConnection(_databaseConnectionString))
|
||||
{
|
||||
await connection.OpenAsync();
|
||||
|
||||
string query = "SELECT `id` FROM `wp_users` WHERE `steamid` = @steamid";
|
||||
int? databaseIndex = await connection.QueryFirstOrDefaultAsync<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;
|
||||
try
|
||||
{
|
||||
if (_config.GlobalShare)
|
||||
{
|
||||
var values = new Dictionary<string, string>
|
||||
{
|
||||
{ "server_id", _globalShareServerId.ToString() },
|
||||
{ "steamid", player.SteamId },
|
||||
{ "knife", "1" }
|
||||
};
|
||||
{
|
||||
{ "server_id", _globalShareServerId.ToString() },
|
||||
{ "steamid", player.SteamId.ToString()! },
|
||||
{ "knife", "1" }
|
||||
};
|
||||
|
||||
UriBuilder builder = new UriBuilder(_globalShareApi);
|
||||
builder.Query = string.Join("&", values.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}"));
|
||||
@@ -64,13 +109,17 @@ namespace WeaponPaints
|
||||
return;
|
||||
}
|
||||
|
||||
using (var connection = new MySqlConnection(_databaseConnectionString))
|
||||
if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var connection = new MySqlConnection(_databaseConnectionString))
|
||||
{
|
||||
await connection.OpenAsync();
|
||||
string query = "SELECT `knife` FROM `wp_player_knife` WHERE `steamid` = @steamid";
|
||||
string? PlayerKnife = await connection.QueryFirstOrDefaultAsync<string>(query, new { steamid = player.SteamId });
|
||||
|
||||
if (PlayerKnife != null)
|
||||
string query = "SELECT `knife` FROM `wp_users_knife` WHERE `user_id` = @userId";
|
||||
string? PlayerKnife = await connection.QueryFirstOrDefaultAsync<string>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] });
|
||||
if (PlayerKnife != null)
|
||||
{
|
||||
WeaponPaints.g_playersKnife[player.Index] = PlayerKnife;
|
||||
}
|
||||
@@ -83,30 +132,63 @@ namespace WeaponPaints
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utility.Log(e.Message);
|
||||
Utility.Log("GetKnifeFromDatabase: " + e.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
internal async Task GetMusicKitFromDatabase(PlayerInfo player)
|
||||
{
|
||||
if (!_config.AdditionalSetting.MusicKitEnabled) return;
|
||||
if (player.SteamId == null || player.Index == 0) return;
|
||||
if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
using (var connection = new MySqlConnection(_databaseConnectionString))
|
||||
{
|
||||
await connection.OpenAsync();
|
||||
string query = "SELECT `music` FROM `wp_users_music` WHERE `user_id` = @userId";
|
||||
int? PlayerMusitKit = await connection.QueryFirstOrDefaultAsync<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 (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out _))
|
||||
{
|
||||
WeaponPaints.gPlayerWeaponsInfo[player.Index] = new ConcurrentDictionary<int, WeaponInfo>();
|
||||
}
|
||||
try
|
||||
if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out _))
|
||||
{
|
||||
WeaponPaints.gPlayerWeaponsInfo[player.Index] = new ConcurrentDictionary<ushort, WeaponInfo>();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (_config.GlobalShare)
|
||||
{
|
||||
var values = new Dictionary<string, string>
|
||||
{
|
||||
{ "server_id", _globalShareServerId.ToString() },
|
||||
{ "steamid", player.SteamId },
|
||||
{ "skins", "1" }
|
||||
};
|
||||
{
|
||||
{ "server_id", _globalShareServerId.ToString() },
|
||||
{ "steamid", player.SteamId.ToString()! },
|
||||
{ "skins", "1" }
|
||||
};
|
||||
UriBuilder builder = new UriBuilder(_globalShareApi);
|
||||
builder.Query = string.Join("&", values.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}"));
|
||||
|
||||
@@ -124,19 +206,20 @@ namespace WeaponPaints
|
||||
{
|
||||
foreach (var weapon in jsonArray)
|
||||
{
|
||||
int? weaponDefIndex = weapon["weapon_defindex"]?.Value<int>();
|
||||
int? weaponPaintId = weapon["weapon_paint_id"]?.Value<int>();
|
||||
ushort? weaponDefIndex = weapon["weapon_defindex"]?.Value<ushort>();
|
||||
ushort? weaponPaintId = weapon["weapon_paint_id"]?.Value<ushort>();
|
||||
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
|
||||
{
|
||||
Paint = weaponPaintId.Value,
|
||||
Seed = weaponSeed.Value,
|
||||
Wear = weaponWear.Value
|
||||
};
|
||||
Wear = weaponWear.Value,
|
||||
NameTag = null
|
||||
};
|
||||
WeaponPaints.gPlayerWeaponsInfo[player.Index][weaponDefIndex.Value] = weaponInfo;
|
||||
}
|
||||
}
|
||||
@@ -150,28 +233,33 @@ namespace WeaponPaints
|
||||
}
|
||||
}
|
||||
|
||||
using (var connection = new MySqlConnection(_databaseConnectionString))
|
||||
if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var connection = new MySqlConnection(_databaseConnectionString))
|
||||
{
|
||||
await connection.OpenAsync();
|
||||
|
||||
string query = "SELECT * FROM `wp_player_skins` WHERE `steamid` = @steamid";
|
||||
IEnumerable<dynamic> PlayerSkins = await connection.QueryAsync<dynamic>(query, new { steamid = player.SteamId });
|
||||
|
||||
if (PlayerSkins != null && PlayerSkins.AsList().Count > 0)
|
||||
string query = "SELECT `weapon`, `paint`, `wear`, `seed`, `nametag` FROM `wp_users_items` WHERE `user_id` = @userId";
|
||||
IEnumerable<dynamic> PlayerSkins = await connection.QueryAsync<dynamic>(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index] });
|
||||
if (PlayerSkins != null && PlayerSkins.Any())
|
||||
{
|
||||
PlayerSkins.ToList().ForEach(row =>
|
||||
PlayerSkins.ToList().ForEach(row =>
|
||||
{
|
||||
int weaponDefIndex = row.weapon_defindex ?? default(int);
|
||||
int weaponPaintId = row.weapon_paint_id ?? default(int);
|
||||
float weaponWear = row.weapon_wear ?? default(float);
|
||||
int weaponSeed = row.weapon_seed ?? default(int);
|
||||
ushort weaponDefIndex = row.weapon ?? default(ushort);
|
||||
ushort weaponPaintId = row.paint ?? default(ushort);
|
||||
float weaponWear = row.wear ?? default(float);
|
||||
ushort weaponSeed = row.seed ?? default(ushort);
|
||||
string weaponNameTag = row.nametag;
|
||||
|
||||
WeaponInfo weaponInfo = new WeaponInfo
|
||||
WeaponInfo weaponInfo = new WeaponInfo
|
||||
{
|
||||
Paint = weaponPaintId,
|
||||
Seed = weaponSeed,
|
||||
Wear = weaponWear
|
||||
};
|
||||
Wear = weaponWear,
|
||||
NameTag = weaponNameTag
|
||||
};
|
||||
WeaponPaints.gPlayerWeaponsInfo[player.Index][weaponDefIndex] = weaponInfo;
|
||||
});
|
||||
}
|
||||
@@ -184,22 +272,24 @@ namespace WeaponPaints
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utility.Log(e.Message);
|
||||
Utility.Log("GetWeaponPaintsFromDatabase: " + e.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife)
|
||||
{
|
||||
if (!_config.Additional.KnifeEnabled) return;
|
||||
try
|
||||
if (!_config.AdditionalSetting.KnifeEnabled) return;
|
||||
if(player == null || player.Index <= 0) return;
|
||||
try
|
||||
{
|
||||
if (player.SteamId == null || player.Index == 0) return;
|
||||
if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out _))
|
||||
return;
|
||||
|
||||
using var connection = new MySqlConnection(_databaseConnectionString);
|
||||
using var connection = new MySqlConnection(_databaseConnectionString);
|
||||
await connection.OpenAsync();
|
||||
string query = "INSERT INTO `wp_player_knife` (`steamid`, `knife`) VALUES(@steamid, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife";
|
||||
await connection.ExecuteAsync(query, new { steamid = player.SteamId, newKnife = knife });
|
||||
string query = "INSERT INTO `wp_users_knife` (`user_id`, `knife`) VALUES(@userId, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife";
|
||||
await connection.ExecuteAsync(query, new { userId = WeaponPaints.g_playersDatabaseIndex[player.Index], newKnife = knife });
|
||||
await connection.CloseAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -208,42 +298,34 @@ namespace WeaponPaints
|
||||
return;
|
||||
}
|
||||
}
|
||||
internal async Task SyncWeaponPaintsToDatabase(PlayerInfo player)
|
||||
internal async Task SyncWeaponPaintToDatabase(PlayerInfo player, ushort weaponDefIndex)
|
||||
{
|
||||
if (player == null || player.Index <= 0 || player.SteamId == null) return;
|
||||
if (!_config.AdditionalSetting.SkinEnabled) return;
|
||||
if (player == null || player.Index <= 0) return;
|
||||
|
||||
using var connection = new MySqlConnection(_databaseConnectionString);
|
||||
await connection.OpenAsync();
|
||||
if (!WeaponPaints.g_playersDatabaseIndex.TryGetValue(player.Index, out var playerDatabaseIndex))
|
||||
return;
|
||||
|
||||
if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out var playerSavedWeapons))
|
||||
return;
|
||||
|
||||
if (!playerSavedWeapons.TryGetValue(weaponDefIndex, out var weaponInfo))
|
||||
return;
|
||||
|
||||
if (!WeaponPaints.gPlayerWeaponsInfo.ContainsKey(player.Index))
|
||||
return;
|
||||
|
||||
foreach (var weaponInfoPair in WeaponPaints.gPlayerWeaponsInfo[player.Index])
|
||||
{
|
||||
int weaponDefIndex = weaponInfoPair.Key;
|
||||
WeaponInfo weaponInfo = weaponInfoPair.Value;
|
||||
|
||||
int paintId = weaponInfo.Paint;
|
||||
float wear = weaponInfo.Wear;
|
||||
int seed = weaponInfo.Seed;
|
||||
|
||||
string updateSql = "UPDATE `wp_player_skins` SET `weapon_paint_id` = @paintId, " +
|
||||
"`weapon_wear` = @wear, `weapon_seed` = @seed WHERE `steamid` = @steamid " +
|
||||
"AND `weapon_defindex` = @weaponDefIndex";
|
||||
|
||||
var updateParams = new { paintId, wear, seed, steamid = player.SteamId, weaponDefIndex };
|
||||
int rowsAffected = await connection.ExecuteAsync(updateSql, updateParams);
|
||||
|
||||
if (rowsAffected == 0)
|
||||
{
|
||||
string insertSql = "INSERT INTO `wp_player_skins` (`steamid`, `weapon_defindex`, " +
|
||||
"`weapon_paint_id`, `weapon_wear`, `weapon_seed`) " +
|
||||
"VALUES (@steamid, @weaponDefIndex, @paintId, @wear, @seed)";
|
||||
|
||||
await connection.ExecuteAsync(insertSql, updateParams);
|
||||
}
|
||||
}
|
||||
await connection.CloseAsync();
|
||||
using var connection = new MySqlConnection(_databaseConnectionString);
|
||||
string querySql = @"
|
||||
INSERT INTO `wp_users_items`
|
||||
(`user_id`, `weapon`, `paint`, `wear`, `seed`)
|
||||
VALUES
|
||||
(@userId, @weaponDefIndex, @paintId, @wear, @seed)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
paint = @paintId,
|
||||
wear = @wear,
|
||||
seed = @seed";
|
||||
var queryParams = new { weaponDefIndex, userId = playerDatabaseIndex, paintId = weaponInfo.Paint, wear = weaponInfo.Wear, seed = weaponInfo.Seed };
|
||||
await connection.ExecuteAsync(querySql, queryParams);
|
||||
await connection.CloseAsync();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user