Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebc932e47c | ||
|
|
e258ed8c92 | ||
|
|
e44af369bb | ||
|
|
47055ad6f7 | ||
|
|
d9166253b3 | ||
|
|
4e90506645 | ||
|
|
bd93936fab | ||
|
|
63403dfc8e | ||
|
|
b24a2bd04e | ||
|
|
dbc652a68c | ||
|
|
a59ce8f1a5 | ||
|
|
baaa47d837 | ||
|
|
7dcfea3e17 | ||
|
|
4eab8f0a87 | ||
|
|
236c79c4b9 | ||
|
|
83084452df | ||
|
|
43e7a3183e | ||
|
|
60c592aa54 | ||
|
|
2568f263d9 | ||
|
|
14e285d44f | ||
|
|
97b8840ac4 | ||
|
|
f820c7d251 | ||
|
|
6e5d595c0f | ||
|
|
71d57eb3ad | ||
|
|
620b067991 | ||
|
|
89c425c170 | ||
|
|
c744f2898b | ||
|
|
d04bc0879a | ||
|
|
4417b093dd | ||
|
|
3f8533ab94 | ||
|
|
55905ccc33 | ||
|
|
24fcfa0222 | ||
|
|
cd059c6bfb | ||
|
|
e338bebaec | ||
|
|
efd7f5dbef | ||
|
|
6bd002cdec | ||
|
|
3a1adf8d4a | ||
|
|
7c3fa6469b | ||
|
|
52962518fe | ||
|
|
7e12b89a9e | ||
|
|
ae56b18a3c | ||
|
|
c907911cd1 | ||
|
|
1aa486cd7d | ||
|
|
5e62c7c597 | ||
|
|
819ac6233c | ||
|
|
ed24eb0dfc | ||
|
|
1a9f7ad108 | ||
|
|
6f1a29bb39 | ||
|
|
9e64cdcd43 | ||
|
|
da86756092 | ||
|
|
22880070cd | ||
|
|
208cbe1aef | ||
|
|
c0cf9210dc | ||
|
|
5f61254b4e | ||
|
|
6cd1bb3bf5 | ||
|
|
4f94b831c2 | ||
|
|
969d40b970 | ||
|
|
0cd36a7877 | ||
|
|
a3306b5f8f | ||
|
|
379c2f797c | ||
|
|
7f41607d54 | ||
|
|
fc42190701 | ||
|
|
928c1e1466 | ||
|
|
78649f5dcf | ||
|
|
4e72f10326 | ||
|
|
3ddbf7e11e | ||
|
|
ee770fd8c2 | ||
|
|
72c5df53b5 | ||
|
|
d0ed0f4c0b | ||
|
|
643beaad46 | ||
|
|
6d44e582be | ||
|
|
a8cf33d404 | ||
|
|
1c026c018e | ||
|
|
4a410fd0d8 | ||
|
|
bb08e88371 |
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
|
||||
.vs/
|
||||
bin/
|
||||
obj/
|
||||
website/getskins.php
|
||||
|
||||
139
Commands.cs
@@ -10,8 +10,9 @@ namespace WeaponPaints
|
||||
{
|
||||
if (!Config.Additional.CommandWpEnabled || !Config.Additional.SkinEnabled || !g_bCommandsAllowed) return;
|
||||
if (!Utility.IsPlayerValid(player)) return;
|
||||
string temp = "";
|
||||
if (player == null || player.Index <= 0) return;
|
||||
|
||||
if (player == null || !player.IsValid || player.UserId == null || player.IsBot) return;
|
||||
|
||||
int playerIndex = (int)player!.Index;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
@@ -23,30 +24,35 @@ namespace WeaponPaints
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
|
||||
if (playerIndex != 0 && DateTime.UtcNow >= commandCooldown[playerIndex].AddSeconds(Config.CmdRefreshCooldownSeconds))
|
||||
{
|
||||
commandCooldown[playerIndex] = DateTime.UtcNow;
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
{
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.GetKnifeFromDatabase(playerInfo));
|
||||
if (player == null || !player.IsValid || player.UserId == null || player.IsBot) return;
|
||||
|
||||
RefreshWeapons(player);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Config.Messages.SuccessRefreshCommand))
|
||||
{
|
||||
temp = $" {Config.Prefix} {Config.Messages.SuccessRefreshCommand}";
|
||||
player!.PrintToChat(Utility.ReplaceTags(temp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Config.Messages.CooldownRefreshCommand))
|
||||
try
|
||||
{
|
||||
temp = $" {Config.Prefix} {Config.Messages.CooldownRefreshCommand}";
|
||||
player!.PrintToChat(Utility.ReplaceTags(temp));
|
||||
if (!commandsCooldown.TryGetValue((int)player.UserId, out DateTime cooldownEndTime) ||
|
||||
DateTime.UtcNow >= (commandsCooldown.TryGetValue((int)player.UserId, out cooldownEndTime) ? cooldownEndTime : DateTime.UtcNow))
|
||||
{
|
||||
commandsCooldown[(int)player.UserId] = DateTime.UtcNow.AddSeconds(Config.CmdRefreshCooldownSeconds);
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
{
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.GetKnifeFromDatabase(playerInfo));
|
||||
|
||||
RefreshWeapons(player);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_command_refresh_done"]))
|
||||
{
|
||||
player!.Print(Localizer["wp_command_refresh_done"]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_command_cooldown"]))
|
||||
{
|
||||
player!.Print(Localizer["wp_command_cooldown"]);
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
private void OnCommandWS(CCSPlayerController? player, CommandInfo command)
|
||||
@@ -54,22 +60,18 @@ namespace WeaponPaints
|
||||
if (!Config.Additional.SkinEnabled) return;
|
||||
if (!Utility.IsPlayerValid(player)) return;
|
||||
|
||||
string temp;
|
||||
if (!string.IsNullOrEmpty(Config.Messages.WebsiteMessageCommand))
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_info_website"]))
|
||||
{
|
||||
temp = $" {Config.Prefix} {Config.Messages.WebsiteMessageCommand}";
|
||||
player!.PrintToChat(Utility.ReplaceTags(temp));
|
||||
player!.Print(Localizer["wp_info_website", Config.Website]);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Config.Messages.SynchronizeMessageCommand))
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_info_refresh"]))
|
||||
{
|
||||
temp = $" {Config.Prefix} {Config.Messages.SynchronizeMessageCommand}";
|
||||
player!.PrintToChat(Utility.ReplaceTags(temp));
|
||||
player!.Print(Localizer["wp_info_refresh"]);
|
||||
}
|
||||
if (!Config.Additional.KnifeEnabled) return;
|
||||
if (!string.IsNullOrEmpty(Config.Messages.KnifeMessageCommand))
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_info_knife"]))
|
||||
{
|
||||
temp = $" {Config.Prefix} {Config.Messages.KnifeMessageCommand}";
|
||||
player!.PrintToChat(Utility.ReplaceTags(temp));
|
||||
player!.Print(Localizer["wp_info_knife"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +106,7 @@ namespace WeaponPaints
|
||||
.Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet"))
|
||||
.ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
|
||||
var giveItemMenu = new ChatMenu(Utility.ReplaceTags($" {Config.Messages.KnifeMenuTitle}"));
|
||||
var giveItemMenu = new ChatMenu(Localizer["wp_knife_menu_title"]);
|
||||
var handleGive = (CCSPlayerController? player, ChatMenuOption option) =>
|
||||
{
|
||||
if (Utility.IsPlayerValid(player))
|
||||
@@ -114,18 +116,14 @@ namespace WeaponPaints
|
||||
var knifeKey = knivesOnly.FirstOrDefault(x => x.Value == knifeName).Key;
|
||||
if (!string.IsNullOrEmpty(knifeKey))
|
||||
{
|
||||
string temp = "";
|
||||
|
||||
if (!string.IsNullOrEmpty(Config.Messages.ChosenKnifeMenu))
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_knife_menu_select"]))
|
||||
{
|
||||
temp = $" {Config.Prefix} {Config.Messages.ChosenKnifeMenu}".Replace("{KNIFE}", knifeName);
|
||||
player!.PrintToChat(Utility.ReplaceTags(temp));
|
||||
player!.Print(Localizer["wp_knife_menu_select", knifeName]);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Config.Messages.ChosenKnifeMenuKill) && Config.Additional.CommandKillEnabled)
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_knife_menu_kill"]) && Config.Additional.CommandKillEnabled)
|
||||
{
|
||||
temp = $" {Config.Prefix} {Config.Messages.ChosenKnifeMenuKill}";
|
||||
player!.PrintToChat(Utility.ReplaceTags(temp));
|
||||
player!.Print(Localizer["wp_knife_menu_kill"]);
|
||||
}
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
@@ -156,18 +154,19 @@ namespace WeaponPaints
|
||||
AddCommand($"css_{Config.Additional.CommandKnife}", "Knife Menu", (player, info) =>
|
||||
{
|
||||
if (!Utility.IsPlayerValid(player) || !g_bCommandsAllowed) return;
|
||||
int playerIndex = (int)player!.Index;
|
||||
|
||||
if (commandCooldown != null && DateTime.UtcNow >= commandCooldown[playerIndex].AddSeconds(Config.CmdRefreshCooldownSeconds))
|
||||
if (player == null || player.UserId == null) return;
|
||||
|
||||
if (!commandsCooldown.TryGetValue((int)player.UserId, out DateTime cooldownEndTime) ||
|
||||
DateTime.UtcNow >= (commandsCooldown.TryGetValue((int)player.UserId, out cooldownEndTime) ? cooldownEndTime : DateTime.UtcNow))
|
||||
{
|
||||
commandCooldown[playerIndex] = DateTime.UtcNow;
|
||||
ChatMenus.OpenMenu(player, giveItemMenu);
|
||||
commandsCooldown[(int)player.UserId] = DateTime.UtcNow.AddSeconds(Config.CmdRefreshCooldownSeconds);
|
||||
MenuManager.OpenChatMenu(player, giveItemMenu);
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Config.Messages.CooldownRefreshCommand))
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_command_cooldown"]))
|
||||
{
|
||||
string temp = $" {Config.Prefix} {Config.Messages.CooldownRefreshCommand}";
|
||||
player.PrintToChat(Utility.ReplaceTags(temp));
|
||||
player!.Print(Localizer["wp_command_cooldown"]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -175,7 +174,7 @@ namespace WeaponPaints
|
||||
private void SetupSkinsMenu()
|
||||
{
|
||||
var classNamesByWeapon = weaponList.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);
|
||||
var weaponSelectionMenu = new ChatMenu(Utility.ReplaceTags($" {Config.Messages.WeaponMenuTitle}"));
|
||||
var weaponSelectionMenu = new ChatMenu(Localizer["wp_skin_menu_weapon_title"]);
|
||||
|
||||
// Function to handle skin selection for a specific weapon
|
||||
var handleWeaponSelection = (CCSPlayerController? player, ChatMenuOption option) =>
|
||||
@@ -193,7 +192,7 @@ namespace WeaponPaints
|
||||
weaponName?.ToString() == selectedWeaponClassname
|
||||
)?.ToList();
|
||||
|
||||
var skinSubMenu = new ChatMenu(Utility.ReplaceTags($" {Config.Messages.SkinMenuTitle}").Replace("{WEAPON}", selectedWeapon));
|
||||
var skinSubMenu = new ChatMenu(Localizer["wp_skin_menu_skin_title", selectedWeapon]);
|
||||
|
||||
// Function to handle skin selection for the chosen weapon
|
||||
var handleSkinSelection = (CCSPlayerController? p, ChatMenuOption opt) =>
|
||||
@@ -222,8 +221,7 @@ namespace WeaponPaints
|
||||
int.TryParse(weaponDefIndexObj.ToString(), out var weaponDefIndex) &&
|
||||
int.TryParse(selectedPaintID, out var paintID))
|
||||
{
|
||||
string temp = $" {Config.Prefix} {Config.Messages.ChosenSkinMenu}".Replace("{SKIN}", selectedSkin);
|
||||
p.PrintToChat(Utility.ReplaceTags(temp));
|
||||
p!.Print(Localizer["wp_skin_menu_select", selectedSkin]);
|
||||
|
||||
if (!gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex))
|
||||
{
|
||||
@@ -231,16 +229,22 @@ namespace WeaponPaints
|
||||
}
|
||||
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Paint = paintID;
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.0f;
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Wear = 0.01f;
|
||||
gPlayerWeaponsInfo[playerIndex][weaponDefIndex].Seed = 0;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
|
||||
if (!Config.GlobalShare)
|
||||
{
|
||||
if (weaponSync == null) return;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await weaponSync.SyncWeaponPaintsToDatabase(p);
|
||||
});
|
||||
if (weaponSync != null)
|
||||
Task.Run(async () => await weaponSync.SyncWeaponPaintsToDatabase(playerInfo));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -264,7 +268,7 @@ namespace WeaponPaints
|
||||
}
|
||||
|
||||
// Open the submenu for skin selection of the chosen weapon
|
||||
ChatMenus.OpenMenu(player, skinSubMenu);
|
||||
MenuManager.OpenChatMenu(player, skinSubMenu);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -278,18 +282,19 @@ namespace WeaponPaints
|
||||
AddCommand($"css_{Config.Additional.CommandSkinSelection}", "Skins selection menu", (player, info) =>
|
||||
{
|
||||
if (!Utility.IsPlayerValid(player)) return;
|
||||
int playerIndex = (int)player!.Index;
|
||||
|
||||
if (commandCooldown != null && DateTime.UtcNow >= commandCooldown[playerIndex].AddSeconds(Config.CmdRefreshCooldownSeconds) && playerIndex > 0 && playerIndex < commandCooldown.Length)
|
||||
if (player == null || player.UserId == null) return;
|
||||
|
||||
if (!commandsCooldown.TryGetValue((int)player.UserId, out DateTime cooldownEndTime) ||
|
||||
DateTime.UtcNow >= (commandsCooldown.TryGetValue((int)player.UserId, out cooldownEndTime) ? cooldownEndTime : DateTime.UtcNow))
|
||||
{
|
||||
commandCooldown[playerIndex] = DateTime.UtcNow;
|
||||
ChatMenus.OpenMenu(player, weaponSelectionMenu);
|
||||
commandsCooldown[(int)player.UserId] = DateTime.UtcNow.AddSeconds(Config.CmdRefreshCooldownSeconds);
|
||||
MenuManager.OpenChatMenu(player, weaponSelectionMenu);
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Config.Messages.CooldownRefreshCommand))
|
||||
if (!string.IsNullOrEmpty(Localizer["wp_command_cooldown"]))
|
||||
{
|
||||
string temp = $"{Config.Prefix} {Config.Messages.CooldownRefreshCommand}";
|
||||
player.PrintToChat(Utility.ReplaceTags(temp));
|
||||
player!.Print(Localizer["wp_command_cooldown"]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
31
Config.cs
@@ -3,32 +3,6 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace WeaponPaints
|
||||
{
|
||||
public class Messages
|
||||
{
|
||||
[JsonPropertyName("WebsiteMessageCommand")]
|
||||
public string WebsiteMessageCommand { get; set; } = "Visit {WEBSITE} where you can change skins.";
|
||||
[JsonPropertyName("SynchronizeMessageCommand")]
|
||||
public string SynchronizeMessageCommand { get; set; } = "Type !wp to synchronize chosen skins.";
|
||||
[JsonPropertyName("KnifeMessageCommand")]
|
||||
public string KnifeMessageCommand { get; set; } = "Type !knife to open knife menu.";
|
||||
[JsonPropertyName("CooldownRefreshCommand")]
|
||||
public string CooldownRefreshCommand { get; set; } = "You can't refresh weapon paints right now.";
|
||||
[JsonPropertyName("SuccessRefreshCommand")]
|
||||
public string SuccessRefreshCommand { get; set; } = "Refreshing weapon paints.";
|
||||
[JsonPropertyName("ChosenKnifeMenu")]
|
||||
public string ChosenKnifeMenu { get; set; } = "You have chosen {KNIFE} as your knife.";
|
||||
[JsonPropertyName("ChosenSkinMenu")]
|
||||
public string ChosenSkinMenu { get; set; } = "You have chosen {SKIN} as your skin.";
|
||||
[JsonPropertyName("ChosenKnifeMenuKill")]
|
||||
public string ChosenKnifeMenuKill { get; set; } = "To correctly apply skin for knife, you need to type !kill.";
|
||||
[JsonPropertyName("KnifeMenuTitle")]
|
||||
public string KnifeMenuTitle { get; set; } = "Knife Menu.";
|
||||
[JsonPropertyName("WeaponMenuTitle")]
|
||||
public string WeaponMenuTitle { get; set; } = "Weapon Menu.";
|
||||
[JsonPropertyName("SkinMenuTitle")]
|
||||
public string SkinMenuTitle { get; set; } = "Select skin for {WEAPON}";
|
||||
}
|
||||
|
||||
public class Additional
|
||||
{
|
||||
[JsonPropertyName("SkinVisibilityFix")]
|
||||
@@ -66,6 +40,8 @@ namespace WeaponPaints
|
||||
|
||||
[JsonPropertyName("GiveRandomSkin")]
|
||||
public bool GiveRandomSkin { get; set; } = false;
|
||||
[JsonPropertyName("GiveKnifeAfterRemove")]
|
||||
public bool GiveKnifeAfterRemove { get; set; } = false;
|
||||
}
|
||||
|
||||
public class WeaponPaintsConfig : BasePluginConfig
|
||||
@@ -99,9 +75,6 @@ namespace WeaponPaints
|
||||
[JsonPropertyName("Website")]
|
||||
public string Website { get; set; } = "example.com/skins";
|
||||
|
||||
[JsonPropertyName("Messages")]
|
||||
public Messages Messages { get; set; } = new Messages();
|
||||
|
||||
[JsonPropertyName("Additional")]
|
||||
public Additional Additional { get; set; } = new Additional();
|
||||
}
|
||||
|
||||
179
Events.cs
@@ -1,54 +1,62 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
|
||||
namespace WeaponPaints
|
||||
{
|
||||
public partial class WeaponPaints
|
||||
{
|
||||
private void OnClientAuthorized(int playerSlot, SteamID steamID)
|
||||
private void OnClientPutInServer(int playerSlot)
|
||||
{
|
||||
int playerIndex = playerSlot + 1;
|
||||
CCSPlayerController? player = Utilities.GetPlayerFromSlot(playerSlot);
|
||||
|
||||
CCSPlayerController? player = Utilities.GetPlayerFromIndex(playerIndex);
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || weaponSync == null || player.Connected == PlayerConnectedState.PlayerDisconnecting) return;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
SteamId = player.SteamID.ToString(),
|
||||
Name = player.PlayerName,
|
||||
IpAddress = player.IpAddress?.Split(":")[0]
|
||||
};
|
||||
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || weaponSync == null) return;
|
||||
|
||||
Task.Run(async () =>
|
||||
if (!gPlayerWeaponsInfo.ContainsKey((int)player.Index))
|
||||
{
|
||||
if (Config.Additional.SkinEnabled)
|
||||
await weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
});
|
||||
|
||||
//if (Config.Additional.KnifeEnabled && weaponSync != null)
|
||||
//_ = weaponSync.GetKnifeFromDatabase(playerIndex);
|
||||
Task.Run(async () =>
|
||||
{
|
||||
if (Config.Additional.SkinEnabled)
|
||||
await weaponSync.GetWeaponPaintsFromDatabase(playerInfo);
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
await weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClientDisconnect(int playerSlot)
|
||||
{
|
||||
CCSPlayerController player = Utilities.GetPlayerFromSlot(playerSlot);
|
||||
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV) return;
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.UserId == null) return;
|
||||
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
g_playersKnife.Remove((int)player.Index);
|
||||
g_playersKnife.TryRemove((int)player.Index, out _);
|
||||
if (Config.Additional.SkinEnabled)
|
||||
gPlayerWeaponsInfo.Remove((int)player.Index);
|
||||
{
|
||||
if (gPlayerWeaponsInfo.TryRemove((int)player.Index, out var innerDictionary))
|
||||
{
|
||||
innerDictionary.Clear();
|
||||
}
|
||||
}
|
||||
if (commandsCooldown.ContainsKey((int)player.UserId))
|
||||
{
|
||||
commandsCooldown.Remove((int)player.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEntitySpawned(CEntityInstance entity)
|
||||
private void OnEntityCreated(CEntityInstance entity)
|
||||
{
|
||||
if (!Config.Additional.SkinEnabled) return;
|
||||
var designerName = entity.DesignerName;
|
||||
if (entity == null || !entity.IsValid || string.IsNullOrEmpty(entity.DesignerName)) return;
|
||||
string designerName = entity.DesignerName;
|
||||
if (!weaponList.ContainsKey(designerName)) return;
|
||||
bool isKnife = false;
|
||||
var weapon = new CBasePlayerWeapon(entity.Handle);
|
||||
@@ -57,6 +65,7 @@ namespace WeaponPaints
|
||||
{
|
||||
isKnife = true;
|
||||
}
|
||||
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
try
|
||||
@@ -84,18 +93,25 @@ namespace WeaponPaints
|
||||
|
||||
if (player == null || !player.IsValid) return HookResult.Continue;
|
||||
|
||||
/*
|
||||
if (Config.Additional.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 (!Utility.IsPlayerValid(player) || !player.PawnIsAlive || g_knifePickupCount[(int)player.Index] >= 2) return HookResult.Continue;
|
||||
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_playersKnife.ContainsKey((int)player.Index)
|
||||
&&
|
||||
@@ -104,12 +120,43 @@ namespace WeaponPaints
|
||||
g_knifePickupCount[(int)player.Index]++;
|
||||
|
||||
RemovePlayerKnife(player, true);
|
||||
AddTimer(0.3f, () => GiveKnifeToPlayer(player));
|
||||
|
||||
if (!PlayerHasKnife(player) && Config.Additional.GiveKnifeAfterRemove)
|
||||
AddTimer(0.3f, () => GiveKnifeToPlayer(player));
|
||||
}
|
||||
}
|
||||
return HookResult.Continue;
|
||||
}
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
if (player == null || player.IsBot || player.IsHLTV)
|
||||
return HookResult.Continue;
|
||||
|
||||
if (player == null || !player.IsValid || player.SteamID.ToString() == "" ||
|
||||
!g_knifePickupCount.ContainsKey((int)player.Index) || !g_playersKnife.ContainsKey((int)player.Index))
|
||||
return HookResult.Continue;
|
||||
|
||||
CBasePlayerWeapon weapon = new(caller.Handle);
|
||||
|
||||
if (weapon.AttributeManager.Item.ItemDefinitionIndex != 42 && weapon.AttributeManager.Item.ItemDefinitionIndex != 59)
|
||||
return HookResult.Continue;
|
||||
|
||||
if (g_knifePickupCount[(int)player.Index] >= 2) return HookResult.Continue;
|
||||
|
||||
if (g_playersKnife[(int)player.Index] != "weapon_knife")
|
||||
{
|
||||
g_knifePickupCount[(int)player.Index]++;
|
||||
player.RemoveItemByDesignerName(weapon.DesignerName);
|
||||
if (Config.Additional.GiveKnifeAfterRemove)
|
||||
AddTimer(0.2f, () => GiveKnifeToPlayer(player));
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
private void OnMapStart(string mapName)
|
||||
{
|
||||
@@ -118,6 +165,7 @@ namespace WeaponPaints
|
||||
// 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");
|
||||
@@ -128,20 +176,21 @@ namespace WeaponPaints
|
||||
weaponSync = new WeaponSynchronization(DatabaseConnectionString, Config, GlobalShareApi, GlobalShareServerId);
|
||||
});
|
||||
|
||||
/*
|
||||
g_hTimerCheckSkinsData = AddTimer(10.0f, () =>
|
||||
{
|
||||
List<CCSPlayerController> players = Utilities.GetPlayers();
|
||||
|
||||
foreach (CCSPlayerController player in players)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.AuthorizedSteamID == null) continue;
|
||||
if (player.IsBot || player.IsHLTV || player.SteamID.ToString() == "") continue;
|
||||
if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue;
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
SteamId = player?.SteamID.ToString(),
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
@@ -152,7 +201,7 @@ namespace WeaponPaints
|
||||
_ = weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
}
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE | CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT);
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
private HookResult OnPlayerConnectFull(EventPlayerConnectFull @event, GameEventInfo info)
|
||||
@@ -165,7 +214,7 @@ namespace WeaponPaints
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
SteamId = player?.SteamID.ToString(),
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
@@ -193,22 +242,23 @@ namespace WeaponPaints
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
if (Config.Additional.KnifeEnabled && !PlayerHasKnife(player))
|
||||
{
|
||||
g_knifePickupCount[(int)player.Index] = 0;
|
||||
if (!PlayerHasKnife(player))
|
||||
GiveKnifeToPlayer(player);
|
||||
GiveKnifeToPlayer(player);
|
||||
//AddTimer(0.1f, () => GiveKnifeToPlayer(player));
|
||||
}
|
||||
|
||||
/*
|
||||
if (Config.Additional.SkinVisibilityFix)
|
||||
{
|
||||
AddTimer(0.3f, () => RefreshSkins(player));
|
||||
}
|
||||
*/
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
|
||||
private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info)
|
||||
{
|
||||
g_bCommandsAllowed = false;
|
||||
@@ -226,21 +276,76 @@ namespace WeaponPaints
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
private void OnTick()
|
||||
{
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (player == null || !player.IsValid || !player.PawnIsAlive || player.IsBot || player.IsHLTV || player.Connected == PlayerConnectedState.PlayerDisconnecting) continue;
|
||||
|
||||
var viewModels = GetPlayerViewModels(player);
|
||||
|
||||
if (viewModels == null) continue;
|
||||
|
||||
var viewModel = viewModels[0];
|
||||
if (viewModel == null || viewModel.Value == null || viewModel.Value.Weapon == null || viewModel.Value.Weapon.Value == null) continue;
|
||||
CBasePlayerWeapon weapon = viewModel.Value.Weapon.Value;
|
||||
|
||||
if (weapon == null || !weapon.IsValid) continue;
|
||||
|
||||
var isKnife = viewModel.Value.VMName.Contains("knife");
|
||||
|
||||
if (!isKnife)
|
||||
{
|
||||
if (
|
||||
viewModel.Value.CBodyComponent != null
|
||||
&& viewModel.Value.CBodyComponent.SceneNode != null
|
||||
)
|
||||
{
|
||||
var skeleton = GetSkeletonInstance(viewModel.Value.CBodyComponent.SceneNode);
|
||||
int[] array = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 };
|
||||
int fallbackPaintKit = weapon.FallbackPaintKit;
|
||||
if (array.Contains(fallbackPaintKit))
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skeleton.ModelState.MeshGroupMask != 2)
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Utilities.SetStateChanged(viewModel.Value, "CBaseEntity", "m_CBodyComponent");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterListeners()
|
||||
{
|
||||
RegisterListener<Listeners.OnEntitySpawned>(OnEntitySpawned);
|
||||
RegisterListener<Listeners.OnClientAuthorized>(OnClientAuthorized);
|
||||
RegisterListener<Listeners.OnEntityCreated>(OnEntityCreated);
|
||||
RegisterListener<Listeners.OnClientPutInServer>(OnClientPutInServer);
|
||||
RegisterListener<Listeners.OnClientDisconnect>(OnClientDisconnect);
|
||||
RegisterListener<Listeners.OnMapStart>(OnMapStart);
|
||||
RegisterListener<Listeners.OnTick>(OnTick);
|
||||
|
||||
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull);
|
||||
//RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull);
|
||||
RegisterEventHandler<EventPlayerSpawn>(OnPlayerSpawn);
|
||||
RegisterEventHandler<EventRoundStart>(OnRoundStart, HookMode.Pre);
|
||||
RegisterEventHandler<EventRoundEnd>(OnRoundEnd);
|
||||
RegisterEventHandler<EventItemPurchase>(OnEventItemPurchasePost);
|
||||
RegisterEventHandler<EventItemPickup>(OnItemPickup);
|
||||
//RegisterEventHandler<EventItemPurchase>(OnEventItemPurchasePost);
|
||||
//RegisterEventHandler<EventItemPickup>(OnItemPickup);
|
||||
HookEntityOutput("weapon_knife", "OnPlayerPickup", OnPickup, HookMode.Pre);
|
||||
}
|
||||
|
||||
|
||||
/* WORKAROUND FOR CLIENTS WITHOUT STEAMID ON AUTHORIZATION */
|
||||
/*private HookResult OnPlayerConnectFull(EventPlayerConnectFull @event, GameEventInfo info)
|
||||
{
|
||||
|
||||
15
PlayerExtensions.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using System.Text;
|
||||
|
||||
namespace WeaponPaints;
|
||||
|
||||
public static class PlayerExtensions
|
||||
{
|
||||
public static void Print(this CCSPlayerController controller, string message)
|
||||
{
|
||||
if (WeaponPaints._localizer == null) return;
|
||||
StringBuilder _message = new(WeaponPaints._localizer["wp_prefix"]);
|
||||
_message.Append(message);
|
||||
controller.PrintToChat(_message.ToString());
|
||||
}
|
||||
}
|
||||
64
README.md
@@ -1,26 +1,31 @@
|
||||
# CS2 Weapon Paints
|
||||
|
||||
## Description
|
||||
Unfinished, unoptimized and not fully functional ugly demo weapon paints plugin for **[CSSharp](https://docs.cssharp.dev/)**.
|
||||
Unfinished, unoptimized and not fully functional ugly demo weapon paints plugin for **[CSSharp](https://docs.cssharp.dev/docs/guides/getting-started.html)**.
|
||||
|
||||
## Created [Discord server](https://discord.gg/d9CvaYPSFe) where you can discus about plugin.
|
||||
## Created [Discord server](https://discord.gg/d9CvaYPSFe) where you can discuss about plugin.
|
||||
|
||||
### Consider to donate instead of buying from unknown sources.
|
||||
[](https://ko-fi.com/E1E2G0P2O) or [](https://steamcommunity.com/tradeoffer/new/?partner=41515647&token=gW2W-nXE)
|
||||
|
||||
## Features
|
||||
- Changes only paint, seed and wear on weapons and knives;
|
||||
- MySQL based or global website at [weaponpaints.fun](https://weaponpaints.fun/), so you dont need MySQL/Website;
|
||||
- Data sync on player connect;
|
||||
- Added command **`!wp`** to refresh skins; ***(with cooldown in second can be configured)***
|
||||
- Added command **`!ws`** to show website;
|
||||
- Added command **`!knife`** to show menu with knives;
|
||||
- Knife change is now limited to have these cvars empty **`mp_t_default_melee ""`** and **`mp_ct_default_melee ""`**;
|
||||
- Changes only paint, seed and wear on weapons and knives
|
||||
- MySQL based or global website, so you dont need MySQL/Website
|
||||
- Data syncs on player connect
|
||||
- Added command **`!wp`** to refresh skins ***(with cooldown in seconds can be configured)***
|
||||
- Added command **`!ws`** to show website
|
||||
- Added command **`!knife`** to show menu with knives
|
||||
- Knife change is now limited to have these cvars empty **`mp_t_default_melee ""`** and **`mp_ct_default_melee ""`**
|
||||
- Translations support, submit a PR if you want to share your translation
|
||||
|
||||
**GlobalShare** - global website accessible at [weaponpaints.fun](https://weaponpaints.fun/)
|
||||
|
||||
## CS2 Server
|
||||
- Compile and copy plugin to plugins, [more info here](https://docs.cssharp.dev/guides/hello-world-plugin/);
|
||||
- Setup **`addons/counterstrikesharp/configs/plugins/WeaponPaints/WeaponPaints.json`** set **`GlobalShare`** to **`true`** for global, or include database credentials;
|
||||
- in **`addons/counterstrikesharp/configs/core.json`** set **FollowCS2ServerGuidelines** to **`false`**;
|
||||
- Have working CounterStrikeSharp (**with RUNTIME!**)
|
||||
- Download from Release and copy plugin to plugins
|
||||
- Run server with plugin, **it will generate config if installed correctly!**
|
||||
- Edit `addons/counterstrikesharp/configs/`**`plugins/WeaponPaints/WeaponPaints.json`** set **`GlobalShare`** to **`true`** for global, or include database credentials
|
||||
- In `addons/counterstrikesharp/configs/`**`core.json`** set **FollowCS2ServerGuidelines** to **`false`**
|
||||
|
||||
## Plugin Configuration
|
||||
<details>
|
||||
@@ -69,15 +74,38 @@ Unfinished, unoptimized and not fully functional ugly demo weapon paints plugin
|
||||
</details>
|
||||
|
||||
## Web install
|
||||
Disregard if the config is **`GlobalShare = true`**;
|
||||
- Requires PHP >= 7.4; ***(Tested on php ver **`8.2.3`** and nginx webserver)***
|
||||
- Copy website to web server; ***(Folder `img` not needed)***
|
||||
- Get [Steam API Key](https://steamcommunity.com/dev/apikey);
|
||||
- Fill in database credentials and api key in `class/config.php`;
|
||||
- Visit website and login via steam;
|
||||
Disregard if the config is **`GlobalShare = true`**
|
||||
- Requires PHP >= 7.4 ***(Tested on php ver **`8.2.3`** and nginx webserver)***
|
||||
- **Before using website, make sure the plugin is correctly loaded in cs2 server!** Mysql tables are created by plugin not by website.
|
||||
- Copy website to web server ***(Folder `img` not needed)***
|
||||
- Get [Steam API Key](https://steamcommunity.com/dev/apikey)
|
||||
- Fill in database credentials and api key in `class/config.php`
|
||||
- Visit website and login via steam
|
||||
|
||||
## Web Features
|
||||
- Basic website
|
||||
- Steam login/logout
|
||||
- Change knife, paint, seed and wear
|
||||
|
||||
## Known issues
|
||||
- Issue on Windows servers, no knives are given.
|
||||
- You can't change knife if it's equpied in cs2 inventory
|
||||
- Can cause incompatibility with plugins/maps which manipulates weapons and knives
|
||||
|
||||
## Troubleshooting
|
||||
<details>
|
||||
**Skins are not changing:**
|
||||
Set FollowCSGOGuidelines to false in cssharp’s core.jcon config
|
||||
|
||||
**Database error table does not exists:**
|
||||
Plugin is not loaded or configured with mysql credentials. Tables are auto-created by plugin.
|
||||
|
||||
**Knives are disappearing:**
|
||||
Set in config GiveKnifeAfterRemove to true
|
||||
|
||||
**Knives are not changing for players:**
|
||||
You can't change knife if you have your own equipped
|
||||
</details>
|
||||
|
||||
### Use this plugin at your own risk! Using this may lead to GSLT ban or something else Valve come with. [Valve Server guidelines](https://blog.counter-strike.net/index.php/server_guidelines/)
|
||||
|
||||
|
||||
41
Utility.cs
@@ -5,6 +5,7 @@ using MySqlConnector;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WeaponPaints
|
||||
{
|
||||
@@ -107,6 +108,46 @@ namespace WeaponPaints
|
||||
return message;
|
||||
}
|
||||
|
||||
internal static async Task CheckVersion(string version, ILogger logger)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = await client.GetAsync("https://raw.githubusercontent.com/Nereziel/cs2-WeaponPaints/main/VERSION");
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
string remoteVersion = await response.Content.ReadAsStringAsync();
|
||||
remoteVersion = remoteVersion.Trim();
|
||||
|
||||
int comparisonResult = string.Compare(version, remoteVersion);
|
||||
|
||||
if (comparisonResult < 0)
|
||||
{
|
||||
logger.LogWarning("Plugin is outdated! Check https://github.com/Nereziel/cs2-WeaponPaints");
|
||||
}
|
||||
else if (comparisonResult > 0)
|
||||
{
|
||||
logger.LogInformation("Probably dev version detected");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("Plugin is up to date");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Failed to check version");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ShowAd(string moduleVersion)
|
||||
{
|
||||
Console.WriteLine(" ");
|
||||
|
||||
@@ -3,6 +3,7 @@ using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace WeaponPaints
|
||||
{
|
||||
@@ -20,6 +21,12 @@ namespace WeaponPaints
|
||||
|
||||
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||
|
||||
|
||||
if (isKnife)
|
||||
{
|
||||
weapon.AttributeManager.Item.EntityQuality = 3;
|
||||
}
|
||||
|
||||
if (_config.Additional.GiveRandomSkin &&
|
||||
!gPlayerWeaponsInfo[playerIndex].ContainsKey(weaponDefIndex))
|
||||
{
|
||||
@@ -33,7 +40,20 @@ namespace WeaponPaints
|
||||
if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null)
|
||||
{
|
||||
var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode);
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
|
||||
int[] array = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 };
|
||||
int fallbackPaintKit = weapon.FallbackPaintKit;
|
||||
if (array.Contains(fallbackPaintKit))
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skeleton.ModelState.MeshGroupMask != 2)
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -47,16 +67,30 @@ namespace WeaponPaints
|
||||
weapon.FallbackPaintKit = weaponInfo.Paint;
|
||||
weapon.FallbackSeed = weaponInfo.Seed;
|
||||
weapon.FallbackWear = weaponInfo.Wear;
|
||||
|
||||
if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null)
|
||||
{
|
||||
var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode);
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
int[] array = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 };
|
||||
int fallbackPaintKit = weapon.FallbackPaintKit;
|
||||
if (array.Contains(fallbackPaintKit))
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skeleton.ModelState.MeshGroupMask != 2)
|
||||
{
|
||||
skeleton.ModelState.MeshGroupMask = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void GiveKnifeToPlayer(CCSPlayerController? player)
|
||||
{
|
||||
if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return;
|
||||
|
||||
if (g_playersKnife.TryGetValue((int)player.Index, out var knife))
|
||||
{
|
||||
player.GiveNamedItem(knife);
|
||||
@@ -165,6 +199,7 @@ namespace WeaponPaints
|
||||
|
||||
internal void RefreshSkins(CCSPlayerController? player)
|
||||
{
|
||||
return;
|
||||
if (!Utility.IsPlayerValid(player) || !player!.PawnIsAlive) return;
|
||||
|
||||
AddTimer(0.18f, () => NativeAPI.IssueClientCommand((int)player.Index - 1, "slot3"));
|
||||
@@ -192,7 +227,7 @@ namespace WeaponPaints
|
||||
{
|
||||
if (weapon.Value.DesignerName.Contains("knife") || weapon.Value.DesignerName.Contains("bayonet"))
|
||||
{
|
||||
weapon.Value.Remove();
|
||||
player.RemoveItemByDesignerName(weapon.Value.DesignerName, true);
|
||||
GiveKnifeToPlayer(player);
|
||||
}
|
||||
else
|
||||
@@ -203,8 +238,8 @@ namespace WeaponPaints
|
||||
clip1 = weapon.Value.Clip1;
|
||||
reservedAmmo = weapon.Value.ReserveAmmo[0];
|
||||
|
||||
weapon.Value.Remove();
|
||||
string weaponByDefindex = weaponDefindex[weapon.Value.AttributeManager.Item.ItemDefinitionIndex];
|
||||
player.RemoveItemByDesignerName(weapon.Value.DesignerName, true);
|
||||
CBasePlayerWeapon newWeapon = new(player.GiveNamedItem(weaponByDefindex));
|
||||
|
||||
Server.NextFrame(() =>
|
||||
@@ -228,8 +263,11 @@ namespace WeaponPaints
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (Config.Additional.SkinVisibilityFix)
|
||||
RefreshSkins(player);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,10 +318,10 @@ namespace WeaponPaints
|
||||
}
|
||||
private static int GetRandomPaint(int defindex)
|
||||
{
|
||||
Random rnd = new Random();
|
||||
|
||||
if (WeaponPaints.skinsList != null)
|
||||
if (skinsList != null)
|
||||
{
|
||||
Random rnd = new Random();
|
||||
// Filter weapons by the provided defindex
|
||||
var filteredWeapons = skinsList.FindAll(w => w["weapon_defindex"]?.ToString() == defindex.ToString());
|
||||
|
||||
@@ -308,5 +346,27 @@ namespace WeaponPaints
|
||||
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;
|
||||
CCSPlayer_ViewModelServices viewModelServices = new CCSPlayer_ViewModelServices(player.PlayerPawn.Value.ViewModelServices!.Handle);
|
||||
return GetFixedArray<CHandle<CBaseViewModel>>(viewModelServices.Handle, "CCSPlayer_ViewModelServices", "m_hViewModel", 3);
|
||||
}
|
||||
|
||||
public static unsafe T[] GetFixedArray<T>(nint pointer, string @class, string member, int length) where T : CHandle<CBaseViewModel>
|
||||
{
|
||||
nint ptr = pointer + Schema.GetSchemaOffset(@class, member);
|
||||
Span<nint> references = MemoryMarshal.CreateSpan<nint>(ref ptr, length);
|
||||
T[] values = new T[length];
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
values[i] = (T)Activator.CreateInstance(typeof(T), references[i])!;
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,14 @@ using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Modules.Cvars;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace WeaponPaints;
|
||||
|
||||
[MinimumApiVersion(101)]
|
||||
[MinimumApiVersion(163)]
|
||||
public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig>
|
||||
{
|
||||
internal static readonly Dictionary<string, string> weaponList = new()
|
||||
@@ -34,6 +36,7 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
{"weapon_negev", "Negev"},
|
||||
{"weapon_sawedoff", "Sawed-Off"},
|
||||
{"weapon_tec9", "Tec-9"},
|
||||
{"weapon_taser", "Zeus x27"},
|
||||
{"weapon_hkp2000", "P2000"},
|
||||
{"weapon_mp7", "MP7"},
|
||||
{"weapon_mp9", "MP9"},
|
||||
@@ -65,23 +68,24 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
{ "weapon_knife_cord", "Paracord Knife" },
|
||||
{ "weapon_knife_canis", "Survival Knife" },
|
||||
{ "weapon_knife_outdoor", "Nomad Knife" },
|
||||
{ "weapon_knife_skeleton", "Skeleton Knife" }
|
||||
{ "weapon_knife_skeleton", "Skeleton Knife" },
|
||||
{ "weapon_knife_kukri", "Kukri Knife" }
|
||||
};
|
||||
|
||||
internal static WeaponPaintsConfig _config = new WeaponPaintsConfig();
|
||||
internal static IStringLocalizer? _localizer;
|
||||
internal static Dictionary<int, int> g_knifePickupCount = new Dictionary<int, int>();
|
||||
internal static Dictionary<int, string> g_playersKnife = new();
|
||||
internal static Dictionary<int, Dictionary<int, WeaponInfo>> gPlayerWeaponsInfo = new Dictionary<int, Dictionary<int, WeaponInfo>>();
|
||||
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 List<JObject> skinsList = new List<JObject>();
|
||||
internal static WeaponSynchronization? weaponSync;
|
||||
//internal static List<int> g_changedKnife = new();
|
||||
internal bool g_bCommandsAllowed = true;
|
||||
|
||||
internal Uri GlobalShareApi = new Uri("https://weaponpaints.fun/api.php");
|
||||
internal Uri GlobalShareApi = new("https://weaponpaints.fun/api.php");
|
||||
internal int GlobalShareServerId = 0;
|
||||
private DateTime[] commandCooldown = new DateTime[Server.MaxPlayers];
|
||||
internal static Dictionary<int, DateTime> commandsCooldown = new Dictionary<int, DateTime>();
|
||||
private string DatabaseConnectionString = string.Empty;
|
||||
private CounterStrikeSharp.API.Modules.Timers.Timer? g_hTimerCheckSkinsData = null;
|
||||
//private CounterStrikeSharp.API.Modules.Timers.Timer? g_hTimerCheckSkinsData = null;
|
||||
public static Dictionary<int, string> weaponDefindex { get; } = new Dictionary<int, string>
|
||||
{
|
||||
{ 1, "weapon_deagle" },
|
||||
@@ -106,6 +110,7 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
{ 28, "weapon_negev" },
|
||||
{ 29, "weapon_sawedoff" },
|
||||
{ 30, "weapon_tec9" },
|
||||
{ 31, "weapon_taser" },
|
||||
{ 32, "weapon_hkp2000" },
|
||||
{ 33, "weapon_mp7" },
|
||||
{ 34, "weapon_mp9" },
|
||||
@@ -136,14 +141,16 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
{ 521, "weapon_knife_outdoor" },
|
||||
{ 522, "weapon_knife_stiletto" },
|
||||
{ 523, "weapon_knife_widowmaker" },
|
||||
{ 525, "weapon_knife_skeleton" }
|
||||
{ 525, "weapon_knife_skeleton" },
|
||||
{ 526, "weapon_knife_kukri" }
|
||||
};
|
||||
|
||||
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.3d";
|
||||
public override string ModuleVersion => "1.5a";
|
||||
|
||||
public static WeaponPaintsConfig GetWeaponPaintsConfig()
|
||||
{
|
||||
return _config;
|
||||
@@ -165,14 +172,19 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
|
||||
foreach (CCSPlayerController player in players)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.AuthorizedSteamID == null) continue;
|
||||
if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue;
|
||||
if (player == null || !player.IsValid || player.IsBot || player.IsHLTV) continue;
|
||||
//if (gPlayerWeaponsInfo.ContainsKey((int)player.Index)) continue;
|
||||
|
||||
if (gPlayerWeaponsInfo.ContainsKey((int)player.Index))
|
||||
gPlayerWeaponsInfo.TryRemove((int)player.Index, out _);
|
||||
if (g_playersKnife.ContainsKey((int)player.Index))
|
||||
g_playersKnife.TryRemove((int)player.Index, out _);
|
||||
|
||||
PlayerInfo playerInfo = new PlayerInfo
|
||||
{
|
||||
UserId = player.UserId,
|
||||
Index = (int)player.Index,
|
||||
SteamId = player?.AuthorizedSteamID?.SteamId64.ToString(),
|
||||
SteamId = player?.SteamID.ToString(),
|
||||
Name = player?.PlayerName,
|
||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||
};
|
||||
@@ -181,10 +193,9 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
_ = weaponSync.GetWeaponPaintsFromDatabase(playerInfo);
|
||||
if (Config.Additional.KnifeEnabled && weaponSync != null)
|
||||
_ = weaponSync.GetKnifeFromDatabase(playerInfo);
|
||||
}
|
||||
|
||||
RegisterListeners();
|
||||
RegisterCommands();
|
||||
g_knifePickupCount[(int)player!.Index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.Additional.KnifeEnabled)
|
||||
@@ -211,8 +222,11 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
|
||||
Config = config;
|
||||
_config = config;
|
||||
_localizer = Localizer;
|
||||
|
||||
Utility.Config = config;
|
||||
Utility.ShowAd(ModuleVersion);
|
||||
Task.Run(async () => await Utility.CheckVersion(ModuleVersion, Logger));
|
||||
}
|
||||
|
||||
public override void Unload(bool hotReload)
|
||||
@@ -244,7 +258,7 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
||||
Task<string> responseBodyTask = response.Content.ReadAsStringAsync();
|
||||
responseBodyTask.Wait();
|
||||
string responseBody = responseBodyTask.Result;
|
||||
GlobalShareServerId = Int32.Parse(responseBody);
|
||||
GlobalShareServerId = int.Parse(responseBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -5,12 +5,17 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CounterStrikeSharp.API" Version="*" />
|
||||
<PackageReference Include="Dapper" Version="2.1.24" />
|
||||
<PackageReference Include="MySqlConnector" Version="2.3.1" />
|
||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.163" />
|
||||
<PackageReference Include="Dapper" Version="2.1.28" />
|
||||
<PackageReference Include="MySqlConnector" Version="2.3.5" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="lang\**\*.*" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using Dapper;
|
||||
using Dapper;
|
||||
using MySqlConnector;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace WeaponPaints
|
||||
{
|
||||
@@ -96,7 +95,7 @@ namespace WeaponPaints
|
||||
|
||||
if (!WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Index, out _))
|
||||
{
|
||||
WeaponPaints.gPlayerWeaponsInfo[player.Index] = new Dictionary<int, WeaponInfo>();
|
||||
WeaponPaints.gPlayerWeaponsInfo[player.Index] = new ConcurrentDictionary<int, WeaponInfo>();
|
||||
}
|
||||
try
|
||||
{
|
||||
@@ -209,21 +208,17 @@ namespace WeaponPaints
|
||||
return;
|
||||
}
|
||||
}
|
||||
internal async Task SyncWeaponPaintsToDatabase(CCSPlayerController? player)
|
||||
internal async Task SyncWeaponPaintsToDatabase(PlayerInfo player)
|
||||
{
|
||||
if (player == null || !Utility.IsPlayerValid(player)) return;
|
||||
|
||||
int playerIndex = (int)player.Index;
|
||||
if (player.AuthorizedSteamID == null) return;
|
||||
string steamId = player.AuthorizedSteamID.SteamId64.ToString();
|
||||
if (player == null || player.Index <= 0 || player.SteamId == null) return;
|
||||
|
||||
using var connection = new MySqlConnection(_databaseConnectionString);
|
||||
await connection.OpenAsync();
|
||||
|
||||
if (!WeaponPaints.gPlayerWeaponsInfo.ContainsKey(playerIndex))
|
||||
if (!WeaponPaints.gPlayerWeaponsInfo.ContainsKey(player.Index))
|
||||
return;
|
||||
|
||||
foreach (var weaponInfoPair in WeaponPaints.gPlayerWeaponsInfo[playerIndex])
|
||||
foreach (var weaponInfoPair in WeaponPaints.gPlayerWeaponsInfo[player.Index])
|
||||
{
|
||||
int weaponDefIndex = weaponInfoPair.Key;
|
||||
WeaponInfo weaponInfo = weaponInfoPair.Value;
|
||||
@@ -236,7 +231,7 @@ namespace WeaponPaints
|
||||
"`weapon_wear` = @wear, `weapon_seed` = @seed WHERE `steamid` = @steamid " +
|
||||
"AND `weapon_defindex` = @weaponDefIndex";
|
||||
|
||||
var updateParams = new { paintId, wear, seed, steamid = steamId, weaponDefIndex };
|
||||
var updateParams = new { paintId, wear, seed, steamid = player.SteamId, weaponDefIndex };
|
||||
int rowsAffected = await connection.ExecuteAsync(updateSql, updateParams);
|
||||
|
||||
if (rowsAffected == 0)
|
||||
|
||||
14
lang/en.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||
"wp_info_website": "Visit {lime}{0}{default} where you can change skins",
|
||||
"wp_info_refresh": "Type {lime}!wp{default} to synchronize chosen skins",
|
||||
"wp_info_knife": "Type {lime}!knife{default} to open knife menu",
|
||||
"wp_command_cooldown": "{lightred}You can't refresh weapon paints right now",
|
||||
"wp_command_refresh_done": "{lime}Refreshing weapon paints",
|
||||
"wp_knife_menu_select": "You have chosen {lime}{0}{default} as your knife",
|
||||
"wp_knife_menu_kill": "To correctly apply skin for knife, you need to type {lime}!kill{default}",
|
||||
"wp_knife_menu_title": "Knife Menu",
|
||||
"wp_skin_menu_weapon_title": "Weapon Menu",
|
||||
"wp_skin_menu_skin_title": "Select skin for {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "You have chosen {lime}{0}{default} as your skin"
|
||||
}
|
||||
14
lang/lv.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[Ieroču Ādiņas] {default}",
|
||||
"wp_info_website": "Apmeklē {lime}{0}{default} kur tu vari nomainīt skinus",
|
||||
"wp_info_refresh": "Raksti {lime}!wp{default} lai sinhronizētu izvēlētos skinus",
|
||||
"wp_info_knife": "Raksti {lime}!knife{default} lai atvērtu nažu izvēlni",
|
||||
"wp_command_cooldown": "{lightred} Tu šobrīd nevari atjaunot ieroču skinus...",
|
||||
"wp_command_refresh_done": "{lime}Izvēlētie skini tiek atjaunoti",
|
||||
"wp_knife_menu_select": "Tu esi izvēlējies {lime}{0}{default} nazi",
|
||||
"wp_knife_menu_kill": "Lai pareizi atjaunotu naža skinu, ieraksti čatā {lime}!kill{default}",
|
||||
"wp_knife_menu_title": "Nažu Izvēlne",
|
||||
"wp_skin_menu_weapon_title": "Ieroču Izvēlne",
|
||||
"wp_skin_menu_skin_title": "Izvēlies skinu ierocim: {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "Tu esi izvēlējies {lime}{0}{default} kā savu skinu"
|
||||
}
|
||||
14
lang/pl.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||
"wp_info_website": "Odwiedź {lime}{0}{default} gdzie będziesz mógł ustawić skiny",
|
||||
"wp_info_refresh": "Wpisz {lime}!wp{default} aby zsynchronizować swoje skiny",
|
||||
"wp_info_knife": "Wpisz {lime}!knife{default} aby wy<77>wietlić menu no<6E>y",
|
||||
"wp_command_cooldown": "{lightred}Odczekaj chwilę przed wykonaniem tej komendy...",
|
||||
"wp_command_refresh_done": "{lime}Pomyslnie zsynchronizowano twoje skiny",
|
||||
"wp_knife_menu_select": "Wybrałeś {lime}{0}{default} jako swój nóż",
|
||||
"wp_knife_menu_kill": "Do prawidłowego zastosowania noża użyj {lime}!kill{default}",
|
||||
"wp_knife_menu_title": "Menu noży",
|
||||
"wp_skin_menu_weapon_title": "Menu broni",
|
||||
"wp_skin_menu_skin_title": "Wybierz skin dla {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "Wybrałeś {lime}{0}{default} jako swój skin"
|
||||
}
|
||||
14
lang/pt-BR.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||
"wp_info_website": "Visite {lime}{0}{default} para mudar suas skins e faca",
|
||||
"wp_info_refresh": "Digite {lime}!wp{default} para sincronizar as suas skins",
|
||||
"wp_info_knife": "Digite {lime}!knife{default} para abrir o menu de facas",
|
||||
"wp_command_cooldown": "{lightred}Você não pode atualizar as skins das armas agora",
|
||||
"wp_command_refresh_done": "{lime}Sincronizando as suas skins",
|
||||
"wp_knife_menu_select": "Você escolheu {lime}{0}{default} como sua faca",
|
||||
"wp_knife_menu_kill": "Para aplicar corretamente a skin da faca, você precisa digitar {lime}!kill{default}",
|
||||
"wp_knife_menu_title": "Menu de Facas",
|
||||
"wp_skin_menu_weapon_title": "Menu de Armas",
|
||||
"wp_skin_menu_skin_title": "Selecionou a skin para {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "Você escolheu {lime}{0}{default} como sua skin"
|
||||
}
|
||||
14
lang/pt-PT.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||
"wp_info_website": "Visita {lime}{0}{default} onde podes mudar as tuas skins",
|
||||
"wp_info_refresh": "Digita {lime}!wp{default} para sincronizar as tuas skins",
|
||||
"wp_info_knife": "Digita {lime}!knife{default} para abrir o menu de facas",
|
||||
"wp_command_cooldown": "{lightred}Tu não podes sincronizar agora as tuas skins",
|
||||
"wp_command_refresh_done": "{lime}Sincronizando as tuas skins",
|
||||
"wp_knife_menu_select": "Tu escolheste {lime}{0}{default} como a tua faca",
|
||||
"wp_knife_menu_kill": "Para aplicar corretamente a skins para a tua faca, digita {lime}!kill{default}",
|
||||
"wp_knife_menu_title": "Menu Facas",
|
||||
"wp_skin_menu_weapon_title": "Menu de Armas",
|
||||
"wp_skin_menu_skin_title": "Escolhe a skin para {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "Tu escolheste {lime}{0}{default} como a tua skin"
|
||||
}
|
||||
14
lang/ru.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||
"wp_info_website": "Посетите сайт {lime}{0},{default} чтобы выбрать скин",
|
||||
"wp_info_refresh": "Наберите в чат {lime}!wp{default} для синхронизации выбранных скинов",
|
||||
"wp_info_knife": "Наберите в чат {lime}!knife,{default} чтобы выбрать нож",
|
||||
"wp_command_cooldown": "{lightred}Вы не можете выбрать оружие прямо сейчас",
|
||||
"wp_command_refresh_done": "{lime}Обновление скинов для оружия",
|
||||
"wp_knife_menu_select": "Вы выбрали {lime}{0}{default} скин для ножа",
|
||||
"wp_knife_menu_kill": "Чтобы правильно применить скин для ножа, набери в чат {lime}!kill{default}",
|
||||
"wp_knife_menu_title": "Меню ножей",
|
||||
"wp_skin_menu_weapon_title": "Меню оружия",
|
||||
"wp_skin_menu_skin_title": "Выберите скин для {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "Вы выбрали {lime}{0}{default} скина для оружия"
|
||||
}
|
||||
14
lang/tr.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||
"wp_info_website": "Görünümleri değiştirebileceğiniz {lime}{0}{default} adresini ziyaret edin",
|
||||
"wp_info_refresh": "Seçilen kaplamyı senkronize etmek için {lime}!wp{default} yazın",
|
||||
"wp_info_knife": "Bıçak menüsünü açmak için {lime}!knife{default} yazın",
|
||||
"wp_command_cooldown": "{lightred}Şu anda silah kaplamasını yenileyemezsiniz",
|
||||
"wp_command_refresh_done": "{lime}Silah kaplaması yenileniyor",
|
||||
"wp_knife_menu_select": "Bıçağınız olarak {lime}{0}{default} seçtiniz",
|
||||
"wp_knife_menu_kill": "Bıçak için doğru şekilde kaplama uygulamak için {lime}!kill{default} yazmanız gerekir",
|
||||
"wp_knife_menu_title": "Bıçak Menüsü",
|
||||
"wp_skin_menu_weapon_title": "Silah Menüsü",
|
||||
"wp_skin_menu_skin_title": "Select skin for {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "Teniniz olarak {lime}{0}{default} seçtiniz"
|
||||
}
|
||||
14
lang/ua.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||
"wp_info_website": "Відвідайте веб-сайт {lime}{0},{default} щоб вибрати скин",
|
||||
"wp_info_refresh": "Напишіть у чат {lime}!wp{default} для синхронізації вибраних скинів",
|
||||
"wp_info_knife": "Напишіть у чат {lime}!knife,{default} щоб вибрати ніж",
|
||||
"wp_command_cooldown": "{lightred}Ви не можете вибрати зброю зараз",
|
||||
"wp_command_refresh_done": "{lime}Оновлення скинів для зброї",
|
||||
"wp_knife_menu_select": "Ви вибрали скин {lime}{0}{default} для ножа",
|
||||
"wp_knife_menu_kill": "Щоб правильно застосувати скин для ножа, напишіть у чат {lime}!kill{default}",
|
||||
"wp_knife_menu_title": "Меню ножів",
|
||||
"wp_skin_menu_weapon_title": "Меню зброї",
|
||||
"wp_skin_menu_skin_title": "Виберіть скин для {lime}{0}{default}",
|
||||
"wp_skin_menu_select": "Ви вибрали скин {lime}{0}{default} для зброї"
|
||||
}
|
||||
14
lang/zh-cn.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"wp_prefix": "{lightblue}[武器皮肤] {default}",
|
||||
"wp_info_website": "在线访问 {lime}{0}{default} 更改你的武器皮肤",
|
||||
"wp_info_refresh": "输入 {lime}!wp{default} 进行在线皮肤同步",
|
||||
"wp_info_knife": "输入 {lime}!knife{default} 打开刀菜单",
|
||||
"wp_command_cooldown": "{lightred}皮肤同步刷新冷却中",
|
||||
"wp_command_refresh_done": "{lime}刷新武器皮肤中",
|
||||
"wp_knife_menu_select": "你选择了 {lime}{0}{default} 作为你的刀",
|
||||
"wp_knife_menu_kill": "如需完全应用皮肤到刀上, 你需要输入 {lime}!kill{default} 自杀来进行刷新",
|
||||
"wp_knife_menu_title": "刀菜单",
|
||||
"wp_skin_menu_weapon_title": "武器菜单",
|
||||
"wp_skin_menu_skin_title": "选择 {lime}{0}{default} 的皮肤",
|
||||
"wp_skin_menu_select": "你选择了 {lime}{0}{default} 作为你的皮肤"
|
||||
}
|
||||
@@ -5,6 +5,8 @@ define('DB_NAME', '');
|
||||
define('DB_USER', '');
|
||||
define('DB_PASS', '');
|
||||
|
||||
define('WEB_STYLE_DARK', true);
|
||||
|
||||
define('STEAM_API_KEY', '');
|
||||
define('STEAM_DOMAIN_NAME', '');
|
||||
define('STEAM_LOGOUT_PAGE', '');
|
||||
|
||||
@@ -4,7 +4,14 @@ class DataBase {
|
||||
private $PDO;
|
||||
|
||||
public function __construct() {
|
||||
$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"));
|
||||
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"));
|
||||
}
|
||||
catch(PDOException $ex)
|
||||
{
|
||||
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>");
|
||||
}
|
||||
}
|
||||
public function select($query, $bindings = []) {
|
||||
$STH = $this->PDO->prepare($query);
|
||||
|
||||
@@ -62,7 +62,8 @@ class UtilsClass
|
||||
521,
|
||||
522,
|
||||
523,
|
||||
525
|
||||
525,
|
||||
526
|
||||
])
|
||||
)
|
||||
continue;
|
||||
@@ -88,7 +89,11 @@ class UtilsClass
|
||||
$selected = [];
|
||||
|
||||
foreach ($temp as $weapon) {
|
||||
$selected[$weapon['weapon_defindex']] = $weapon['weapon_paint_id'];
|
||||
$selected[$weapon['weapon_defindex']] = [
|
||||
'weapon_paint_id' => $weapon['weapon_paint_id'],
|
||||
'weapon_seed' => $weapon['weapon_seed'],
|
||||
'weapon_wear' => $weapon['weapon_wear'],
|
||||
];
|
||||
}
|
||||
|
||||
return $selected;
|
||||
|
||||
73
website/getskins.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
$weapons = array (
|
||||
"weapon_deagle" => 1,
|
||||
"weapon_elite" => 2,
|
||||
"weapon_fiveseven" => 3,
|
||||
"weapon_glock" => 4,
|
||||
"weapon_ak47" => 7,
|
||||
"weapon_aug" => 8,
|
||||
"weapon_awp" => 9,
|
||||
"weapon_famas" => 10,
|
||||
"weapon_g3sg1" => 10,
|
||||
"weapon_galilar" => 13,
|
||||
"weapon_m249" => 14,
|
||||
"weapon_m4a1" => 16,
|
||||
"weapon_mac10" => 17,
|
||||
"weapon_p90" => 19,
|
||||
"weapon_mp5sd" => 23,
|
||||
"weapon_ump45" => 24,
|
||||
"weapon_xm1014" => 25,
|
||||
"weapon_bizon" => 26,
|
||||
"weapon_mag7" => 27,
|
||||
"weapon_negev" => 28,
|
||||
"weapon_sawedoff" => 29,
|
||||
"weapon_tec9" => 30,
|
||||
"weapon_hkp2000" => 32,
|
||||
"weapon_mp7" => 33,
|
||||
"weapon_mp9" => 34,
|
||||
"weapon_nova" => 35,
|
||||
"weapon_p250" => 36,
|
||||
"weapon_scar20" => 38,
|
||||
"weapon_sg556" => 39,
|
||||
"weapon_ssg08" => 40,
|
||||
"weapon_m4a1_silencer" => 60,
|
||||
"weapon_usp_silencer" => 61,
|
||||
"weapon_cz75a" => 63,
|
||||
"weapon_revolver" => 64,
|
||||
"weapon_bayonet" => 500,
|
||||
"weapon_knife_css" => 503,
|
||||
"weapon_knife_flip" => 505,
|
||||
"weapon_knife_gut" => 506,
|
||||
"weapon_knife_karambit" => 507,
|
||||
"weapon_knife_m9_bayonet" => 508,
|
||||
"weapon_knife_tactical" => 509,
|
||||
"weapon_knife_falchion" => 512,
|
||||
"weapon_knife_survival_bowie"=> 514,
|
||||
"weapon_knife_butterfly" => 515,
|
||||
"weapon_knife_push" => 516,
|
||||
"weapon_knife_cord" => 517,
|
||||
"weapon_knife_canis" => 518,
|
||||
"weapon_knife_ursus" => 519,
|
||||
"weapon_knife_gypsy_jackknife" => 520,
|
||||
"weapon_knife_outdoor" => 521,
|
||||
"weapon_knife_stiletto" => 522,
|
||||
"weapon_knife_widowmaker" => 523,
|
||||
"weapon_knife_skeleton" => 525);
|
||||
$json = json_decode(file_get_contents('skins.json'));
|
||||
echo "<pre>";
|
||||
foreach($json as $skin)
|
||||
{
|
||||
if(!str_contains($skin->weapon->id, "weapon_")) continue;
|
||||
$name = $skin->name;
|
||||
$name = str_replace("'","\'",$name);
|
||||
$weapon = $skin->weapon->id;
|
||||
$image = $skin->image;
|
||||
$paint = $skin->paint_index;
|
||||
echo "('{$weapon}', {$weapons[$weapon]}, {$paint}, '{$image}', '{$name}')";
|
||||
echo ",<br>";
|
||||
|
||||
}
|
||||
//print_r($json);
|
||||
echo "</pre>";
|
||||
|
||||
?>
|
||||
BIN
website/img/skins/weapon_ak47-1004.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
website/img/skins/weapon_ak47-1018.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
website/img/skins/weapon_ak47-1035.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
website/img/skins/weapon_ak47-1070.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
website/img/skins/weapon_ak47-1087.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
website/img/skins/weapon_ak47-1141.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
website/img/skins/weapon_ak47-1143.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
website/img/skins/weapon_ak47-1171.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
website/img/skins/weapon_ak47-122.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
website/img/skins/weapon_ak47-1221.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
website/img/skins/weapon_ak47-1238.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
website/img/skins/weapon_ak47-14.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
website/img/skins/weapon_ak47-170.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
website/img/skins/weapon_ak47-172.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
website/img/skins/weapon_ak47-180.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
website/img/skins/weapon_ak47-226.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
website/img/skins/weapon_ak47-282.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
website/img/skins/weapon_ak47-300.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
website/img/skins/weapon_ak47-302.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
website/img/skins/weapon_ak47-316.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
website/img/skins/weapon_ak47-340.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
website/img/skins/weapon_ak47-341.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
website/img/skins/weapon_ak47-380.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
website/img/skins/weapon_ak47-394.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
website/img/skins/weapon_ak47-422.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
website/img/skins/weapon_ak47-44.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
website/img/skins/weapon_ak47-456.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
website/img/skins/weapon_ak47-474.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
website/img/skins/weapon_ak47-490.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
website/img/skins/weapon_ak47-506.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
website/img/skins/weapon_ak47-524.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
website/img/skins/weapon_ak47-600.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
website/img/skins/weapon_ak47-639.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
website/img/skins/weapon_ak47-656.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
website/img/skins/weapon_ak47-675.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
website/img/skins/weapon_ak47-707.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
website/img/skins/weapon_ak47-72.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
website/img/skins/weapon_ak47-724.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
website/img/skins/weapon_ak47-745.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
website/img/skins/weapon_ak47-795.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
website/img/skins/weapon_ak47-801.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
website/img/skins/weapon_ak47-836.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
website/img/skins/weapon_ak47-885.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
website/img/skins/weapon_ak47-921.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
website/img/skins/weapon_ak47-941.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
website/img/skins/weapon_ak47-959.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 83 KiB |