mirror of
https://github.com/Nereziel/cs2-WeaponPaints.git
synced 2026-02-25 04:42:47 +00:00
Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ff3fe9ecd | ||
|
|
2bc53cd3c0 | ||
|
|
c43f4bde80 | ||
|
|
7172dc344f | ||
|
|
a9fb5b241d | ||
|
|
179eb41e47 | ||
|
|
8b4d9dc676 | ||
|
|
2852623936 | ||
|
|
d9adaa4cd5 | ||
|
|
c91141516e | ||
|
|
399a56be12 | ||
|
|
692fcc905a | ||
|
|
3c4f06c4e2 | ||
|
|
a5723a4462 | ||
|
|
e9f47e9237 | ||
|
|
e209b12829 | ||
|
|
c55a40ecb1 | ||
|
|
b6cac17197 | ||
|
|
683f9f2a1c | ||
|
|
a70e2f771e | ||
|
|
f4e6a4338d | ||
|
|
edd3733940 | ||
|
|
492b8a7976 | ||
|
|
6db3d00893 | ||
|
|
fc79381e1e | ||
|
|
7b12d29227 | ||
|
|
abff60a1db | ||
|
|
edb848b4f9 | ||
|
|
694cc548c8 | ||
|
|
201f723a3c | ||
|
|
d6384f4ecf | ||
|
|
85fc0bd4bc | ||
|
|
5c7df833cc | ||
|
|
5640919b09 | ||
|
|
0550ef68f4 | ||
|
|
c0d42a3d9c | ||
|
|
5636b401ea | ||
|
|
06cfda21f2 | ||
|
|
771a832ae8 | ||
|
|
323c74b49c | ||
|
|
ee1dffa06b | ||
|
|
d90055ad89 | ||
|
|
48854c4eaf | ||
|
|
c06f7ae3be | ||
|
|
29461e9de2 | ||
|
|
74ec584d9a | ||
|
|
ec0d4f4d5a | ||
|
|
a8ba645292 | ||
|
|
e04dd312e8 | ||
|
|
702dea9450 | ||
|
|
c594cd534e | ||
|
|
5aaf0e6f62 | ||
|
|
942e776688 | ||
|
|
36046fee2d | ||
|
|
d6de0ce6c8 | ||
|
|
d2c19d8af8 | ||
|
|
0f6d334621 | ||
|
|
f99c9b2767 | ||
|
|
6a2d28c303 | ||
|
|
27a2ae5be9 | ||
|
|
0af9177f07 | ||
|
|
cfb49e1498 | ||
|
|
bbdb4b82ce | ||
|
|
bfb7defcaa | ||
|
|
5626c32d30 | ||
|
|
a6575e9ab2 | ||
|
|
683efbd0ae | ||
|
|
3bc9123a71 | ||
|
|
f75ea76deb | ||
|
|
bf0deda5d7 | ||
|
|
548fdb642d | ||
|
|
8cb9563994 | ||
|
|
e45714cb9a | ||
|
|
97e73bfd53 | ||
|
|
6dc047477c | ||
|
|
ced010645d | ||
|
|
b030d5c7e1 | ||
|
|
90771f76c7 | ||
|
|
ad8e51a403 | ||
|
|
8c1edddd1e | ||
|
|
6f86cddd13 | ||
|
|
24801e814b | ||
|
|
77def8a305 | ||
|
|
651fae4d23 | ||
|
|
692c22f7d1 | ||
|
|
cf07106641 | ||
|
|
44177f18fe |
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -58,12 +58,8 @@ jobs:
|
|||||||
${{ env.OUTPUT_PATH }}/McMaster.NETCore.Plugins.dll \
|
${{ env.OUTPUT_PATH }}/McMaster.NETCore.Plugins.dll \
|
||||||
${{ env.OUTPUT_PATH }}/Microsoft.DotNet.PlatformAbstractions.dll \
|
${{ env.OUTPUT_PATH }}/Microsoft.DotNet.PlatformAbstractions.dll \
|
||||||
${{ env.OUTPUT_PATH }}/Microsoft.Extensions.DependencyModel.dll \
|
${{ env.OUTPUT_PATH }}/Microsoft.Extensions.DependencyModel.dll \
|
||||||
- name: Copy skins.json
|
- name: Copy skins
|
||||||
run: cp website/data/skins.json ${{ env.OUTPUT_PATH }}/skins.json
|
run: cp -R website/data ${{ env.OUTPUT_PATH }}
|
||||||
- name: Copy gloves.json
|
|
||||||
run: cp website/data/gloves.json ${{ env.OUTPUT_PATH }}/gloves.json
|
|
||||||
- name: Copy agents.json
|
|
||||||
run: cp website/data/agents.json ${{ env.OUTPUT_PATH }}/agents.json
|
|
||||||
- name: Zip
|
- name: Zip
|
||||||
run: zip -r "${{ env.PROJECT_NAME }}.zip" "${{ env.OUTPUT_PATH }}" gamedata/
|
run: zip -r "${{ env.PROJECT_NAME }}.zip" "${{ env.OUTPUT_PATH }}" gamedata/
|
||||||
- name: Clean files Website
|
- name: Clean files Website
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
|||||||
bin/
|
bin/
|
||||||
obj/
|
obj/
|
||||||
website/getskins.php
|
website/getskins.php
|
||||||
|
.idea/
|
||||||
BIN
3rd_party/MenuManagerApi.dll
vendored
Normal file
BIN
3rd_party/MenuManagerApi.dll
vendored
Normal file
Binary file not shown.
993
Commands.cs
993
Commands.cs
File diff suppressed because it is too large
Load Diff
37
Config.cs
37
Config.cs
@@ -10,12 +10,19 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
[JsonPropertyName("GloveEnabled")]
|
[JsonPropertyName("GloveEnabled")]
|
||||||
public bool GloveEnabled { get; set; } = true;
|
public bool GloveEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonPropertyName("MusicEnabled")]
|
||||||
|
public bool MusicEnabled { get; set; } = true;
|
||||||
|
|
||||||
[JsonPropertyName("AgentEnabled")]
|
[JsonPropertyName("AgentEnabled")]
|
||||||
public bool AgentEnabled { get; set; } = true;
|
public bool AgentEnabled { get; set; } = true;
|
||||||
|
|
||||||
[JsonPropertyName("SkinEnabled")]
|
[JsonPropertyName("SkinEnabled")]
|
||||||
public bool SkinEnabled { get; set; } = true;
|
public bool SkinEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonPropertyName("PinsEnabled")]
|
||||||
|
public bool PinsEnabled { get; set; } = true;
|
||||||
|
|
||||||
[JsonPropertyName("CommandWpEnabled")]
|
[JsonPropertyName("CommandWpEnabled")]
|
||||||
public bool CommandWpEnabled { get; set; } = true;
|
public bool CommandWpEnabled { get; set; } = true;
|
||||||
|
|
||||||
@@ -23,24 +30,28 @@ namespace WeaponPaints
|
|||||||
public bool CommandKillEnabled { get; set; } = true;
|
public bool CommandKillEnabled { get; set; } = true;
|
||||||
|
|
||||||
[JsonPropertyName("CommandKnife")]
|
[JsonPropertyName("CommandKnife")]
|
||||||
public string CommandKnife { get; set; } = "knife";
|
public List<string> CommandKnife { get; set; } = ["knife"];
|
||||||
|
|
||||||
|
[JsonPropertyName("CommandMusic")]
|
||||||
|
public List<string> CommandMusic { get; set; } = ["music"];
|
||||||
|
|
||||||
[JsonPropertyName("CommandGlove")]
|
[JsonPropertyName("CommandGlove")]
|
||||||
public string CommandGlove { get; set; } = "gloves";
|
public List<string> CommandGlove { get; set; } = ["gloves"];
|
||||||
|
|
||||||
[JsonPropertyName("CommandAgent")]
|
[JsonPropertyName("CommandAgent")]
|
||||||
public string CommandAgent { get; set; } = "agents";
|
public List<string> CommandAgent { get; set; } = ["agents"];
|
||||||
|
|
||||||
[JsonPropertyName("CommandSkin")]
|
[JsonPropertyName("CommandSkin")]
|
||||||
public string CommandSkin { get; set; } = "ws";
|
public List<string> CommandSkin { get; set; } = ["ws"];
|
||||||
|
|
||||||
[JsonPropertyName("CommandSkinSelection")]
|
[JsonPropertyName("CommandSkinSelection")]
|
||||||
public string CommandSkinSelection { get; set; } = "skins";
|
public List<string> CommandSkinSelection { get; set; } = ["skins"];
|
||||||
|
|
||||||
[JsonPropertyName("CommandRefresh")]
|
[JsonPropertyName("CommandRefresh")]
|
||||||
public string CommandRefresh { get; set; } = "wp";
|
public List<string> CommandRefresh { get; set; } = ["wp"];
|
||||||
|
|
||||||
[JsonPropertyName("CommandKill")]
|
[JsonPropertyName("CommandKill")]
|
||||||
public string CommandKill { get; set; } = "kill";
|
public List<string> CommandKill { get; set; } = ["kill"];
|
||||||
|
|
||||||
[JsonPropertyName("GiveRandomKnife")]
|
[JsonPropertyName("GiveRandomKnife")]
|
||||||
public bool GiveRandomKnife { get; set; } = false;
|
public bool GiveRandomKnife { get; set; } = false;
|
||||||
@@ -54,7 +65,10 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
public class WeaponPaintsConfig : BasePluginConfig
|
public class WeaponPaintsConfig : BasePluginConfig
|
||||||
{
|
{
|
||||||
public override int Version { get; set; } = 6;
|
[JsonPropertyName("ConfigVersion")] public override int Version { get; set; } = 8;
|
||||||
|
|
||||||
|
[JsonPropertyName("SkinsLanguage")]
|
||||||
|
public string SkinsLanguage { get; set; } = "en";
|
||||||
|
|
||||||
[JsonPropertyName("DatabaseHost")]
|
[JsonPropertyName("DatabaseHost")]
|
||||||
public string DatabaseHost { get; set; } = "";
|
public string DatabaseHost { get; set; } = "";
|
||||||
@@ -72,15 +86,12 @@ namespace WeaponPaints
|
|||||||
public string DatabaseName { get; set; } = "";
|
public string DatabaseName { get; set; } = "";
|
||||||
|
|
||||||
[JsonPropertyName("CmdRefreshCooldownSeconds")]
|
[JsonPropertyName("CmdRefreshCooldownSeconds")]
|
||||||
public int CmdRefreshCooldownSeconds { get; set; } = 60;
|
public int CmdRefreshCooldownSeconds { get; set; } = 10;
|
||||||
|
|
||||||
[JsonPropertyName("Prefix")]
|
|
||||||
public string Prefix { get; set; } = "[WeaponPaints]";
|
|
||||||
|
|
||||||
[JsonPropertyName("Website")]
|
[JsonPropertyName("Website")]
|
||||||
public string Website { get; set; } = "example.com/skins";
|
public string Website { get; set; } = "example.com/skins";
|
||||||
|
|
||||||
[JsonPropertyName("Additional")]
|
[JsonPropertyName("Additional")]
|
||||||
public Additional Additional { get; set; } = new Additional();
|
public Additional Additional { get; set; } = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
17
Database.cs
17
Database.cs
@@ -1,26 +1,21 @@
|
|||||||
using MySqlConnector;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MySqlConnector;
|
||||||
|
|
||||||
namespace WeaponPaints
|
namespace WeaponPaints
|
||||||
{
|
{
|
||||||
public class Database
|
public class Database(string dbConnectionString)
|
||||||
{
|
{
|
||||||
private readonly string _dbConnectionString;
|
|
||||||
|
|
||||||
public Database(string dbConnectionString)
|
|
||||||
{
|
|
||||||
_dbConnectionString = dbConnectionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<MySqlConnection> GetConnectionAsync()
|
public async Task<MySqlConnection> GetConnectionAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var connection = new MySqlConnection(_dbConnectionString);
|
var connection = new MySqlConnection(dbConnectionString);
|
||||||
await connection.OpenAsync();
|
await connection.OpenAsync();
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
WeaponPaints.Instance.Logger.LogError($"Unable to connect to database: {ex.Message}");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
305
Events.cs
305
Events.cs
@@ -1,6 +1,8 @@
|
|||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||||
|
using CounterStrikeSharp.API.Modules.Entities;
|
||||||
|
using CounterStrikeSharp.API.Modules.Memory;
|
||||||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||||
|
|
||||||
namespace WeaponPaints
|
namespace WeaponPaints
|
||||||
@@ -12,10 +14,10 @@ namespace WeaponPaints
|
|||||||
{
|
{
|
||||||
CCSPlayerController? player = @event.Userid;
|
CCSPlayerController? player = @event.Userid;
|
||||||
|
|
||||||
if (player is null || !player.IsValid || player.IsBot || player.IsHLTV || player.SteamID.ToString().Length != 17 ||
|
if (player is null || !player.IsValid || player.IsBot ||
|
||||||
weaponSync == null || _database == null) return HookResult.Continue;
|
WeaponSync == null || Database == null) return HookResult.Continue;
|
||||||
|
|
||||||
PlayerInfo playerInfo = new PlayerInfo
|
var playerInfo = new PlayerInfo
|
||||||
{
|
{
|
||||||
UserId = player.UserId,
|
UserId = player.UserId,
|
||||||
Slot = player.Slot,
|
Slot = player.Slot,
|
||||||
@@ -27,34 +29,32 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<Task> tasks = new List<Task>();
|
_ = Task.Run(async () => await WeaponSync.GetPlayerData(playerInfo));
|
||||||
|
/*
|
||||||
if (Config.Additional.SkinEnabled)
|
if (Config.Additional.SkinEnabled)
|
||||||
{
|
{
|
||||||
tasks.Add(Task.Run(() => weaponSync.GetWeaponPaintsFromDatabase(playerInfo)));
|
_ = Task.Run(async () => await weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
|
||||||
}
|
}
|
||||||
if (Config.Additional.KnifeEnabled)
|
if (Config.Additional.KnifeEnabled)
|
||||||
{
|
{
|
||||||
tasks.Add(Task.Run(() => weaponSync.GetKnifeFromDatabase(playerInfo)));
|
_ = Task.Run(async () => await weaponSync.GetKnifeFromDatabase(playerInfo));
|
||||||
}
|
}
|
||||||
if (Config.Additional.GloveEnabled)
|
if (Config.Additional.GloveEnabled)
|
||||||
{
|
{
|
||||||
tasks.Add(Task.Run(() => weaponSync.GetGloveFromDatabase(playerInfo)));
|
_ = Task.Run(async () => await weaponSync.GetGloveFromDatabase(playerInfo));
|
||||||
}
|
}
|
||||||
if (Config.Additional.AgentEnabled)
|
if (Config.Additional.AgentEnabled)
|
||||||
{
|
{
|
||||||
tasks.Add(Task.Run(() => weaponSync.GetAgentFromDatabase(playerInfo)));
|
_ = Task.Run(async () => await weaponSync.GetAgentFromDatabase(playerInfo));
|
||||||
}
|
}
|
||||||
|
if (Config.Additional.MusicEnabled)
|
||||||
Task.WaitAll(tasks.ToArray());
|
|
||||||
}
|
|
||||||
catch (AggregateException ex)
|
|
||||||
{
|
|
||||||
// Handle the exception
|
|
||||||
foreach (var innerException in ex.InnerExceptions)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine($"An error occurred for player {player}: {innerException.Message}");
|
_ = Task.Run(async () => await weaponSync.GetMusicFromDatabase(playerInfo));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
@@ -63,12 +63,11 @@ namespace WeaponPaints
|
|||||||
[GameEventHandler]
|
[GameEventHandler]
|
||||||
public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
|
public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
|
||||||
{
|
{
|
||||||
CCSPlayerController player = @event.Userid;
|
CCSPlayerController? player = @event.Userid;
|
||||||
|
|
||||||
if (player is null || !player.IsValid || player.IsBot ||
|
if (player is null || !player.IsValid || player.IsBot) return HookResult.Continue;
|
||||||
player.IsHLTV || player.SteamID.ToString().Length != 17) return HookResult.Continue;
|
|
||||||
|
|
||||||
PlayerInfo playerInfo = new PlayerInfo
|
var playerInfo = new PlayerInfo
|
||||||
{
|
{
|
||||||
UserId = player.UserId,
|
UserId = player.UserId,
|
||||||
Slot = player.Slot,
|
Slot = player.Slot,
|
||||||
@@ -78,133 +77,56 @@ namespace WeaponPaints
|
|||||||
IpAddress = player.IpAddress?.Split(":")[0]
|
IpAddress = player.IpAddress?.Split(":")[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!GPlayerWeaponsInfo.TryGetValue(player.Slot, out var weaponInfos))
|
||||||
|
return HookResult.Continue;
|
||||||
|
|
||||||
|
if (WeaponSync != null)
|
||||||
|
_ = Task.Run(async () => await WeaponSync.SyncStatTrakToDatabase(playerInfo, weaponInfos));
|
||||||
|
|
||||||
if (Config.Additional.SkinEnabled)
|
if (Config.Additional.SkinEnabled)
|
||||||
{
|
{
|
||||||
gPlayerWeaponsInfo.TryRemove(player.Slot, out _);
|
GPlayerWeaponsInfo.TryRemove(player.Slot, out _);
|
||||||
}
|
}
|
||||||
if (Config.Additional.KnifeEnabled)
|
if (Config.Additional.KnifeEnabled)
|
||||||
{
|
{
|
||||||
g_playersKnife.TryRemove(player.Slot, out _);
|
GPlayersKnife.TryRemove(player.Slot, out _);
|
||||||
}
|
}
|
||||||
if (Config.Additional.GloveEnabled)
|
if (Config.Additional.GloveEnabled)
|
||||||
{
|
{
|
||||||
g_playersGlove.TryRemove(player.Slot, out _);
|
GPlayersGlove.TryRemove(player.Slot, out _);
|
||||||
}
|
}
|
||||||
if (Config.Additional.AgentEnabled)
|
if (Config.Additional.AgentEnabled)
|
||||||
{
|
{
|
||||||
g_playersAgent.TryRemove(player.Slot, out _);
|
GPlayersAgent.TryRemove(player.Slot, out _);
|
||||||
|
}
|
||||||
|
if (Config.Additional.MusicEnabled)
|
||||||
|
{
|
||||||
|
GPlayersMusic.TryRemove(player.Slot, out _);
|
||||||
|
}
|
||||||
|
if (Config.Additional.PinsEnabled)
|
||||||
|
{
|
||||||
|
GPlayersPin.TryRemove(player.Slot, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
commandsCooldown.Remove(player.Slot);
|
_temporaryPlayerWeaponWear.TryRemove(player.Slot, out _);
|
||||||
|
CommandsCooldown.Remove(player.Slot);
|
||||||
|
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivePlayerWeaponSkin(CCSPlayerController player, CBasePlayerWeapon weapon)
|
|
||||||
{
|
|
||||||
if (!Config.Additional.SkinEnabled) return;
|
|
||||||
|
|
||||||
if (player is null || weapon is null || !weapon.IsValid || !Utility.IsPlayerValid(player)) return;
|
|
||||||
|
|
||||||
if (!gPlayerWeaponsInfo.ContainsKey(player.Slot)) return;
|
|
||||||
|
|
||||||
bool isKnife = weapon.DesignerName.Contains("knife") || weapon.DesignerName.Contains("bayonet");
|
|
||||||
|
|
||||||
if (isKnife && !g_playersKnife.ContainsKey(player.Slot) || isKnife && g_playersKnife[player.Slot] == "weapon_knife") return;
|
|
||||||
|
|
||||||
int[] newPaints = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 };
|
|
||||||
|
|
||||||
if (isKnife)
|
|
||||||
{
|
|
||||||
var newDefIndex = WeaponDefindex.FirstOrDefault(x => x.Value == g_playersKnife[player.Slot]);
|
|
||||||
if (newDefIndex.Key == 0) return;
|
|
||||||
|
|
||||||
if (weapon.AttributeManager.Item.ItemDefinitionIndex != newDefIndex.Key)
|
|
||||||
{
|
|
||||||
SubclassChange(weapon, (ushort)newDefIndex.Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
weapon.AttributeManager.Item.ItemDefinitionIndex = (ushort)newDefIndex.Key;
|
|
||||||
weapon.AttributeManager.Item.EntityQuality = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
|
||||||
int fallbackPaintKit = 0;
|
|
||||||
|
|
||||||
if (_config.Additional.GiveRandomSkin &&
|
|
||||||
!gPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex))
|
|
||||||
{
|
|
||||||
// Random skins
|
|
||||||
weapon.AttributeManager.Item.ItemID = 16384;
|
|
||||||
weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF;
|
|
||||||
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
|
|
||||||
weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex);
|
|
||||||
weapon.FallbackSeed = 0;
|
|
||||||
weapon.FallbackWear = 0.000001f;
|
|
||||||
CAttributeList_SetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit);
|
|
||||||
|
|
||||||
fallbackPaintKit = weapon.FallbackPaintKit;
|
|
||||||
|
|
||||||
if (fallbackPaintKit == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!isKnife)
|
|
||||||
{
|
|
||||||
if (newPaints.Contains(fallbackPaintKit))
|
|
||||||
{
|
|
||||||
UpdatePlayerWeaponMeshGroupMask(player, weapon, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdatePlayerWeaponMeshGroupMask(player, weapon, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex)) return;
|
|
||||||
WeaponInfo weaponInfo = gPlayerWeaponsInfo[player.Slot][weaponDefIndex];
|
|
||||||
//Log($"Apply on {weapon.DesignerName}({weapon.AttributeManager.Item.ItemDefinitionIndex}) paint {gPlayerWeaponPaints[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} seed {gPlayerWeaponSeed[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} wear {gPlayerWeaponWear[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]}");
|
|
||||||
weapon.AttributeManager.Item.ItemID = 16384;
|
|
||||||
weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF;
|
|
||||||
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
|
|
||||||
weapon.FallbackPaintKit = weaponInfo.Paint;
|
|
||||||
weapon.FallbackSeed = weaponInfo.Seed;
|
|
||||||
weapon.FallbackWear = weaponInfo.Wear;
|
|
||||||
CAttributeList_SetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit);
|
|
||||||
|
|
||||||
fallbackPaintKit = weapon.FallbackPaintKit;
|
|
||||||
|
|
||||||
if (fallbackPaintKit == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!isKnife)
|
|
||||||
{
|
|
||||||
if (newPaints.Contains(fallbackPaintKit))
|
|
||||||
{
|
|
||||||
UpdatePlayerWeaponMeshGroupMask(player, weapon, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdatePlayerWeaponMeshGroupMask(player, weapon, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnMapStart(string mapName)
|
private void OnMapStart(string mapName)
|
||||||
{
|
{
|
||||||
if (!Config.Additional.KnifeEnabled && !Config.Additional.SkinEnabled && !Config.Additional.GloveEnabled) return;
|
if (Config.Additional is { KnifeEnabled: false, SkinEnabled: false, GloveEnabled: false }) return;
|
||||||
|
|
||||||
if (_database != null)
|
if (Database != null)
|
||||||
weaponSync = new WeaponSynchronization(_database, Config);
|
WeaponSync = new WeaponSynchronization(Database, Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HookResult OnPlayerSpawn(EventPlayerSpawn @event, GameEventInfo info)
|
private HookResult OnPlayerSpawn(EventPlayerSpawn @event, GameEventInfo info)
|
||||||
{
|
{
|
||||||
CCSPlayerController? player = @event.Userid;
|
CCSPlayerController? player = @event.Userid;
|
||||||
|
|
||||||
if (player is null || !player.IsValid || !Config.Additional.KnifeEnabled && !Config.Additional.GloveEnabled)
|
if (player is null || !player.IsValid || Config.Additional is { KnifeEnabled: false, GloveEnabled: false })
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
|
|
||||||
CCSPlayerPawn? pawn = player.PlayerPawn.Value;
|
CCSPlayerPawn? pawn = player.PlayerPawn.Value;
|
||||||
@@ -212,51 +134,45 @@ namespace WeaponPaints
|
|||||||
if (pawn == null || !pawn.IsValid)
|
if (pawn == null || !pawn.IsValid)
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
|
|
||||||
g_knifePickupCount[player.Slot] = 0;
|
GivePlayerMusicKit(player);
|
||||||
|
|
||||||
GivePlayerAgent(player);
|
GivePlayerAgent(player);
|
||||||
Server.NextFrame(() =>
|
GivePlayerGloves(player);
|
||||||
{
|
|
||||||
RefreshGloves(player);
|
|
||||||
});
|
|
||||||
|
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info)
|
private HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info)
|
||||||
{
|
{
|
||||||
g_bCommandsAllowed = false;
|
_gBCommandsAllowed = false;
|
||||||
|
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info)
|
private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info)
|
||||||
{
|
{
|
||||||
/*
|
_gBCommandsAllowed = true;
|
||||||
NativeAPI.IssueServerCommand("mp_t_default_melee \"\"");
|
|
||||||
NativeAPI.IssueServerCommand("mp_ct_default_melee \"\"");
|
|
||||||
NativeAPI.IssueServerCommand("mp_equipment_reset_rounds 0");
|
|
||||||
*/
|
|
||||||
g_bCommandsAllowed = true;
|
|
||||||
|
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HookResult OnGiveNamedItemPost(DynamicHook hook)
|
public HookResult OnGiveNamedItemPost(DynamicHook hook)
|
||||||
{
|
{
|
||||||
var itemServices = hook.GetParam<CCSPlayer_ItemServices>(0);
|
try
|
||||||
var weapon = hook.GetReturn<CBasePlayerWeapon>(0);
|
{
|
||||||
if (!weapon.DesignerName.Contains("weapon"))
|
var itemServices = hook.GetParam<CCSPlayer_ItemServices>(0);
|
||||||
return HookResult.Continue;
|
var weapon = hook.GetReturn<CBasePlayerWeapon>();
|
||||||
|
if (!weapon.DesignerName.Contains("weapon"))
|
||||||
|
return HookResult.Continue;
|
||||||
|
|
||||||
var player = GetPlayerFromItemServices(itemServices);
|
var player = GetPlayerFromItemServices(itemServices);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
GivePlayerWeaponSkin(player, weapon);
|
GivePlayerWeaponSkin(player, weapon);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEntitySpawned(CEntityInstance entity)
|
public void OnEntityCreated(CEntityInstance entity)
|
||||||
{
|
{
|
||||||
var designerName = entity.DesignerName;
|
var designerName = entity.DesignerName;
|
||||||
|
|
||||||
@@ -267,41 +183,118 @@ namespace WeaponPaints
|
|||||||
var weapon = new CBasePlayerWeapon(entity.Handle);
|
var weapon = new CBasePlayerWeapon(entity.Handle);
|
||||||
if (!weapon.IsValid) return;
|
if (!weapon.IsValid) return;
|
||||||
|
|
||||||
var player = Utilities.GetPlayerFromSteamId(weapon.OriginalOwnerXuidLow);
|
try
|
||||||
if (player == null || !Utility.IsPlayerValid(player)) return;
|
{
|
||||||
|
SteamID? steamid = null;
|
||||||
|
|
||||||
GivePlayerWeaponSkin(player, weapon);
|
if (weapon.OriginalOwnerXuidLow > 0)
|
||||||
|
steamid = new SteamID(weapon.OriginalOwnerXuidLow);
|
||||||
|
|
||||||
|
CCSPlayerController? player;
|
||||||
|
|
||||||
|
if (steamid != null && steamid.IsValid())
|
||||||
|
{
|
||||||
|
player = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == steamid.SteamId64);
|
||||||
|
|
||||||
|
if (player == null)
|
||||||
|
player = Utilities.GetPlayerFromSteamId(weapon.OriginalOwnerXuidLow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCSWeaponBaseGun gun = weapon.As<CCSWeaponBaseGun>();
|
||||||
|
player = Utilities.GetPlayerFromIndex((int)weapon.OwnerEntity.Index) ?? Utilities.GetPlayerFromIndex((int)gun.OwnerEntity.Value!.Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(player?.PlayerName)) return;
|
||||||
|
if (!Utility.IsPlayerValid(player)) return;
|
||||||
|
|
||||||
|
GivePlayerWeaponSkin(player, weapon);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTick()
|
private void OnTick()
|
||||||
{
|
{
|
||||||
|
if (!Config.Additional.ShowSkinImage) return;
|
||||||
|
|
||||||
foreach (var player in Utilities.GetPlayers().Where(p =>
|
foreach (var player in Utilities.GetPlayers().Where(p =>
|
||||||
p is not null && p.IsValid && p.PlayerPawn != null && p.PlayerPawn.IsValid &&
|
p is { IsValid: true, PlayerPawn.IsValid: true } &&
|
||||||
(LifeState_t)p.LifeState == LifeState_t.LIFE_ALIVE && p.SteamID.ToString().Length == 17
|
(LifeState_t)p.LifeState == LifeState_t.LIFE_ALIVE
|
||||||
&& !p.IsBot && !p.IsHLTV && p.Connected == PlayerConnectedState.PlayerConnected
|
&& !p.IsBot && p is { Connected: PlayerConnectedState.PlayerConnected }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (Config.Additional.ShowSkinImage && PlayerWeaponImage.TryGetValue(player.Slot, out string? value) && !string.IsNullOrEmpty(value))
|
if (_playerWeaponImage.TryGetValue(player.Slot, out var value) && !string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
player.PrintToCenterHtml("<img src='{PATH}'</img>".Replace("{PATH}", value));
|
player.PrintToCenterHtml("<img src='{PATH}'</img>".Replace("{PATH}", value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GameEventHandler]
|
||||||
|
public HookResult OnItemPickup(EventItemPickup @event, GameEventInfo _)
|
||||||
|
{
|
||||||
|
if (!IsWindows) return HookResult.Continue;
|
||||||
|
|
||||||
|
var player = @event.Userid;
|
||||||
|
if (player != null && player is { IsValid: true, Connected: PlayerConnectedState.PlayerConnected, PawnIsAlive: true, PlayerPawn.IsValid: true })
|
||||||
|
{
|
||||||
|
GiveOnItemPickup(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HookResult.Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
|
||||||
|
{
|
||||||
|
CCSPlayerController? player = @event.Attacker;
|
||||||
|
|
||||||
|
if (player is null || !player.IsValid)
|
||||||
|
return HookResult.Continue;
|
||||||
|
|
||||||
|
if (!GPlayerWeaponsInfo.TryGetValue(player.Slot, out _)) return HookResult.Continue;
|
||||||
|
|
||||||
|
CBasePlayerWeapon? weapon = player.PlayerPawn.Value?.WeaponServices?.ActiveWeapon.Value;
|
||||||
|
|
||||||
|
if (weapon == null) return HookResult.Continue;
|
||||||
|
|
||||||
|
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||||
|
|
||||||
|
if (!GPlayerWeaponsInfo[player.Slot].TryGetValue(weaponDefIndex, out var weaponInfo) || weaponInfo.Paint == 0)
|
||||||
|
return HookResult.Continue;
|
||||||
|
|
||||||
|
if (!weaponInfo.StatTrak) return HookResult.Continue;
|
||||||
|
|
||||||
|
weaponInfo.StatTrakCount += 1;
|
||||||
|
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "kill eater", ViewAsFloat((uint)weaponInfo.StatTrakCount));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "kill eater score type", 0);
|
||||||
|
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "kill eater", ViewAsFloat((uint)weaponInfo.StatTrakCount));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "kill eater score type", 0);
|
||||||
|
|
||||||
|
return HookResult.Continue;
|
||||||
|
}
|
||||||
|
|
||||||
private void RegisterListeners()
|
private void RegisterListeners()
|
||||||
{
|
{
|
||||||
RegisterListener<Listeners.OnMapStart>(OnMapStart);
|
RegisterListener<Listeners.OnMapStart>(OnMapStart);
|
||||||
|
|
||||||
RegisterEventHandler<EventPlayerSpawn>(OnPlayerSpawn);
|
RegisterEventHandler<EventPlayerSpawn>(OnPlayerSpawn);
|
||||||
RegisterEventHandler<EventRoundStart>(OnRoundStart, HookMode.Pre);
|
RegisterEventHandler<EventRoundStart>(OnRoundStart);
|
||||||
RegisterEventHandler<EventRoundEnd>(OnRoundEnd);
|
RegisterEventHandler<EventRoundEnd>(OnRoundEnd);
|
||||||
RegisterListener<Listeners.OnEntitySpawned>(OnEntitySpawned);
|
RegisterListener<Listeners.OnEntityCreated>(OnEntityCreated);
|
||||||
RegisterListener<Listeners.OnTick>(OnTick);
|
RegisterEventHandler<EventPlayerDeath>(OnPlayerDeath);
|
||||||
//VirtualFunctions.GiveNamedItemFunc.Hook(OnGiveNamedItemPost, HookMode.Post);
|
|
||||||
|
if (Config.Additional.ShowSkinImage)
|
||||||
|
RegisterListener<Listeners.OnTick>(OnTick);
|
||||||
|
|
||||||
|
if (!IsWindows)
|
||||||
|
VirtualFunctions.GiveNamedItemFunc.Hook(OnGiveNamedItemPost, HookMode.Post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ public static class PlayerExtensions
|
|||||||
public static void Print(this CCSPlayerController controller, string message)
|
public static void Print(this CCSPlayerController controller, string message)
|
||||||
{
|
{
|
||||||
if (WeaponPaints._localizer == null) return;
|
if (WeaponPaints._localizer == null) return;
|
||||||
|
|
||||||
StringBuilder _message = new(WeaponPaints._localizer["wp_prefix"]);
|
StringBuilder _message = new(WeaponPaints._localizer["wp_prefix"]);
|
||||||
_message.Append(message);
|
_message.Append(message);
|
||||||
controller.PrintToChat(_message.ToString());
|
controller.PrintToChat(_message.ToString());
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
public class PlayerInfo
|
public class PlayerInfo
|
||||||
{
|
{
|
||||||
public int Index { get; set; }
|
public int Index { get; set; }
|
||||||
public int Slot { get; set; }
|
public int Slot { get; init; }
|
||||||
public int? UserId { get; set; }
|
public int? UserId { get; set; }
|
||||||
public string? SteamId { get; set; }
|
public string? SteamId { get; init; }
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
public string? IpAddress { get; set; }
|
public string? IpAddress { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -19,12 +19,21 @@ Unfinished, unoptimized and not fully functional ugly demo weapon paints plugin
|
|||||||
- Added command **`!agents`** to show menu with agents
|
- Added command **`!agents`** to show menu with agents
|
||||||
- Translations support, submit a PR if you want to share your translation
|
- Translations support, submit a PR if you want to share your translation
|
||||||
|
|
||||||
|
## ⚙️ Requirements
|
||||||
|
**Ensure all the following dependencies are installed before proceeding**
|
||||||
|
- [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp)
|
||||||
|
- [PlayerSettings](https://github.com/NickFox007/PlayerSettingsCS2) - Required by MenuManagerCS2
|
||||||
|
- [AnyBaseLibCS2](https://github.com/NickFox007/AnyBaseLibCS2) - Required by PlayerSettings
|
||||||
|
- [MenuManagerCS2](https://github.com/NickFox007/MenuManagerCS2)
|
||||||
|
- MySQL database
|
||||||
|
|
||||||
## CS2 Server
|
## CS2 Server
|
||||||
- Have working CounterStrikeSharp (**with RUNTIME!**)
|
- Have working CounterStrikeSharp (**with RUNTIME!**)
|
||||||
- Download from Release and copy plugin to plugins
|
- Download from Release and copy plugin to plugins
|
||||||
- Run server with plugin, **it will generate config if installed correctly!**
|
- Run server with plugin, **it will generate config if installed correctly!**
|
||||||
- Edit `addons/counterstrikesharp/configs/`**`plugins/WeaponPaints/WeaponPaints.json`** include database credentials
|
- Edit `addons/counterstrikesharp/configs/`**`plugins/WeaponPaints/WeaponPaints.json`** include database credentials
|
||||||
- In `addons/counterstrikesharp/configs/`**`core.json`** set **FollowCS2ServerGuidelines** to **`false`**
|
- In `addons/counterstrikesharp/configs/`**`core.json`** set **FollowCS2ServerGuidelines** to **`false`**
|
||||||
|
- Copy from plugins folder gamedata file **`weaponpaints.json`** to folder **`addons/counterstrikesharp/gamedata/`**
|
||||||
|
|
||||||
## Plugin Configuration
|
## Plugin Configuration
|
||||||
<details>
|
<details>
|
||||||
@@ -65,13 +74,11 @@ Unfinished, unoptimized and not fully functional ugly demo weapon paints plugin
|
|||||||
"GiveRandomKnife": false, // Give random knife to players if they didn't choose
|
"GiveRandomKnife": false, // Give random knife to players if they didn't choose
|
||||||
"GiveRandomSkins": false // Give random skins to players if they didn't choose
|
"GiveRandomSkins": false // Give random skins to players if they didn't choose
|
||||||
},
|
},
|
||||||
|
</pre></code>
|
||||||
"ConfigVersion": 4 // Don't touch
|
|
||||||
}</pre></code>
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Web install
|
## Web install
|
||||||
- Requires PHP >= 7.4 ***(Tested on php ver **`8.2.3`** and nginx webserver)***
|
- Requires PHP >= 7.4 with curl and pdo_mysql ***(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.
|
- **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)***
|
- Copy website to web server ***(Folder `img` not needed)***
|
||||||
- Get [Steam API Key](https://steamcommunity.com/dev/apikey)
|
- Get [Steam API Key](https://steamcommunity.com/dev/apikey)
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
using CounterStrikeSharp.API;
|
|
||||||
using CounterStrikeSharp.API.Modules.Memory;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace WeaponPaints;
|
|
||||||
|
|
||||||
public class SchemaString<TSchemaClass> : NativeObject where TSchemaClass : NativeObject
|
|
||||||
{
|
|
||||||
internal SchemaString(TSchemaClass instance, string member) : base(Schema.GetSchemaValue<nint>(instance.Handle, typeof(TSchemaClass).Name!, member))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
internal unsafe void Set(string str)
|
|
||||||
{
|
|
||||||
var bytes = Encoding.UTF8.GetBytes(str);
|
|
||||||
|
|
||||||
for (var i = 0; i < bytes.Length; i++)
|
|
||||||
{
|
|
||||||
Unsafe.Write((void*)(Handle.ToInt64() + i), bytes[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Unsafe.Write((void*)(Handle.ToInt64() + bytes.Length), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
211
Utility.cs
211
Utility.cs
@@ -1,11 +1,9 @@
|
|||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Core.Translations;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MySqlConnector;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace WeaponPaints
|
namespace WeaponPaints
|
||||||
{
|
{
|
||||||
@@ -13,54 +11,73 @@ namespace WeaponPaints
|
|||||||
{
|
{
|
||||||
internal static WeaponPaintsConfig? Config { get; set; }
|
internal static WeaponPaintsConfig? Config { get; set; }
|
||||||
|
|
||||||
internal static string BuildDatabaseConnectionString()
|
|
||||||
{
|
|
||||||
if (Config == null) return string.Empty;
|
|
||||||
var builder = new MySqlConnectionStringBuilder
|
|
||||||
{
|
|
||||||
Server = Config.DatabaseHost,
|
|
||||||
UserID = Config.DatabaseUser,
|
|
||||||
Password = Config.DatabasePassword,
|
|
||||||
Database = Config.DatabaseName,
|
|
||||||
Port = (uint)Config.DatabasePort,
|
|
||||||
Pooling = true
|
|
||||||
};
|
|
||||||
|
|
||||||
return builder.ConnectionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static async Task CheckDatabaseTables()
|
internal static async Task CheckDatabaseTables()
|
||||||
{
|
{
|
||||||
if (WeaponPaints._database is null) return;
|
if (WeaponPaints.Database is null) return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var connection = await WeaponPaints._database.GetConnectionAsync();
|
await using var connection = await WeaponPaints.Database.GetConnectionAsync();
|
||||||
|
|
||||||
await using var transaction = await connection.BeginTransactionAsync();
|
await using var transaction = await connection.BeginTransactionAsync();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string[] createTableQueries = new[]
|
string[] createTableQueries =
|
||||||
{
|
[
|
||||||
@"CREATE TABLE IF NOT EXISTS `wp_player_skins` (
|
"""
|
||||||
`steamid` varchar(64) NOT NULL,
|
CREATE TABLE IF NOT EXISTS `wp_player_skins` (
|
||||||
`weapon_defindex` int(6) NOT NULL,
|
`steamid` varchar(18) NOT NULL,
|
||||||
`weapon_paint_id` int(6) NOT NULL,
|
`weapon_defindex` int(6) NOT NULL,
|
||||||
`weapon_wear` float NOT NULL DEFAULT 0.000001,
|
`weapon_paint_id` int(6) NOT NULL,
|
||||||
`weapon_seed` int(16) NOT NULL DEFAULT 0
|
`weapon_wear` float NOT NULL DEFAULT 0.000001,
|
||||||
) ENGINE=InnoDB",
|
`weapon_seed` int(16) NOT NULL DEFAULT 0,
|
||||||
@"CREATE TABLE IF NOT EXISTS `wp_player_knife` (
|
`weapon_nametag` VARCHAR(128) DEFAULT NULL,
|
||||||
`steamid` varchar(64) NOT NULL,
|
`weapon_stattrak` tinyint(1) NOT NULL,
|
||||||
|
`weapon_stattrak_count` int(10) NOT NULL,
|
||||||
|
`weapon_sticker_0` VARCHAR(128) NOT NULL DEFAULT '0;0;0;0;0;0;0' COMMENT 'id;schema;x;y;wear;scale;rotation',
|
||||||
|
`weapon_sticker_1` VARCHAR(128) NOT NULL DEFAULT '0;0;0;0;0;0;0' COMMENT 'id;schema;x;y;wear;scale;rotation',
|
||||||
|
`weapon_sticker_2` VARCHAR(128) NOT NULL DEFAULT '0;0;0;0;0;0;0' COMMENT 'id;schema;x;y;wear;scale;rotation',
|
||||||
|
`weapon_sticker_3` VARCHAR(128) NOT NULL DEFAULT '0;0;0;0;0;0;0' COMMENT 'id;schema;x;y;wear;scale;rotation',
|
||||||
|
`weapon_sticker_4` VARCHAR(128) NOT NULL DEFAULT '0;0;0;0;0;0;0' COMMENT 'id;schema;x;y;wear;scale;rotation',
|
||||||
|
`weapon_keychain`VARCHAR(128) NOT NULL DEFAULT '0;0;0;0;0' COMMENT 'id;x;y;z;seed'
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
@"CREATE TABLE IF NOT EXISTS `wp_player_knife` (
|
||||||
|
`steamid` varchar(18) NOT NULL,
|
||||||
`knife` varchar(64) NOT NULL,
|
`knife` varchar(64) NOT NULL,
|
||||||
UNIQUE (`steamid`)
|
UNIQUE (`steamid`)
|
||||||
) ENGINE = InnoDB",
|
) ENGINE = InnoDB",
|
||||||
@"CREATE TABLE IF NOT EXISTS `wp_player_gloves` (
|
"""
|
||||||
`steamid` varchar(64) NOT NULL,
|
CREATE TABLE IF NOT EXISTS `wp_player_gloves` (
|
||||||
`weapon_defindex` int(11) NOT NULL,
|
`steamid` varchar(18) NOT NULL,
|
||||||
UNIQUE (`steamid`)
|
`weapon_defindex` int(11) NOT NULL,
|
||||||
) ENGINE=InnoDB"
|
UNIQUE (`steamid`)
|
||||||
};
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
CREATE TABLE IF NOT EXISTS `wp_player_agents` (
|
||||||
|
`steamid` varchar(18) NOT NULL,
|
||||||
|
`agent_ct` varchar(64) DEFAULT NULL,
|
||||||
|
`agent_t` varchar(64) DEFAULT NULL,
|
||||||
|
UNIQUE (`steamid`)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
CREATE TABLE IF NOT EXISTS `wp_player_music` (
|
||||||
|
`steamid` varchar(64) NOT NULL,
|
||||||
|
`music_id` int(11) NOT NULL,
|
||||||
|
UNIQUE (`steamid`)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
CREATE TABLE IF NOT EXISTS `wp_player_pins` (
|
||||||
|
`steamid` varchar(64) NOT NULL,
|
||||||
|
`id` int(11) NOT NULL,
|
||||||
|
UNIQUE (`steamid`)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
];
|
||||||
|
|
||||||
foreach (var query in createTableQueries)
|
foreach (var query in createTableQueries)
|
||||||
{
|
{
|
||||||
@@ -83,51 +100,64 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
internal static bool IsPlayerValid(CCSPlayerController? player)
|
internal static bool IsPlayerValid(CCSPlayerController? player)
|
||||||
{
|
{
|
||||||
if (player is null) return false;
|
if (player is null || WeaponPaints.WeaponSync is null) return false;
|
||||||
|
|
||||||
return (player is not null && player.IsValid && !player.IsBot && !player.IsHLTV && player.UserId.HasValue
|
return player is { IsValid: true, IsBot: false, IsHLTV: false, UserId: not null };
|
||||||
&& WeaponPaints.weaponSync != null && player.Connected == PlayerConnectedState.PlayerConnected && player.SteamID.ToString().Length == 17);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void LoadSkinsFromFile(string filePath)
|
internal static void LoadSkinsFromFile(string filePath, ILogger logger)
|
||||||
{
|
{
|
||||||
|
var json = File.ReadAllText(filePath);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string json = File.ReadAllText(filePath);
|
|
||||||
var deserializedSkins = JsonConvert.DeserializeObject<List<JObject>>(json);
|
var deserializedSkins = JsonConvert.DeserializeObject<List<JObject>>(json);
|
||||||
WeaponPaints.skinsList = deserializedSkins ?? new List<JObject>();
|
WeaponPaints.SkinsList = deserializedSkins ?? [];
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
throw;
|
logger?.LogError("Not found \"skins.json\" file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void LoadGlovesFromFile(string filePath)
|
internal static void LoadGlovesFromFile(string filePath, ILogger logger)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string json = File.ReadAllText(filePath);
|
var json = File.ReadAllText(filePath);
|
||||||
var deserializedSkins = JsonConvert.DeserializeObject<List<JObject>>(json);
|
var deserializedSkins = JsonConvert.DeserializeObject<List<JObject>>(json);
|
||||||
WeaponPaints.glovesList = deserializedSkins ?? new List<JObject>();
|
WeaponPaints.GlovesList = deserializedSkins ?? [];
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
throw;
|
logger?.LogError("Not found \"gloves.json\" file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void LoadAgentsFromFile(string filePath)
|
internal static void LoadAgentsFromFile(string filePath, ILogger logger)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string json = File.ReadAllText(filePath);
|
var json = File.ReadAllText(filePath);
|
||||||
var deserializedSkins = JsonConvert.DeserializeObject<List<JObject>>(json);
|
var deserializedSkins = JsonConvert.DeserializeObject<List<JObject>>(json);
|
||||||
WeaponPaints.agentsList = deserializedSkins ?? new List<JObject>();
|
WeaponPaints.AgentsList = deserializedSkins ?? [];
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
throw;
|
logger?.LogError("Not found \"agents.json\" file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LoadMusicFromFile(string filePath, ILogger logger)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = File.ReadAllText(filePath);
|
||||||
|
var deserializedSkins = JsonConvert.DeserializeObject<List<JObject>>(json);
|
||||||
|
WeaponPaints.MusicList = deserializedSkins ?? [];
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
logger?.LogError("Not found \"music.json\" file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,69 +171,50 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
internal static string ReplaceTags(string message)
|
internal static string ReplaceTags(string message)
|
||||||
{
|
{
|
||||||
if (message.Contains('{'))
|
return message.ReplaceColorTags();
|
||||||
{
|
|
||||||
string modifiedValue = message;
|
|
||||||
if (Config != null)
|
|
||||||
{
|
|
||||||
modifiedValue = modifiedValue.Replace("{WEBSITE}", Config.Website);
|
|
||||||
}
|
|
||||||
foreach (FieldInfo field in typeof(ChatColors).GetFields())
|
|
||||||
{
|
|
||||||
string pattern = $"{{{field.Name}}}";
|
|
||||||
if (message.Contains(pattern, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
modifiedValue = modifiedValue.Replace(pattern, field.GetValue(null)!.ToString(), StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return modifiedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task CheckVersion(string version, ILogger logger)
|
internal static async Task CheckVersion(string version, ILogger logger)
|
||||||
{
|
{
|
||||||
using (HttpClient client = new HttpClient())
|
using HttpClient client = new();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
var response = await client.GetAsync("https://raw.githubusercontent.com/Nereziel/cs2-WeaponPaints/main/VERSION").ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await client.GetAsync("https://raw.githubusercontent.com/Nereziel/cs2-WeaponPaints/main/VERSION").ConfigureAwait(false);
|
var remoteVersion = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
remoteVersion = remoteVersion.Trim();
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
var comparisonResult = string.CompareOrdinal(version, remoteVersion);
|
||||||
|
|
||||||
|
switch (comparisonResult)
|
||||||
{
|
{
|
||||||
string remoteVersion = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
case < 0:
|
||||||
remoteVersion = remoteVersion.Trim();
|
|
||||||
|
|
||||||
int comparisonResult = string.Compare(version, remoteVersion);
|
|
||||||
|
|
||||||
if (comparisonResult < 0)
|
|
||||||
{
|
|
||||||
logger.LogWarning("Plugin is outdated! Check https://github.com/Nereziel/cs2-WeaponPaints");
|
logger.LogWarning("Plugin is outdated! Check https://github.com/Nereziel/cs2-WeaponPaints");
|
||||||
}
|
break;
|
||||||
else if (comparisonResult > 0)
|
case > 0:
|
||||||
{
|
|
||||||
logger.LogInformation("Probably dev version detected");
|
logger.LogInformation("Probably dev version detected");
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
{
|
|
||||||
logger.LogInformation("Plugin is up to date");
|
logger.LogInformation("Plugin is up to date");
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.LogWarning("Failed to check version");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
else
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "Failed to connect to the version server.");
|
logger.LogWarning("Failed to check version");
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.LogError(ex, "An error occurred while checking version.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "Failed to connect to the version server.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An error occurred while checking version.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ShowAd(string moduleVersion)
|
internal static void ShowAd(string moduleVersion)
|
||||||
|
|||||||
166
Variables.cs
Normal file
166
Variables.cs
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using CounterStrikeSharp.API.Core;
|
||||||
|
using CounterStrikeSharp.API.Core.Capabilities;
|
||||||
|
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||||
|
using MenuManager;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace WeaponPaints;
|
||||||
|
|
||||||
|
public partial class WeaponPaints
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, string> WeaponList = new()
|
||||||
|
{
|
||||||
|
{"weapon_deagle", "Desert Eagle"},
|
||||||
|
{"weapon_elite", "Dual Berettas"},
|
||||||
|
{"weapon_fiveseven", "Five-SeveN"},
|
||||||
|
{"weapon_glock", "Glock-18"},
|
||||||
|
{"weapon_ak47", "AK-47"},
|
||||||
|
{"weapon_aug", "AUG"},
|
||||||
|
{"weapon_awp", "AWP"},
|
||||||
|
{"weapon_famas", "FAMAS"},
|
||||||
|
{"weapon_g3sg1", "G3SG1"},
|
||||||
|
{"weapon_galilar", "Galil AR"},
|
||||||
|
{"weapon_m249", "M249"},
|
||||||
|
{"weapon_m4a1", "M4A1"},
|
||||||
|
{"weapon_mac10", "MAC-10"},
|
||||||
|
{"weapon_p90", "P90"},
|
||||||
|
{"weapon_mp5sd", "MP5-SD"},
|
||||||
|
{"weapon_ump45", "UMP-45"},
|
||||||
|
{"weapon_xm1014", "XM1014"},
|
||||||
|
{"weapon_bizon", "PP-Bizon"},
|
||||||
|
{"weapon_mag7", "MAG-7"},
|
||||||
|
{"weapon_negev", "Negev"},
|
||||||
|
{"weapon_sawedoff", "Sawed-Off"},
|
||||||
|
{"weapon_tec9", "Tec-9"},
|
||||||
|
{"weapon_taser", "Zeus x27"},
|
||||||
|
{"weapon_hkp2000", "P2000"},
|
||||||
|
{"weapon_mp7", "MP7"},
|
||||||
|
{"weapon_mp9", "MP9"},
|
||||||
|
{"weapon_nova", "Nova"},
|
||||||
|
{"weapon_p250", "P250"},
|
||||||
|
{"weapon_scar20", "SCAR-20"},
|
||||||
|
{"weapon_sg556", "SG 553"},
|
||||||
|
{"weapon_ssg08", "SSG 08"},
|
||||||
|
{"weapon_m4a1_silencer", "M4A1-S"},
|
||||||
|
{"weapon_usp_silencer", "USP-S"},
|
||||||
|
{"weapon_cz75a", "CZ75-Auto"},
|
||||||
|
{"weapon_revolver", "R8 Revolver"},
|
||||||
|
{ "weapon_knife", "Default Knife" },
|
||||||
|
{ "weapon_knife_m9_bayonet", "M9 Bayonet" },
|
||||||
|
{ "weapon_knife_karambit", "Karambit" },
|
||||||
|
{ "weapon_bayonet", "Bayonet" },
|
||||||
|
{ "weapon_knife_survival_bowie", "Bowie Knife" },
|
||||||
|
{ "weapon_knife_butterfly", "Butterfly Knife" },
|
||||||
|
{ "weapon_knife_falchion", "Falchion Knife" },
|
||||||
|
{ "weapon_knife_flip", "Flip Knife" },
|
||||||
|
{ "weapon_knife_gut", "Gut Knife" },
|
||||||
|
{ "weapon_knife_tactical", "Huntsman Knife" },
|
||||||
|
{ "weapon_knife_push", "Shadow Daggers" },
|
||||||
|
{ "weapon_knife_gypsy_jackknife", "Navaja Knife" },
|
||||||
|
{ "weapon_knife_stiletto", "Stiletto Knife" },
|
||||||
|
{ "weapon_knife_widowmaker", "Talon Knife" },
|
||||||
|
{ "weapon_knife_ursus", "Ursus Knife" },
|
||||||
|
{ "weapon_knife_css", "Classic Knife" },
|
||||||
|
{ "weapon_knife_cord", "Paracord Knife" },
|
||||||
|
{ "weapon_knife_canis", "Survival Knife" },
|
||||||
|
{ "weapon_knife_outdoor", "Nomad Knife" },
|
||||||
|
{ "weapon_knife_skeleton", "Skeleton Knife" },
|
||||||
|
{ "weapon_knife_kukri", "Kukri Knife" }
|
||||||
|
};
|
||||||
|
|
||||||
|
public static IStringLocalizer? _localizer;
|
||||||
|
internal static readonly ConcurrentDictionary<int, string> GPlayersKnife = new();
|
||||||
|
internal static readonly ConcurrentDictionary<int, ushort> GPlayersGlove = new();
|
||||||
|
internal static readonly ConcurrentDictionary<int, ushort> GPlayersMusic = new();
|
||||||
|
internal static readonly ConcurrentDictionary<int, ushort> GPlayersPin = new();
|
||||||
|
public static readonly ConcurrentDictionary<int, (string? CT, string? T)> GPlayersAgent = new();
|
||||||
|
internal static readonly ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>> GPlayerWeaponsInfo = new();
|
||||||
|
internal static List<JObject> SkinsList = [];
|
||||||
|
internal static List<JObject> GlovesList = [];
|
||||||
|
internal static List<JObject> AgentsList = [];
|
||||||
|
internal static List<JObject> MusicList = [];
|
||||||
|
internal static WeaponSynchronization? WeaponSync;
|
||||||
|
private static bool _gBCommandsAllowed = true;
|
||||||
|
private readonly Dictionary<int, string> _playerWeaponImage = new();
|
||||||
|
|
||||||
|
private static readonly Dictionary<int, DateTime> CommandsCooldown = new();
|
||||||
|
internal static Database? Database;
|
||||||
|
|
||||||
|
private static readonly MemoryFunctionVoid<nint, string, float> CAttributeListSetOrAddAttributeValueByName = new(GameData.GetSignature("CAttributeList_SetOrAddAttributeValueByName"));
|
||||||
|
|
||||||
|
private static readonly MemoryFunctionWithReturn<nint, string, int, int> SetBodygroupFunc = new(
|
||||||
|
GameData.GetSignature("CBaseModelEntity_SetBodygroup"));
|
||||||
|
|
||||||
|
private static readonly Func<nint, string, int, int> SetBodygroup = SetBodygroupFunc.Invoke;
|
||||||
|
|
||||||
|
private static Dictionary<int, string> WeaponDefindex { get; } = new()
|
||||||
|
{
|
||||||
|
{ 1, "weapon_deagle" },
|
||||||
|
{ 2, "weapon_elite" },
|
||||||
|
{ 3, "weapon_fiveseven" },
|
||||||
|
{ 4, "weapon_glock" },
|
||||||
|
{ 7, "weapon_ak47" },
|
||||||
|
{ 8, "weapon_aug" },
|
||||||
|
{ 9, "weapon_awp" },
|
||||||
|
{ 10, "weapon_famas" },
|
||||||
|
{ 11, "weapon_g3sg1" },
|
||||||
|
{ 13, "weapon_galilar" },
|
||||||
|
{ 14, "weapon_m249" },
|
||||||
|
{ 16, "weapon_m4a1" },
|
||||||
|
{ 17, "weapon_mac10" },
|
||||||
|
{ 19, "weapon_p90" },
|
||||||
|
{ 23, "weapon_mp5sd" },
|
||||||
|
{ 24, "weapon_ump45" },
|
||||||
|
{ 25, "weapon_xm1014" },
|
||||||
|
{ 26, "weapon_bizon" },
|
||||||
|
{ 27, "weapon_mag7" },
|
||||||
|
{ 28, "weapon_negev" },
|
||||||
|
{ 29, "weapon_sawedoff" },
|
||||||
|
{ 30, "weapon_tec9" },
|
||||||
|
{ 31, "weapon_taser" },
|
||||||
|
{ 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" },
|
||||||
|
{ 526, "weapon_knife_kukri" }
|
||||||
|
};
|
||||||
|
|
||||||
|
private const ulong MinimumCustomItemId = 65578;
|
||||||
|
private ulong _nextItemId = MinimumCustomItemId;
|
||||||
|
private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<int, ConcurrentDictionary<int, float>> _temporaryPlayerWeaponWear = new();
|
||||||
|
|
||||||
|
internal static IMenuApi? MenuApi;
|
||||||
|
private static readonly PluginCapability<IMenuApi> MenuCapability = new("menu:nfcore");
|
||||||
|
}
|
||||||
466
WeaponAction.cs
466
WeaponAction.cs
@@ -5,27 +5,208 @@ using CounterStrikeSharp.API.Modules.Memory;
|
|||||||
using CounterStrikeSharp.API.Modules.Timers;
|
using CounterStrikeSharp.API.Modules.Timers;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Modules.Utils;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace WeaponPaints
|
namespace WeaponPaints
|
||||||
{
|
{
|
||||||
public partial class WeaponPaints
|
public partial class WeaponPaints
|
||||||
{
|
{
|
||||||
internal static void GiveKnifeToPlayer(CCSPlayerController? player)
|
private void GivePlayerWeaponSkin(CCSPlayerController player, CBasePlayerWeapon weapon)
|
||||||
|
{
|
||||||
|
if (!Config.Additional.SkinEnabled) return;
|
||||||
|
if (!GPlayerWeaponsInfo.TryGetValue(player.Slot, out _)) return;
|
||||||
|
|
||||||
|
bool isKnife = weapon.DesignerName.Contains("knife") || weapon.DesignerName.Contains("bayonet");
|
||||||
|
|
||||||
|
if (isKnife && !GPlayersKnife.ContainsKey(player.Slot) || isKnife && GPlayersKnife[player.Slot] == "weapon_knife") return;
|
||||||
|
|
||||||
|
int[] newPaints = { 106, 112, 113, 114, 115, 117, 118, 120, 121, 123, 126, 127, 128, 129, 130, 131, 133, 134, 137, 138, 139, 140, 142, 144, 145, 146, 152, 160, 161, 163, 173, 239, 292, 324, 331, 412, 461, 513, 766, 768, 770, 773, 774, 830, 831, 832, 834, 874, 875, 877, 878, 882, 883, 901, 912, 936, 937, 938, 939, 940, 1054, 1062, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1177, 1178, 1179, 1180 };
|
||||||
|
|
||||||
|
if (isKnife)
|
||||||
|
{
|
||||||
|
var newDefIndex = WeaponDefindex.FirstOrDefault(x => x.Value == GPlayersKnife[player.Slot]);
|
||||||
|
if (newDefIndex.Key == 0) return;
|
||||||
|
|
||||||
|
if (weapon.AttributeManager.Item.ItemDefinitionIndex != newDefIndex.Key)
|
||||||
|
{
|
||||||
|
SubclassChange(weapon, (ushort)newDefIndex.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
weapon.AttributeManager.Item.ItemDefinitionIndex = (ushort)newDefIndex.Key;
|
||||||
|
weapon.AttributeManager.Item.EntityQuality = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdatePlayerEconItemId(weapon.AttributeManager.Item);
|
||||||
|
|
||||||
|
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||||
|
int fallbackPaintKit = 0;
|
||||||
|
|
||||||
|
weapon.AttributeManager.Item.AccountID = (uint)player.SteamID;
|
||||||
|
|
||||||
|
if (_config.Additional.GiveRandomSkin &&
|
||||||
|
!GPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex))
|
||||||
|
{
|
||||||
|
// Random skins
|
||||||
|
weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex);
|
||||||
|
weapon.FallbackSeed = 0;
|
||||||
|
weapon.FallbackWear = 0.01f;
|
||||||
|
|
||||||
|
weapon.AttributeManager.Item.NetworkedDynamicAttributes.Attributes.RemoveAll();
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", GetRandomPaint(weaponDefIndex));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture seed", 0);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture wear", 0.01f);
|
||||||
|
|
||||||
|
weapon.AttributeManager.Item.AttributeList.Attributes.RemoveAll();
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture prefab", GetRandomPaint(weaponDefIndex));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture seed", 0);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture wear", 0.01f);
|
||||||
|
|
||||||
|
fallbackPaintKit = weapon.FallbackPaintKit;
|
||||||
|
|
||||||
|
if (fallbackPaintKit == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isKnife) return;
|
||||||
|
UpdatePlayerWeaponMeshGroupMask(player, weapon, !newPaints.Contains(fallbackPaintKit));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GPlayerWeaponsInfo[player.Slot].TryGetValue(weaponDefIndex, out var value) || value.Paint == 0) return;
|
||||||
|
|
||||||
|
var weaponInfo = value;
|
||||||
|
//Log($"Apply on {weapon.DesignerName}({weapon.AttributeManager.Item.ItemDefinitionIndex}) paint {gPlayerWeaponPaints[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} seed {gPlayerWeaponSeed[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} wear {gPlayerWeaponWear[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]}");
|
||||||
|
|
||||||
|
weapon.AttributeManager.Item.ItemID = 16384;
|
||||||
|
weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF;
|
||||||
|
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
|
||||||
|
weapon.AttributeManager.Item.CustomName = weaponInfo.Nametag;
|
||||||
|
weapon.FallbackPaintKit = weaponInfo.Paint;
|
||||||
|
weapon.FallbackSeed = weaponInfo.Seed;
|
||||||
|
weapon.FallbackWear = weaponInfo.Wear;
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit);
|
||||||
|
|
||||||
|
if (weaponInfo.StatTrak)
|
||||||
|
{
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "kill eater", ViewAsFloat((uint)weaponInfo.StatTrakCount));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "kill eater score type", 0);
|
||||||
|
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "kill eater", ViewAsFloat((uint)weaponInfo.StatTrakCount));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "kill eater score type", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fallbackPaintKit = weapon.FallbackPaintKit;
|
||||||
|
|
||||||
|
if (fallbackPaintKit == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isKnife) return;
|
||||||
|
|
||||||
|
if (weaponInfo.Stickers.Count > 0) SetStickers(player, weapon);
|
||||||
|
if (weaponInfo.KeyChain != null) SetKeychain(player, weapon);
|
||||||
|
|
||||||
|
UpdatePlayerWeaponMeshGroupMask(player, weapon, !newPaints.Contains(fallbackPaintKit));
|
||||||
|
}
|
||||||
|
|
||||||
|
// silly method to update sticker when call RefreshWeapons()
|
||||||
|
private void IncrementWearForWeaponWithStickers(CCSPlayerController player, CBasePlayerWeapon weapon)
|
||||||
|
{
|
||||||
|
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||||
|
if (!GPlayerWeaponsInfo.TryGetValue(player.Slot, out var playerWeapons) ||
|
||||||
|
!playerWeapons.TryGetValue(weaponDefIndex, out var weaponInfo) ||
|
||||||
|
weaponInfo.Stickers.Count <= 0) return;
|
||||||
|
|
||||||
|
float wearIncrement = 0.001f;
|
||||||
|
float currentWear = weaponInfo.Wear;
|
||||||
|
|
||||||
|
var playerWear = _temporaryPlayerWeaponWear.GetOrAdd(player.Slot, _ => new ConcurrentDictionary<int, float>());
|
||||||
|
|
||||||
|
float incrementedWear = playerWear.AddOrUpdate(
|
||||||
|
weaponDefIndex,
|
||||||
|
currentWear + wearIncrement,
|
||||||
|
(_, oldWear) => Math.Min(oldWear + wearIncrement, 1.0f)
|
||||||
|
);
|
||||||
|
|
||||||
|
weapon.FallbackWear = incrementedWear;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetStickers(CCSPlayerController? player, CBasePlayerWeapon weapon)
|
||||||
|
{
|
||||||
|
if (player == null || !player.IsValid) return;
|
||||||
|
|
||||||
|
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||||
|
|
||||||
|
if (!GPlayerWeaponsInfo.TryGetValue(player.Slot, out var playerWeapons) ||
|
||||||
|
!playerWeapons.TryGetValue(weaponDefIndex, out var weaponInfo))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var sticker in weaponInfo.Stickers)
|
||||||
|
{
|
||||||
|
int stickerSlot = weaponInfo.Stickers.IndexOf(sticker);
|
||||||
|
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
$"sticker slot {stickerSlot} id", ViewAsFloat(sticker.Id));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
$"sticker slot {stickerSlot} schema", sticker.Schema);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
$"sticker slot {stickerSlot} offset x", sticker.OffsetX);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
$"sticker slot {stickerSlot} offset y", sticker.OffsetY);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
$"sticker slot {stickerSlot} wear", sticker.Wear);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
$"sticker slot {stickerSlot} scale", sticker.Scale);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
$"sticker slot {stickerSlot} rotation", sticker.Rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_temporaryPlayerWeaponWear.TryGetValue(player.Slot, out var playerWear) &&
|
||||||
|
playerWear.TryGetValue(weaponDefIndex, out float storedWear))
|
||||||
|
{
|
||||||
|
weapon.FallbackWear = storedWear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetKeychain(CCSPlayerController? player, CBasePlayerWeapon weapon)
|
||||||
|
{
|
||||||
|
if (player == null || !player.IsValid) return;
|
||||||
|
|
||||||
|
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
||||||
|
|
||||||
|
if (!GPlayerWeaponsInfo.TryGetValue(player.Slot, out var playerWeaponsInfo) ||
|
||||||
|
!playerWeaponsInfo.TryGetValue(weaponDefIndex, out var value) ||
|
||||||
|
value.KeyChain == null) return;
|
||||||
|
var keyChain = value.KeyChain;
|
||||||
|
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
"keychain slot 0 id", ViewAsFloat(keyChain.Id));
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
"keychain slot 0 offset x", keyChain.OffsetX);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
"keychain slot 0 offset y", keyChain.OffsetY);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
"keychain slot 0 offset z", keyChain.OffsetZ);
|
||||||
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
||||||
|
"keychain slot 0 seed", keyChain.Seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GiveKnifeToPlayer(CCSPlayerController? player)
|
||||||
{
|
{
|
||||||
if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return;
|
if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return;
|
||||||
|
|
||||||
if (PlayerHasKnife(player)) return;
|
if (PlayerHasKnife(player)) return;
|
||||||
|
|
||||||
string knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife";
|
//string knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife";
|
||||||
player.GiveNamedItem(CsItem.Knife);
|
player.GiveNamedItem(CsItem.Knife);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool PlayerHasKnife(CCSPlayerController? player)
|
private static bool PlayerHasKnife(CCSPlayerController? player)
|
||||||
{
|
{
|
||||||
if (!_config.Additional.KnifeEnabled) return false;
|
if (!_config.Additional.KnifeEnabled) return false;
|
||||||
|
|
||||||
if (player == null || !player.IsValid || player.PlayerPawn == null || !player.PlayerPawn.IsValid)
|
if (player == null || !player.IsValid || !player.PlayerPawn.IsValid)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -37,129 +218,92 @@ namespace WeaponPaints
|
|||||||
if (weapons == null) return false;
|
if (weapons == null) return false;
|
||||||
foreach (var weapon in weapons)
|
foreach (var weapon in weapons)
|
||||||
{
|
{
|
||||||
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
|
if (!weapon.IsValid || weapon.Value == null || !weapon.Value.IsValid) continue;
|
||||||
|
if (weapon.Value.DesignerName.Contains("knife") || weapon.Value.DesignerName.Contains("bayonet"))
|
||||||
{
|
{
|
||||||
if (weapon.Value.DesignerName.Contains("knife") || weapon.Value.DesignerName.Contains("bayonet"))
|
return true;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RefreshWeapons(CCSPlayerController? player)
|
private void RefreshWeapons(CCSPlayerController? player)
|
||||||
{
|
{
|
||||||
if (!g_bCommandsAllowed) return;
|
if (!_gBCommandsAllowed) return;
|
||||||
if (player == null || !player.IsValid || player.PlayerPawn?.Value == null || (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE)
|
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE)
|
||||||
return;
|
return;
|
||||||
if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null)
|
if (player.PlayerPawn.Value.WeaponServices == null || player.PlayerPawn.Value.ItemServices == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var weapons = player.PlayerPawn.Value.WeaponServices.MyWeapons;
|
var weapons = player.PlayerPawn.Value.WeaponServices.MyWeapons;
|
||||||
|
|
||||||
if (weapons == null || weapons.Count == 0)
|
if (weapons.Count == 0)
|
||||||
return;
|
return;
|
||||||
if (player.Team == CsTeam.None || player.Team == CsTeam.Spectator)
|
if (player.Team is CsTeam.None or CsTeam.Spectator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int playerTeam = player.TeamNum;
|
int playerTeam = player.TeamNum;
|
||||||
|
|
||||||
Dictionary<string, List<(int, int)>> weaponsWithAmmo = new Dictionary<string, List<(int, int)>>();
|
Dictionary<string, List<(int, int)>> weaponsWithAmmo = [];
|
||||||
|
|
||||||
foreach (var weapon in weapons)
|
foreach (var weapon in weapons)
|
||||||
{
|
{
|
||||||
if (weapon == null || !weapon.IsValid || weapon.Value == null ||
|
if (!weapon.IsValid || weapon.Value == null ||
|
||||||
!weapon.Value.IsValid || !weapon.Value.DesignerName.Contains("weapon_"))
|
!weapon.Value.IsValid || !weapon.Value.DesignerName.Contains("weapon_"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CCSWeaponBaseGun gun = weapon.Value.As<CCSWeaponBaseGun>();
|
CCSWeaponBaseGun gun = weapon.Value.As<CCSWeaponBaseGun>();
|
||||||
|
|
||||||
if (weapon.Value.Entity == null) continue;
|
if (weapon.Value.Entity == null) continue;
|
||||||
if (weapon.Value.OwnerEntity == null) continue;
|
|
||||||
if (!weapon.Value.OwnerEntity.IsValid) continue;
|
if (!weapon.Value.OwnerEntity.IsValid) continue;
|
||||||
if (gun == null) continue;
|
|
||||||
if (gun.Entity == null) continue;
|
if (gun.Entity == null) continue;
|
||||||
if (!gun.IsValid) continue;
|
if (!gun.IsValid) continue;
|
||||||
if (!gun.VisibleinPVS) continue;
|
if (!gun.VisibleinPVS) continue;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string? weaponByDefindex = null;
|
|
||||||
|
|
||||||
CCSWeaponBaseVData? weaponData = weapon.Value.As<CCSWeaponBase>().VData;
|
CCSWeaponBaseVData? weaponData = weapon.Value.As<CCSWeaponBase>().VData;
|
||||||
|
|
||||||
if (weaponData == null) continue;
|
if (weaponData == null) continue;
|
||||||
|
|
||||||
if (weaponData.GearSlot == gear_slot_t.GEAR_SLOT_RIFLE || weaponData.GearSlot == gear_slot_t.GEAR_SLOT_PISTOL)
|
if (weaponData.GearSlot is gear_slot_t.GEAR_SLOT_RIFLE or gear_slot_t.GEAR_SLOT_PISTOL)
|
||||||
{
|
{
|
||||||
if (!WeaponDefindex.TryGetValue(weapon.Value.AttributeManager.Item.ItemDefinitionIndex, out weaponByDefindex))
|
if (!WeaponDefindex.TryGetValue(weapon.Value.AttributeManager.Item.ItemDefinitionIndex, out var weaponByDefindex))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int clip1 = weapon.Value.Clip1;
|
int clip1 = weapon.Value.Clip1;
|
||||||
int reservedAmmo = weapon.Value.ReserveAmmo[0];
|
int reservedAmmo = weapon.Value.ReserveAmmo[0];
|
||||||
|
|
||||||
if (!weaponsWithAmmo.ContainsKey(weaponByDefindex))
|
if (!weaponsWithAmmo.TryGetValue(weaponByDefindex, out var value))
|
||||||
{
|
{
|
||||||
weaponsWithAmmo.Add(weaponByDefindex, new List<(int, int)>());
|
value = [];
|
||||||
|
weaponsWithAmmo.Add(weaponByDefindex, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
weaponsWithAmmo[weaponByDefindex].Add((clip1, reservedAmmo));
|
value.Add((clip1, reservedAmmo));
|
||||||
|
|
||||||
if (gun == null || gun.VData == null) return;
|
if (gun.VData == null) return;
|
||||||
|
|
||||||
|
weapon.Value?.AddEntityIOEvent("Kill", weapon.Value, null, "", 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
weapon.Value.Remove();
|
if (weaponData.GearSlot == gear_slot_t.GEAR_SLOT_KNIFE)
|
||||||
|
{
|
||||||
|
weapon.Value?.AddEntityIOEvent("Kill", weapon.Value, null, "", 0.1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogWarning(ex.Message);
|
Logger.LogWarning(ex.Message);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
AddTimer(0.23f, () =>
|
||||||
{
|
|
||||||
player.ExecuteClientCommand("slot 3");
|
|
||||||
player.ExecuteClientCommand("slot 3");
|
|
||||||
|
|
||||||
var weapon = player.PlayerPawn.Value.WeaponServices.ActiveWeapon;
|
|
||||||
if (weapon is null || !weapon.IsValid || weapon.Value == null) return;
|
|
||||||
CCSWeaponBaseVData? weaponData = weapon.Value.As<CCSWeaponBase>().VData;
|
|
||||||
|
|
||||||
if (weapon.Value.DesignerName.Contains("knife") || weaponData?.GearSlot == gear_slot_t.GEAR_SLOT_KNIFE)
|
|
||||||
{
|
|
||||||
CCSWeaponBaseGun gun = weapon.Value.As<CCSWeaponBaseGun>();
|
|
||||||
|
|
||||||
AddTimer(0.3f, () =>
|
|
||||||
{
|
{
|
||||||
if (player.TeamNum != playerTeam) return;
|
if (!_gBCommandsAllowed) return;
|
||||||
|
|
||||||
player.ExecuteClientCommand("slot 3");
|
if (!PlayerHasKnife(player))
|
||||||
gun = weapon.Value.As<CCSWeaponBaseGun>();
|
GiveKnifeToPlayer(player);
|
||||||
player.DropActiveWeapon();
|
|
||||||
|
|
||||||
AddTimer(0.7f, () =>
|
|
||||||
{
|
|
||||||
if (player.TeamNum != playerTeam) return;
|
|
||||||
|
|
||||||
if (gun == null || !gun.IsValid || gun.State != CSWeaponState_t.WEAPON_NOT_CARRIED) return;
|
|
||||||
|
|
||||||
gun.Remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
GiveKnifeToPlayer(player);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.LogWarning($"Cannot remove knife: {ex.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
AddTimer(0.6f, () =>
|
|
||||||
{
|
|
||||||
if (!g_bCommandsAllowed) return;
|
|
||||||
|
|
||||||
foreach (var entry in weaponsWithAmmo)
|
foreach (var entry in weaponsWithAmmo)
|
||||||
{
|
{
|
||||||
@@ -170,11 +314,10 @@ namespace WeaponPaints
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (newWeapon != null)
|
newWeapon.Clip1 = ammo.Item1;
|
||||||
{
|
newWeapon.ReserveAmmo[0] = ammo.Item2;
|
||||||
newWeapon.Clip1 = ammo.Item1;
|
|
||||||
newWeapon.ReserveAmmo[0] = ammo.Item2;
|
IncrementWearForWeaponWithStickers(player, newWeapon);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -183,56 +326,50 @@ namespace WeaponPaints
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, TimerFlags.STOP_ON_MAPCHANGE);
|
}, TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RefreshGloves(CCSPlayerController player)
|
private void GivePlayerGloves(CCSPlayerController player)
|
||||||
{
|
{
|
||||||
if (!Utility.IsPlayerValid(player) || (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE) return;
|
if (!Utility.IsPlayerValid(player) || (LifeState_t)player.LifeState != LifeState_t.LIFE_ALIVE) return;
|
||||||
|
|
||||||
CCSPlayerPawn? pawn = player.PlayerPawn.Value;
|
CCSPlayerPawn? pawn = player.PlayerPawn.Value;
|
||||||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
if (pawn == null || !pawn.IsValid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string model = pawn.CBodyComponent?.SceneNode?.GetSkeletonInstance()?.ModelState.ModelName ?? string.Empty;
|
var model = pawn.CBodyComponent?.SceneNode?.GetSkeletonInstance()?.ModelState.ModelName ?? string.Empty;
|
||||||
if (!string.IsNullOrEmpty(model))
|
if (!string.IsNullOrEmpty(model))
|
||||||
{
|
{
|
||||||
pawn.SetModel("characters/models/tm_jumpsuit/tm_jumpsuit_varianta.vmdl");
|
pawn.SetModel("characters/models/tm_jumpsuit/tm_jumpsuit_varianta.vmdl");
|
||||||
pawn.SetModel(model);
|
pawn.SetModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance.AddTimer(0.06f, () =>
|
Instance.AddTimer(0.08f, () =>
|
||||||
{
|
{
|
||||||
|
CEconItemView item = pawn.EconGloves;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (player == null || !player.IsValid)
|
if (!player.IsValid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
if (!player.PawnIsAlive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_playersGlove.TryGetValue(player.Slot, out var gloveInfo) && gloveInfo != 0)
|
if (!GPlayersGlove.TryGetValue(player.Slot, out var gloveInfo) || gloveInfo == 0) return;
|
||||||
{
|
|
||||||
CCSPlayerPawn? pawn = player.PlayerPawn.Value;
|
|
||||||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
WeaponInfo weaponInfo = gPlayerWeaponsInfo[player.Slot][gloveInfo];
|
WeaponInfo weaponInfo = GPlayerWeaponsInfo[player.Slot][gloveInfo];
|
||||||
|
|
||||||
CEconItemView item = pawn.EconGloves;
|
item.ItemDefinitionIndex = gloveInfo;
|
||||||
item.ItemDefinitionIndex = gloveInfo;
|
item.ItemIDLow = 16384 & 0xFFFFFFFF;
|
||||||
item.ItemIDLow = 16384 & 0xFFFFFFFF;
|
item.ItemIDHigh = 16384;
|
||||||
item.ItemIDHigh = 16384;
|
|
||||||
|
|
||||||
CAttributeList_SetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weaponInfo.Paint);
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weaponInfo.Paint);
|
||||||
CAttributeList_SetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture seed", weaponInfo.Seed);
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture seed", weaponInfo.Seed);
|
||||||
CAttributeList_SetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture wear", weaponInfo.Wear);
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture wear", weaponInfo.Wear);
|
||||||
|
|
||||||
item.Initialized = true;
|
item.Initialized = true;
|
||||||
|
|
||||||
CBaseModelEntity_SetBodygroup.Invoke(pawn, "default_gloves", 1);
|
SetBodygroup(pawn.Handle, "default_gloves", 1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}, TimerFlags.STOP_ON_MAPCHANGE);
|
}, TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
@@ -240,73 +377,69 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
private static int GetRandomPaint(int defindex)
|
private static int GetRandomPaint(int defindex)
|
||||||
{
|
{
|
||||||
if (skinsList == null || skinsList.Count == 0)
|
if (SkinsList.Count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Random rnd = new Random();
|
Random rnd = new Random();
|
||||||
|
|
||||||
// Filter weapons by the provided defindex
|
// Filter weapons by the provided defindex
|
||||||
var filteredWeapons = skinsList.Where(w => w["weapon_defindex"]?.ToString() == defindex.ToString()).ToList();
|
var filteredWeapons = SkinsList.Where(w => w["weapon_defindex"]?.ToString() == defindex.ToString()).ToList();
|
||||||
|
|
||||||
if (filteredWeapons.Count == 0)
|
if (filteredWeapons.Count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
var randomWeapon = filteredWeapons[rnd.Next(filteredWeapons.Count)];
|
var randomWeapon = filteredWeapons[rnd.Next(filteredWeapons.Count)];
|
||||||
|
|
||||||
if (int.TryParse(randomWeapon["paint"]?.ToString(), out int paintValue))
|
return int.TryParse(randomWeapon["paint"]?.ToString(), out var paintValue) ? paintValue : 0;
|
||||||
return paintValue;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SubclassChange(CBasePlayerWeapon weapon, ushort itemD)
|
private static void SubclassChange(CBasePlayerWeapon weapon, ushort itemD)
|
||||||
{
|
{
|
||||||
var SubclassChangeFunc = VirtualFunction.Create<nint, string, int>(
|
var subclassChangeFunc = VirtualFunction.Create<nint, string, int>(
|
||||||
GameData.GetSignature("ChangeSubclass")
|
GameData.GetSignature("ChangeSubclass")
|
||||||
);
|
);
|
||||||
|
|
||||||
SubclassChangeFunc(weapon.Handle, itemD.ToString());
|
subclassChangeFunc(weapon.Handle, itemD.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateWeaponMeshGroupMask(CBaseEntity weapon, bool isLegacy = false)
|
private static void UpdateWeaponMeshGroupMask(CBaseEntity weapon, bool isLegacy = false)
|
||||||
{
|
{
|
||||||
if (weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null)
|
if (weapon.CBodyComponent?.SceneNode == null) return;
|
||||||
{
|
var skeleton = weapon.CBodyComponent.SceneNode.GetSkeletonInstance();
|
||||||
var skeleton = weapon.CBodyComponent.SceneNode.GetSkeletonInstance();
|
var value = (ulong)(isLegacy ? 2 : 1);
|
||||||
if (skeleton != null)
|
|
||||||
{
|
|
||||||
var value = (ulong)(isLegacy ? 2 : 1);
|
|
||||||
|
|
||||||
if (skeleton.ModelState.MeshGroupMask != value)
|
if (skeleton.ModelState.MeshGroupMask != value)
|
||||||
{
|
{
|
||||||
skeleton.ModelState.MeshGroupMask = value;
|
skeleton.ModelState.MeshGroupMask = value;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdatePlayerWeaponMeshGroupMask(CCSPlayerController player, CBasePlayerWeapon weapon, bool isLegacy)
|
private static void UpdatePlayerWeaponMeshGroupMask(CCSPlayerController player, CBasePlayerWeapon weapon, bool isLegacy)
|
||||||
{
|
{
|
||||||
UpdateWeaponMeshGroupMask(weapon, isLegacy);
|
UpdateWeaponMeshGroupMask(weapon, isLegacy);
|
||||||
|
|
||||||
var viewModel = GetPlayerViewModel(player);
|
var viewModel = GetPlayerViewModel(player);
|
||||||
if (viewModel != null && viewModel.Weapon.Value != null && viewModel.Weapon.Value.Index == weapon.Index)
|
if (viewModel == null || viewModel.Weapon.Value == null ||
|
||||||
{
|
viewModel.Weapon.Value.Index != weapon.Index) return;
|
||||||
UpdateWeaponMeshGroupMask(viewModel, isLegacy);
|
UpdateWeaponMeshGroupMask(viewModel, isLegacy);
|
||||||
Utilities.SetStateChanged(viewModel, "CBaseEntity", "m_CBodyComponent");
|
Utilities.SetStateChanged(viewModel, "CBaseEntity", "m_CBodyComponent");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GivePlayerAgent(CCSPlayerController player)
|
private static void GivePlayerAgent(CCSPlayerController player)
|
||||||
{
|
{
|
||||||
|
if (!GPlayersAgent.TryGetValue(player.Slot, out var value)) return;
|
||||||
|
|
||||||
|
var model = player.TeamNum == 3 ? value.CT : value.T;
|
||||||
|
if (string.IsNullOrEmpty(model)) return;
|
||||||
|
|
||||||
|
if (player.PlayerPawn.Value == null)
|
||||||
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Server.NextFrame(() =>
|
Server.NextFrame(() =>
|
||||||
{
|
{
|
||||||
string? model = player.TeamNum == 3 ? g_playersAgent[player.Slot].CT : g_playersAgent[player.Slot].T;
|
player.PlayerPawn.Value.SetModel(
|
||||||
if (model == null) return;
|
|
||||||
|
|
||||||
player.PlayerPawn.Value!.SetModel(
|
|
||||||
$"characters/models/{model}.vmdl"
|
$"characters/models/{model}.vmdl"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -316,38 +449,77 @@ namespace WeaponPaints
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CCSPlayerController? GetPlayerFromItemServices(CCSPlayer_ItemServices itemServices)
|
private static void GivePlayerMusicKit(CCSPlayerController player)
|
||||||
|
{
|
||||||
|
if (!GPlayersMusic.TryGetValue(player.Slot, out var value)) return;
|
||||||
|
if (player.InventoryServices == null) return;
|
||||||
|
|
||||||
|
player.InventoryServices.MusicID = value;
|
||||||
|
Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInventoryServices");
|
||||||
|
player.MusicKitID = value;
|
||||||
|
Utilities.SetStateChanged(player, "CCSPlayerController", "m_iMusicKitID");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GivePlayerPin(CCSPlayerController player)
|
||||||
|
{
|
||||||
|
if (!GPlayersPin.TryGetValue(player.Slot, out var pin)) return;
|
||||||
|
|
||||||
|
if (player.InventoryServices == null) return;
|
||||||
|
|
||||||
|
for (var index = 0; index < player.InventoryServices.Rank.Length; index++)
|
||||||
|
{
|
||||||
|
player.InventoryServices.Rank[index] = index == 5 ? (MedalRank_t)pin : MedalRank_t.MEDAL_RANK_NONE;
|
||||||
|
Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInventoryServices");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GiveOnItemPickup(CCSPlayerController player)
|
||||||
|
{
|
||||||
|
var pawn = player.PlayerPawn.Value;
|
||||||
|
if (pawn == null) return;
|
||||||
|
|
||||||
|
var myWeapons = pawn.WeaponServices?.MyWeapons;
|
||||||
|
if (myWeapons == null) return;
|
||||||
|
foreach (var handle in myWeapons)
|
||||||
|
{
|
||||||
|
var weapon = handle.Value;
|
||||||
|
if (weapon != null && weapon.DesignerName.Contains("knife"))
|
||||||
|
{
|
||||||
|
GivePlayerWeaponSkin(player, weapon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePlayerEconItemId(CEconItemView econItemView)
|
||||||
|
{
|
||||||
|
var itemId = _nextItemId++;
|
||||||
|
econItemView.ItemID = itemId;
|
||||||
|
|
||||||
|
econItemView.ItemIDLow = (uint)itemId & 0xFFFFFFFF;
|
||||||
|
econItemView.ItemIDHigh = (uint)itemId >> 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CCSPlayerController? GetPlayerFromItemServices(CCSPlayer_ItemServices itemServices)
|
||||||
{
|
{
|
||||||
var pawn = itemServices.Pawn.Value;
|
var pawn = itemServices.Pawn.Value;
|
||||||
if (pawn == null || !pawn.IsValid || !pawn.Controller.IsValid || pawn.Controller.Value == null) return null;
|
if (!pawn.IsValid || !pawn.Controller.IsValid || pawn.Controller.Value == null) return null;
|
||||||
var player = new CCSPlayerController(pawn.Controller.Value.Handle);
|
var player = new CCSPlayerController(pawn.Controller.Value.Handle);
|
||||||
if (!Utility.IsPlayerValid(player)) return null;
|
return !Utility.IsPlayerValid(player) ? null : player;
|
||||||
return player;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static unsafe CBaseViewModel? GetPlayerViewModel(CCSPlayerController player)
|
private static unsafe CBaseViewModel? GetPlayerViewModel(CCSPlayerController player)
|
||||||
{
|
{
|
||||||
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null;
|
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null;
|
||||||
CCSPlayer_ViewModelServices viewModelServices = new(player.PlayerPawn.Value.ViewModelServices!.Handle);
|
CCSPlayer_ViewModelServices viewModelServices = new(player.PlayerPawn.Value.ViewModelServices!.Handle);
|
||||||
nint ptr = viewModelServices.Handle + Schema.GetSchemaOffset("CCSPlayer_ViewModelServices", "m_hViewModel");
|
var ptr = viewModelServices.Handle + Schema.GetSchemaOffset("CCSPlayer_ViewModelServices", "m_hViewModel");
|
||||||
var references = MemoryMarshal.CreateSpan(ref ptr, 3);
|
var references = MemoryMarshal.CreateSpan(ref ptr, 3);
|
||||||
var viewModel = (CHandle<CBaseViewModel>)Activator.CreateInstance(typeof(CHandle<CBaseViewModel>), references[0])!;
|
var viewModel = (CHandle<CBaseViewModel>)Activator.CreateInstance(typeof(CHandle<CBaseViewModel>), references[0])!;
|
||||||
if (viewModel == null || viewModel.Value == null) return null;
|
return viewModel.Value == null ? null : viewModel.Value;
|
||||||
return viewModel.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe T[] GetFixedArray<T>(nint pointer, string @class, string member, int length) where T : CHandle<CBaseViewModel>
|
private static float ViewAsFloat(uint value)
|
||||||
{
|
{
|
||||||
nint ptr = pointer + Schema.GetSchemaOffset(@class, member);
|
return BitConverter.Int32BitsToSingle((int)value);
|
||||||
Span<nint> references = MemoryMarshal.CreateSpan(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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,32 @@
|
|||||||
public class WeaponInfo
|
public class WeaponInfo
|
||||||
{
|
{
|
||||||
public int Paint { get; set; }
|
public int Paint { get; set; }
|
||||||
public int Seed { get; set; } = 0;
|
public int Seed { get; set; }
|
||||||
public float Wear { get; set; } = 0f;
|
public float Wear { get; set; }
|
||||||
|
public string Nametag { get; set; } = "";
|
||||||
|
public bool StatTrak { get; set; } = false;
|
||||||
|
public int StatTrakCount { get; set; }
|
||||||
|
public KeyChainInfo? KeyChain { get; set; }
|
||||||
|
public List<StickerInfo> Stickers { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StickerInfo
|
||||||
|
{
|
||||||
|
public uint Id { get; set; }
|
||||||
|
public uint Schema { get; set; }
|
||||||
|
public float OffsetX { get; set; }
|
||||||
|
public float OffsetY { get; set; }
|
||||||
|
public float Wear { get; set; }
|
||||||
|
public float Scale { get; set; }
|
||||||
|
public float Rotation { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class KeyChainInfo
|
||||||
|
{
|
||||||
|
public uint Id { get; set; }
|
||||||
|
public float OffsetX { get; set; }
|
||||||
|
public float OffsetY { get; set; }
|
||||||
|
public float OffsetZ { get; set; }
|
||||||
|
public uint Seed { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
240
WeaponPaints.cs
240
WeaponPaints.cs
@@ -1,169 +1,22 @@
|
|||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Core.Attributes;
|
using CounterStrikeSharp.API.Core.Attributes;
|
||||||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
|
||||||
using Microsoft.Extensions.Localization;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MySqlConnector;
|
using MySqlConnector;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
|
|
||||||
namespace WeaponPaints;
|
namespace WeaponPaints;
|
||||||
|
|
||||||
[MinimumApiVersion(178)]
|
[MinimumApiVersion(276)]
|
||||||
public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig>
|
public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig>
|
||||||
{
|
{
|
||||||
internal static WeaponPaints Instance { get; private set; } = new();
|
internal static WeaponPaints Instance { get; private set; } = new();
|
||||||
|
|
||||||
internal static readonly Dictionary<string, string> weaponList = new()
|
|
||||||
{
|
|
||||||
{"weapon_deagle", "Desert Eagle"},
|
|
||||||
{"weapon_elite", "Dual Berettas"},
|
|
||||||
{"weapon_fiveseven", "Five-SeveN"},
|
|
||||||
{"weapon_glock", "Glock-18"},
|
|
||||||
{"weapon_ak47", "AK-47"},
|
|
||||||
{"weapon_aug", "AUG"},
|
|
||||||
{"weapon_awp", "AWP"},
|
|
||||||
{"weapon_famas", "FAMAS"},
|
|
||||||
{"weapon_g3sg1", "G3SG1"},
|
|
||||||
{"weapon_galilar", "Galil AR"},
|
|
||||||
{"weapon_m249", "M249"},
|
|
||||||
{"weapon_m4a1", "M4A1"},
|
|
||||||
{"weapon_mac10", "MAC-10"},
|
|
||||||
{"weapon_p90", "P90"},
|
|
||||||
{"weapon_mp5sd", "MP5-SD"},
|
|
||||||
{"weapon_ump45", "UMP-45"},
|
|
||||||
{"weapon_xm1014", "XM1014"},
|
|
||||||
{"weapon_bizon", "PP-Bizon"},
|
|
||||||
{"weapon_mag7", "MAG-7"},
|
|
||||||
{"weapon_negev", "Negev"},
|
|
||||||
{"weapon_sawedoff", "Sawed-Off"},
|
|
||||||
{"weapon_tec9", "Tec-9"},
|
|
||||||
{"weapon_taser", "Zeus x27"},
|
|
||||||
{"weapon_hkp2000", "P2000"},
|
|
||||||
{"weapon_mp7", "MP7"},
|
|
||||||
{"weapon_mp9", "MP9"},
|
|
||||||
{"weapon_nova", "Nova"},
|
|
||||||
{"weapon_p250", "P250"},
|
|
||||||
{"weapon_scar20", "SCAR-20"},
|
|
||||||
{"weapon_sg556", "SG 553"},
|
|
||||||
{"weapon_ssg08", "SSG 08"},
|
|
||||||
{"weapon_m4a1_silencer", "M4A1-S"},
|
|
||||||
{"weapon_usp_silencer", "USP-S"},
|
|
||||||
{"weapon_cz75a", "CZ75-Auto"},
|
|
||||||
{"weapon_revolver", "R8 Revolver"},
|
|
||||||
{ "weapon_knife", "Default Knife" },
|
|
||||||
{ "weapon_knife_m9_bayonet", "M9 Bayonet" },
|
|
||||||
{ "weapon_knife_karambit", "Karambit" },
|
|
||||||
{ "weapon_bayonet", "Bayonet" },
|
|
||||||
{ "weapon_knife_survival_bowie", "Bowie Knife" },
|
|
||||||
{ "weapon_knife_butterfly", "Butterfly Knife" },
|
|
||||||
{ "weapon_knife_falchion", "Falchion Knife" },
|
|
||||||
{ "weapon_knife_flip", "Flip Knife" },
|
|
||||||
{ "weapon_knife_gut", "Gut Knife" },
|
|
||||||
{ "weapon_knife_tactical", "Huntsman Knife" },
|
|
||||||
{ "weapon_knife_push", "Shadow Daggers" },
|
|
||||||
{ "weapon_knife_gypsy_jackknife", "Navaja Knife" },
|
|
||||||
{ "weapon_knife_stiletto", "Stiletto Knife" },
|
|
||||||
{ "weapon_knife_widowmaker", "Talon Knife" },
|
|
||||||
{ "weapon_knife_ursus", "Ursus Knife" },
|
|
||||||
{ "weapon_knife_css", "Classic Knife" },
|
|
||||||
{ "weapon_knife_cord", "Paracord Knife" },
|
|
||||||
{ "weapon_knife_canis", "Survival Knife" },
|
|
||||||
{ "weapon_knife_outdoor", "Nomad 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 ConcurrentDictionary<int, string> g_playersKnife = new ConcurrentDictionary<int, string>();
|
|
||||||
internal static ConcurrentDictionary<int, ushort> g_playersGlove = new ConcurrentDictionary<int, ushort>();
|
|
||||||
internal static ConcurrentDictionary<int, (string? CT, string? T)> g_playersAgent = new ConcurrentDictionary<int, (string?, string?)>();
|
|
||||||
internal static ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>> gPlayerWeaponsInfo = new ConcurrentDictionary<int, ConcurrentDictionary<int, WeaponInfo>>();
|
|
||||||
internal static List<JObject> skinsList = new List<JObject>();
|
|
||||||
internal static List<JObject> glovesList = new List<JObject>();
|
|
||||||
internal static List<JObject> agentsList = new List<JObject>();
|
|
||||||
internal static WeaponSynchronization? weaponSync;
|
|
||||||
public static bool g_bCommandsAllowed = true;
|
|
||||||
internal Dictionary<int, string> PlayerWeaponImage = new();
|
|
||||||
|
|
||||||
internal static Dictionary<int, DateTime> commandsCooldown = new Dictionary<int, DateTime>();
|
|
||||||
internal static Database? _database;
|
|
||||||
|
|
||||||
internal static MemoryFunctionVoid<nint, string, float> CAttributeList_SetOrAddAttributeValueByName = new(GameData.GetSignature("CAttributeList_SetOrAddAttributeValueByName"));
|
|
||||||
internal static MemoryFunctionVoid<CBaseModelEntity, string, UInt64> CBaseModelEntity_SetBodygroup = new(GameData.GetSignature("CBaseModelEntity_SetBodygroup"));
|
|
||||||
|
|
||||||
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" },
|
|
||||||
{ 31, "weapon_taser" },
|
|
||||||
{ 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" },
|
|
||||||
{ 526, "weapon_knife_kukri" }
|
|
||||||
};
|
|
||||||
|
|
||||||
public WeaponPaintsConfig Config { get; set; } = new();
|
public WeaponPaintsConfig Config { get; set; } = new();
|
||||||
public override string ModuleAuthor => "Nereziel & daffyy";
|
private static WeaponPaintsConfig _config { get; set; } = new();
|
||||||
|
public override string ModuleAuthor => "Nereziel & daffyy";
|
||||||
public override string ModuleDescription => "Skin, gloves, agents and knife selector, standalone and web-based";
|
public override string ModuleDescription => "Skin, gloves, agents and knife selector, standalone and web-based";
|
||||||
public override string ModuleName => "WeaponPaints";
|
public override string ModuleName => "WeaponPaints";
|
||||||
public override string ModuleVersion => "2.2a";
|
public override string ModuleVersion => "2.7a";
|
||||||
|
|
||||||
public static WeaponPaintsConfig GetWeaponPaintsConfig()
|
|
||||||
{
|
|
||||||
return _config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Load(bool hotReload)
|
public override void Load(bool hotReload)
|
||||||
{
|
{
|
||||||
@@ -173,17 +26,19 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
|||||||
{
|
{
|
||||||
OnMapStart(string.Empty);
|
OnMapStart(string.Empty);
|
||||||
|
|
||||||
foreach (var player in Utilities.GetPlayers())
|
foreach (var player in Enumerable
|
||||||
|
.OfType<CCSPlayerController>(Utilities.GetPlayers().TakeWhile(player => WeaponSync != null))
|
||||||
|
.Where(player => player.IsValid &&
|
||||||
|
!string.IsNullOrEmpty(player.IpAddress) && player is
|
||||||
|
{ IsBot: false, Connected: PlayerConnectedState.PlayerConnected }))
|
||||||
{
|
{
|
||||||
if (weaponSync == null || player is null || !player.IsValid || player.SteamID.ToString().Length != 17 || !player.PawnIsAlive || player.IsBot ||
|
GPlayerWeaponsInfo.TryRemove(player.Slot, out _);
|
||||||
player.IsHLTV || player.Connected != PlayerConnectedState.PlayerConnected)
|
GPlayersKnife.TryRemove(player.Slot, out _);
|
||||||
continue;
|
GPlayersGlove.TryRemove(player.Slot, out _);
|
||||||
|
GPlayersAgent.TryRemove(player.Slot, out _);
|
||||||
|
GPlayersPin.TryRemove(player.Slot, out _);
|
||||||
|
|
||||||
g_knifePickupCount[player.Slot] = 0;
|
var playerInfo = new PlayerInfo
|
||||||
gPlayerWeaponsInfo.TryRemove(player.Slot, out _);
|
|
||||||
g_playersKnife.TryRemove(player.Slot, out _);
|
|
||||||
|
|
||||||
PlayerInfo playerInfo = new PlayerInfo
|
|
||||||
{
|
{
|
||||||
UserId = player.UserId,
|
UserId = player.UserId,
|
||||||
Slot = player.Slot,
|
Slot = player.Slot,
|
||||||
@@ -193,28 +48,19 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
|||||||
IpAddress = player?.IpAddress?.Split(":")[0]
|
IpAddress = player?.IpAddress?.Split(":")[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Config.Additional.SkinEnabled)
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
Task.Run(() => weaponSync.GetWeaponPaintsFromDatabase(playerInfo));
|
if (WeaponSync != null) await WeaponSync.GetPlayerData(playerInfo);
|
||||||
}
|
});
|
||||||
if (Config.Additional.KnifeEnabled)
|
|
||||||
{
|
|
||||||
Task.Run(() => weaponSync.GetKnifeFromDatabase(playerInfo));
|
|
||||||
}
|
|
||||||
if (Config.Additional.GloveEnabled)
|
|
||||||
{
|
|
||||||
Task.Run(() => weaponSync.GetGloveFromDatabase(playerInfo));
|
|
||||||
}
|
|
||||||
if (Config.Additional.AgentEnabled)
|
|
||||||
{
|
|
||||||
Task.Run(() => weaponSync.GetAgentFromDatabase(playerInfo));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddTimer(2.0f, () => OnAllPluginsLoaded(hotReload));
|
||||||
}
|
}
|
||||||
|
|
||||||
Utility.LoadSkinsFromFile(ModuleDirectory + "/skins.json");
|
Utility.LoadSkinsFromFile(ModuleDirectory + $"/data/skins_{_config.SkinsLanguage}.json", Logger);
|
||||||
Utility.LoadGlovesFromFile(ModuleDirectory + "/gloves.json");
|
Utility.LoadGlovesFromFile(ModuleDirectory + $"/data/gloves_{_config.SkinsLanguage}.json", Logger);
|
||||||
Utility.LoadAgentsFromFile(ModuleDirectory + "/agents.json");
|
Utility.LoadAgentsFromFile(ModuleDirectory + $"/data/agents_{_config.SkinsLanguage}.json", Logger);
|
||||||
|
Utility.LoadMusicFromFile(ModuleDirectory + $"/data/music_{_config.SkinsLanguage}.json", Logger);
|
||||||
|
|
||||||
if (Config.Additional.KnifeEnabled)
|
if (Config.Additional.KnifeEnabled)
|
||||||
SetupKnifeMenu();
|
SetupKnifeMenu();
|
||||||
@@ -224,6 +70,8 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
|||||||
SetupGlovesMenu();
|
SetupGlovesMenu();
|
||||||
if (Config.Additional.AgentEnabled)
|
if (Config.Additional.AgentEnabled)
|
||||||
SetupAgentsMenu();
|
SetupAgentsMenu();
|
||||||
|
if (Config.Additional.MusicEnabled)
|
||||||
|
SetupMusicMenu();
|
||||||
|
|
||||||
RegisterListeners();
|
RegisterListeners();
|
||||||
RegisterCommands();
|
RegisterCommands();
|
||||||
@@ -231,12 +79,23 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
|||||||
|
|
||||||
public void OnConfigParsed(WeaponPaintsConfig config)
|
public void OnConfigParsed(WeaponPaintsConfig config)
|
||||||
{
|
{
|
||||||
|
Config = config;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
if (config.DatabaseHost.Length < 1 || config.DatabaseName.Length < 1 || config.DatabaseUser.Length < 1)
|
if (config.DatabaseHost.Length < 1 || config.DatabaseName.Length < 1 || config.DatabaseUser.Length < 1)
|
||||||
{
|
{
|
||||||
Logger.LogError("You need to setup Database credentials in config!");
|
Logger.LogError("You need to setup Database credentials in \"configs/plugins/WeaponPaints/WeaponPaints.json\"!");
|
||||||
throw new Exception("[WeaponPaints] You need to setup Database credentials in config!");
|
Unload(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(Path.GetDirectoryName(Path.GetDirectoryName(ModuleDirectory)) + "/gamedata/weaponpaints.json"))
|
||||||
|
{
|
||||||
|
Logger.LogError("You need to upload \"weaponpaints.json\" to \"gamedata directory\"!");
|
||||||
|
Unload(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var builder = new MySqlConnectionStringBuilder
|
var builder = new MySqlConnectionStringBuilder
|
||||||
{
|
{
|
||||||
Server = config.DatabaseHost,
|
Server = config.DatabaseHost,
|
||||||
@@ -244,15 +103,13 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
|||||||
Password = config.DatabasePassword,
|
Password = config.DatabasePassword,
|
||||||
Database = config.DatabaseName,
|
Database = config.DatabaseName,
|
||||||
Port = (uint)config.DatabasePort,
|
Port = (uint)config.DatabasePort,
|
||||||
Pooling = true
|
Pooling = true,
|
||||||
|
MaximumPoolSize = 640,
|
||||||
};
|
};
|
||||||
|
|
||||||
_database = new(builder.ConnectionString);
|
Database = new Database(builder.ConnectionString);
|
||||||
|
|
||||||
_ = Utility.CheckDatabaseTables();
|
_ = Utility.CheckDatabaseTables();
|
||||||
|
|
||||||
Config = config;
|
|
||||||
_config = config;
|
|
||||||
_localizer = Localizer;
|
_localizer = Localizer;
|
||||||
|
|
||||||
Utility.Config = config;
|
Utility.Config = config;
|
||||||
@@ -260,8 +117,17 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig<WeaponPaintsConfig
|
|||||||
Task.Run(async () => await Utility.CheckVersion(ModuleVersion, Logger));
|
Task.Run(async () => await Utility.CheckVersion(ModuleVersion, Logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unload(bool hotReload)
|
public override void OnAllPluginsLoaded(bool hotReload)
|
||||||
{
|
{
|
||||||
base.Unload(hotReload);
|
try
|
||||||
|
{
|
||||||
|
MenuApi = MenuCapability.Get();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
MenuApi = null;
|
||||||
|
Logger.LogError("Error while loading required plugins");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.179" />
|
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.281" />
|
||||||
<PackageReference Include="Dapper" Version="2.1.28" />
|
<PackageReference Include="Dapper" Version="2.1.35" />
|
||||||
<PackageReference Include="MySqlConnector" Version="2.3.5" />
|
<PackageReference Include="MySqlConnector" Version="2.4.0-beta.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@@ -22,4 +22,10 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="gamedata\*.*" CopyToOutputDirectory="PreserveNewest" />
|
<None Update="gamedata\*.*" CopyToOutputDirectory="PreserveNewest" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="MenuManagerApi">
|
||||||
|
<HintPath>3rd_party\MenuManagerApi.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
2
WeaponPaints.sln.DotSettings.user
Normal file
2
WeaponPaints.sln.DotSettings.user
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005Cxdaff_005CDocuments_005CGitHub_005Ccs2_002DWeaponPaints_005C3rd_005Fparty_005CMenuManagerApi_002Edll/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using Dapper;
|
using Dapper;
|
||||||
|
using MySqlConnector;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
|
||||||
namespace WeaponPaints
|
namespace WeaponPaints
|
||||||
{
|
{
|
||||||
internal class WeaponSynchronization
|
internal class WeaponSynchronization
|
||||||
@@ -14,20 +16,45 @@ namespace WeaponPaints
|
|||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task GetKnifeFromDatabase(PlayerInfo player)
|
internal async Task GetPlayerData(PlayerInfo? player)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using var connection = await _database.GetConnectionAsync();
|
||||||
|
|
||||||
|
if (_config.Additional.KnifeEnabled)
|
||||||
|
GetKnifeFromDatabase(player, connection);
|
||||||
|
if (_config.Additional.GloveEnabled)
|
||||||
|
GetGloveFromDatabase(player, connection);
|
||||||
|
if (_config.Additional.AgentEnabled)
|
||||||
|
GetAgentFromDatabase(player, connection);
|
||||||
|
if (_config.Additional.MusicEnabled)
|
||||||
|
GetMusicFromDatabase(player, connection);
|
||||||
|
if (_config.Additional.SkinEnabled)
|
||||||
|
GetWeaponPaintsFromDatabase(player, connection);
|
||||||
|
if (_config.Additional.PinsEnabled)
|
||||||
|
GetPinsFromDatabase(player, connection);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Log the exception or handle it appropriately
|
||||||
|
Console.WriteLine($"An error occurred: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetKnifeFromDatabase(PlayerInfo? player, MySqlConnection connection)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player?.SteamId))
|
if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player?.SteamId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
const string query = "SELECT `knife` FROM `wp_player_knife` WHERE `steamid` = @steamid";
|
||||||
string query = "SELECT `knife` FROM `wp_player_knife` WHERE `steamid` = @steamid";
|
var playerKnife = connection.QueryFirstOrDefault<string>(query, new { steamid = player.SteamId });
|
||||||
string? playerKnife = await connection.QueryFirstOrDefaultAsync<string>(query, new { steamid = player.SteamId });
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(playerKnife))
|
if (!string.IsNullOrEmpty(playerKnife))
|
||||||
{
|
{
|
||||||
WeaponPaints.g_playersKnife[player.Slot] = playerKnife;
|
WeaponPaints.GPlayersKnife[player.Slot] = playerKnife;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -36,20 +63,19 @@ namespace WeaponPaints
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task GetGloveFromDatabase(PlayerInfo player)
|
private void GetGloveFromDatabase(PlayerInfo? player, MySqlConnection connection)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player?.SteamId))
|
if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player?.SteamId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
const string query = "SELECT `weapon_defindex` FROM `wp_player_gloves` WHERE `steamid` = @steamid";
|
||||||
string query = "SELECT `weapon_defindex` FROM `wp_player_gloves` WHERE `steamid` = @steamid";
|
var gloveData = connection.QueryFirstOrDefault<ushort?>(query, new { steamid = player.SteamId });
|
||||||
ushort? gloveData = await connection.QueryFirstOrDefaultAsync<ushort?>(query, new { steamid = player.SteamId });
|
|
||||||
|
|
||||||
if (gloveData != null)
|
if (gloveData != null)
|
||||||
{
|
{
|
||||||
WeaponPaints.g_playersGlove[player.Slot] = gloveData.Value;
|
WeaponPaints.GPlayersGlove[player.Slot] = gloveData.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -58,71 +84,131 @@ namespace WeaponPaints
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task GetAgentFromDatabase(PlayerInfo player)
|
private void GetAgentFromDatabase(PlayerInfo? player, MySqlConnection connection)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player?.SteamId))
|
if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player?.SteamId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
const string query = "SELECT `agent_ct`, `agent_t` FROM `wp_player_agents` WHERE `steamid` = @steamid";
|
||||||
string query = "SELECT `agent_ct`, `agent_t` FROM `wp_player_agents` WHERE `steamid` = @steamid";
|
var agentData = connection.QueryFirstOrDefault<(string, string)>(query, new { steamid = player.SteamId });
|
||||||
var agentData = await connection.QueryFirstOrDefaultAsync<(string, string)>(query, new { steamid = player.SteamId });
|
|
||||||
|
|
||||||
if (agentData != default)
|
if (agentData == default) return;
|
||||||
|
var agentCT = agentData.Item1;
|
||||||
|
var agentT = agentData.Item2;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(agentCT) || !string.IsNullOrEmpty(agentT))
|
||||||
{
|
{
|
||||||
string agentCT = agentData.Item1;
|
WeaponPaints.GPlayersAgent[player.Slot] = (
|
||||||
string agentT = agentData.Item2;
|
agentCT,
|
||||||
|
agentT
|
||||||
if (!string.IsNullOrEmpty(agentCT) || !string.IsNullOrEmpty(agentT))
|
);
|
||||||
{
|
|
||||||
WeaponPaints.g_playersAgent[player.Slot] = (
|
|
||||||
agentCT,
|
|
||||||
agentT
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Utility.Log($"An error occurred in GetGloveFromDatabase: {ex.Message}");
|
Utility.Log($"An error occurred in GetAgentFromDatabase: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task GetWeaponPaintsFromDatabase(PlayerInfo player)
|
private void GetWeaponPaintsFromDatabase(PlayerInfo? player, MySqlConnection connection)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_config.Additional.SkinEnabled || player == null || string.IsNullOrEmpty(player.SteamId))
|
if (!_config.Additional.SkinEnabled || player == null || string.IsNullOrEmpty(player.SteamId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
|
||||||
string query = "SELECT * FROM `wp_player_skins` WHERE `steamid` = @steamid";
|
|
||||||
var playerSkins = await connection.QueryAsync<dynamic>(query, new { steamid = player.SteamId });
|
|
||||||
|
|
||||||
if (playerSkins == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var weaponInfos = new ConcurrentDictionary<int, WeaponInfo>();
|
var weaponInfos = new ConcurrentDictionary<int, WeaponInfo>();
|
||||||
|
|
||||||
|
const string query = "SELECT * FROM `wp_player_skins` WHERE `steamid` = @steamid";
|
||||||
|
var playerSkins = connection.Query<dynamic>(query, new { steamid = player.SteamId });
|
||||||
|
|
||||||
foreach (var row in playerSkins)
|
foreach (var row in playerSkins)
|
||||||
{
|
{
|
||||||
int weaponDefIndex = row?.weapon_defindex ?? 0;
|
int weaponDefIndex = row?.weapon_defindex ?? 0;
|
||||||
int weaponPaintId = row?.weapon_paint_id ?? 0;
|
int weaponPaintId = row?.weapon_paint_id ?? 0;
|
||||||
float weaponWear = row?.weapon_wear ?? 0f;
|
float weaponWear = row?.weapon_wear ?? 0f;
|
||||||
int weaponSeed = row?.weapon_seed ?? 0;
|
int weaponSeed = row?.weapon_seed ?? 0;
|
||||||
|
string weaponNameTag = row?.weapon_nametag ?? "";
|
||||||
|
|
||||||
|
string[]? keyChainParts = row?.weapon_keychain?.ToString().Split(';');
|
||||||
|
|
||||||
|
KeyChainInfo keyChainInfo = new KeyChainInfo();
|
||||||
|
|
||||||
|
if (keyChainParts!.Length == 5 &&
|
||||||
|
uint.TryParse(keyChainParts[0], out uint keyChainId) &&
|
||||||
|
float.TryParse(keyChainParts[1], out float keyChainOffsetX) &&
|
||||||
|
float.TryParse(keyChainParts[2], out float keyChainOffsetY) &&
|
||||||
|
float.TryParse(keyChainParts[3], out float keyChainOffsetZ) &&
|
||||||
|
uint.TryParse(keyChainParts[4], out uint keyChainSeed))
|
||||||
|
{
|
||||||
|
// Successfully parsed the values
|
||||||
|
keyChainInfo.Id = keyChainId;
|
||||||
|
keyChainInfo.OffsetX = keyChainOffsetX;
|
||||||
|
keyChainInfo.OffsetY = keyChainOffsetY;
|
||||||
|
keyChainInfo.OffsetZ = keyChainOffsetZ;
|
||||||
|
keyChainInfo.Seed = keyChainSeed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Failed to parse the values, default to 0
|
||||||
|
keyChainInfo.Id = 0;
|
||||||
|
keyChainInfo.OffsetX = 0f;
|
||||||
|
keyChainInfo.OffsetY = 0f;
|
||||||
|
keyChainInfo.OffsetZ = 0f;
|
||||||
|
keyChainInfo.Seed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the WeaponInfo object
|
||||||
WeaponInfo weaponInfo = new WeaponInfo
|
WeaponInfo weaponInfo = new WeaponInfo
|
||||||
{
|
{
|
||||||
Paint = weaponPaintId,
|
Paint = weaponPaintId,
|
||||||
Seed = weaponSeed,
|
Seed = weaponSeed,
|
||||||
Wear = weaponWear
|
Wear = weaponWear,
|
||||||
|
Nametag = weaponNameTag,
|
||||||
|
KeyChain = keyChainInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Retrieve and parse sticker data (up to 5 slots)
|
||||||
|
for (int i = 0; i <= 4; i++)
|
||||||
|
{
|
||||||
|
// Access the sticker data dynamically using reflection
|
||||||
|
string stickerColumn = $"weapon_sticker_{i}";
|
||||||
|
var stickerData = ((IDictionary<string, object>)row!)[stickerColumn]; // Safely cast row to a dictionary
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(stickerData.ToString())) continue;
|
||||||
|
|
||||||
|
var parts = stickerData.ToString()!.Split(';');
|
||||||
|
|
||||||
|
//"id;schema;x;y;wear;scale;rotation"
|
||||||
|
if (parts.Length != 7 ||
|
||||||
|
!uint.TryParse(parts[0], out uint stickerId) ||
|
||||||
|
!uint.TryParse(parts[1], out uint stickerSchema) ||
|
||||||
|
!float.TryParse(parts[2], out float stickerOffsetX) ||
|
||||||
|
!float.TryParse(parts[3], out float stickerOffsetY) ||
|
||||||
|
!float.TryParse(parts[4], out float stickerWear) ||
|
||||||
|
!float.TryParse(parts[5], out float stickerScale) ||
|
||||||
|
!float.TryParse(parts[6], out float stickerRotation)) continue;
|
||||||
|
|
||||||
|
StickerInfo stickerInfo = new StickerInfo
|
||||||
|
{
|
||||||
|
Id = stickerId,
|
||||||
|
Schema = stickerSchema,
|
||||||
|
OffsetX = stickerOffsetX,
|
||||||
|
OffsetY = stickerOffsetY,
|
||||||
|
Wear = stickerWear,
|
||||||
|
Scale = stickerScale,
|
||||||
|
Rotation = stickerRotation
|
||||||
|
};
|
||||||
|
|
||||||
|
weaponInfo.Stickers.Add(stickerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
weaponInfos[weaponDefIndex] = weaponInfo;
|
weaponInfos[weaponDefIndex] = weaponInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
WeaponPaints.gPlayerWeaponsInfo[player.Slot] = weaponInfos;
|
WeaponPaints.GPlayerWeaponsInfo[player.Slot] = weaponInfos;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -130,14 +216,57 @@ namespace WeaponPaints
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GetMusicFromDatabase(PlayerInfo? player, MySqlConnection connection)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!_config.Additional.MusicEnabled || string.IsNullOrEmpty(player?.SteamId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const string query = "SELECT `music_id` FROM `wp_player_music` WHERE `steamid` = @steamid";
|
||||||
|
var musicData = connection.QueryFirstOrDefault<ushort?>(query, new { steamid = player.SteamId });
|
||||||
|
|
||||||
|
if (musicData != null)
|
||||||
|
{
|
||||||
|
WeaponPaints.GPlayersMusic[player.Slot] = musicData.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Utility.Log($"An error occurred in GetMusicFromDatabase: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetPinsFromDatabase(PlayerInfo? player, MySqlConnection connection)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(player?.SteamId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const string query = "SELECT `id` FROM `wp_player_pins` WHERE `steamid` = @steamid";
|
||||||
|
var pinData = connection.QueryFirstOrDefault<ushort?>(query, new { steamid = player.SteamId });
|
||||||
|
|
||||||
|
if (pinData != null)
|
||||||
|
{
|
||||||
|
WeaponPaints.GPlayersPin[player.Slot] = pinData.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Utility.Log($"An error occurred in GetPinsFromDatabase: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife)
|
internal async Task SyncKnifeToDatabase(PlayerInfo player, string knife)
|
||||||
{
|
{
|
||||||
if (!_config.Additional.KnifeEnabled || player == null || string.IsNullOrEmpty(player.SteamId) || string.IsNullOrEmpty(knife)) return;
|
if (!_config.Additional.KnifeEnabled || string.IsNullOrEmpty(player.SteamId) || string.IsNullOrEmpty(knife)) return;
|
||||||
|
|
||||||
|
const string query = "INSERT INTO `wp_player_knife` (`steamid`, `knife`) VALUES(@steamid, @newKnife) ON DUPLICATE KEY UPDATE `knife` = @newKnife";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
await using var connection = await _database.GetConnectionAsync();
|
||||||
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 });
|
await connection.ExecuteAsync(query, new { steamid = player.SteamId, newKnife = knife });
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -148,12 +277,12 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
internal async Task SyncGloveToDatabase(PlayerInfo player, int defindex)
|
internal async Task SyncGloveToDatabase(PlayerInfo player, int defindex)
|
||||||
{
|
{
|
||||||
if (!_config.Additional.GloveEnabled || player == null || string.IsNullOrEmpty(player.SteamId)) return;
|
if (!_config.Additional.GloveEnabled || string.IsNullOrEmpty(player.SteamId)) return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
await using var connection = await _database.GetConnectionAsync();
|
||||||
string query = "INSERT INTO `wp_player_gloves` (`steamid`, `weapon_defindex`) VALUES(@steamid, @weapon_defindex) ON DUPLICATE KEY UPDATE `weapon_defindex` = @weapon_defindex";
|
const string query = "INSERT INTO `wp_player_gloves` (`steamid`, `weapon_defindex`) VALUES(@steamid, @weapon_defindex) ON DUPLICATE KEY UPDATE `weapon_defindex` = @weapon_defindex";
|
||||||
await connection.ExecuteAsync(query, new { steamid = player.SteamId, weapon_defindex = defindex });
|
await connection.ExecuteAsync(query, new { steamid = player.SteamId, weapon_defindex = defindex });
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -164,19 +293,20 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
internal async Task SyncAgentToDatabase(PlayerInfo player)
|
internal async Task SyncAgentToDatabase(PlayerInfo player)
|
||||||
{
|
{
|
||||||
if (!_config.Additional.AgentEnabled || player == null || string.IsNullOrEmpty(player.SteamId)) return;
|
if (!_config.Additional.AgentEnabled || string.IsNullOrEmpty(player.SteamId)) return;
|
||||||
|
|
||||||
|
const string query = """
|
||||||
|
INSERT INTO `wp_player_agents` (`steamid`, `agent_ct`, `agent_t`)
|
||||||
|
VALUES(@steamid, @agent_ct, @agent_t)
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
`agent_ct` = @agent_ct,
|
||||||
|
`agent_t` = @agent_t
|
||||||
|
""";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
await using var connection = await _database.GetConnectionAsync();
|
||||||
string query = @"
|
|
||||||
INSERT INTO `wp_player_agents` (`steamid`, `agent_ct`, `agent_t`)
|
|
||||||
VALUES(@steamid, @agent_ct, @agent_t)
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
`agent_ct` = @agent_ct,
|
|
||||||
`agent_t` = @agent_t";
|
|
||||||
|
|
||||||
await connection.ExecuteAsync(query, new { steamid = player.SteamId, agent_ct = WeaponPaints.g_playersAgent[player.Slot].CT, agent_t = WeaponPaints.g_playersAgent[player.Slot].T });
|
await connection.ExecuteAsync(query, new { steamid = player.SteamId, agent_ct = WeaponPaints.GPlayersAgent[player.Slot].CT, agent_t = WeaponPaints.GPlayersAgent[player.Slot].T });
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -186,38 +316,36 @@ namespace WeaponPaints
|
|||||||
|
|
||||||
internal async Task SyncWeaponPaintsToDatabase(PlayerInfo player)
|
internal async Task SyncWeaponPaintsToDatabase(PlayerInfo player)
|
||||||
{
|
{
|
||||||
if (player == null || string.IsNullOrEmpty(player.SteamId) || !WeaponPaints.gPlayerWeaponsInfo.TryGetValue(player.Slot, out var weaponsInfo))
|
if (string.IsNullOrEmpty(player.SteamId) || !WeaponPaints.GPlayerWeaponsInfo.TryGetValue(player.Slot, out var weaponsInfo))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var connection = await _database.GetConnectionAsync();
|
await using var connection = await _database.GetConnectionAsync();
|
||||||
|
|
||||||
foreach (var weaponInfoPair in weaponsInfo)
|
foreach (var (weaponDefIndex, weaponInfo) in weaponsInfo)
|
||||||
{
|
{
|
||||||
int weaponDefIndex = weaponInfoPair.Key;
|
var paintId = weaponInfo.Paint;
|
||||||
WeaponInfo weaponInfo = weaponInfoPair.Value;
|
var wear = weaponInfo.Wear;
|
||||||
|
var seed = weaponInfo.Seed;
|
||||||
|
|
||||||
int paintId = weaponInfo.Paint;
|
const string queryCheckExistence = "SELECT COUNT(*) FROM `wp_player_skins` WHERE `steamid` = @steamid AND `weapon_defindex` = @weaponDefIndex";
|
||||||
float wear = weaponInfo.Wear;
|
|
||||||
int seed = weaponInfo.Seed;
|
|
||||||
|
|
||||||
string queryCheckExistence = "SELECT COUNT(*) FROM `wp_player_skins` WHERE `steamid` = @steamid AND `weapon_defindex` = @weaponDefIndex";
|
var existingRecordCount = await connection.ExecuteScalarAsync<int>(queryCheckExistence, new { steamid = player.SteamId, weaponDefIndex = weaponDefIndex });
|
||||||
|
|
||||||
int existingRecordCount = await connection.ExecuteScalarAsync<int>(queryCheckExistence, new { steamid = player.SteamId, weaponDefIndex });
|
|
||||||
|
|
||||||
string query;
|
string query;
|
||||||
object parameters;
|
object parameters;
|
||||||
|
|
||||||
if (existingRecordCount > 0)
|
if (existingRecordCount > 0)
|
||||||
{
|
{
|
||||||
query = "UPDATE `wp_player_skins` SET `weapon_paint_id` = @paintId, `weapon_wear` = @wear, `weapon_seed` = @seed WHERE `steamid` = @steamid AND `weapon_defindex` = @weaponDefIndex";
|
query = "UPDATE `wp_player_skins` SET `weapon_paint_id` = @paintId, `weapon_wear` = @wear, `weapon_seed` = @seed WHERE `steamid` = @steamid AND `weapon_defindex` = @weaponDefIndex";
|
||||||
parameters = new { steamid = player.SteamId, weaponDefIndex, paintId, wear, seed };
|
parameters = new { steamid = player.SteamId, weaponDefIndex = weaponDefIndex, paintId, wear, seed };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
query = "INSERT INTO `wp_player_skins` (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`) " +
|
query = "INSERT INTO `wp_player_skins` (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`) " +
|
||||||
"VALUES (@steamid, @weaponDefIndex, @paintId, @wear, @seed)";
|
"VALUES (@steamid, @weaponDefIndex, @paintId, @wear, @seed)";
|
||||||
parameters = new { steamid = player.SteamId, weaponDefIndex, paintId, wear, seed };
|
parameters = new { steamid = player.SteamId, weaponDefIndex = weaponDefIndex, paintId, wear, seed };
|
||||||
}
|
}
|
||||||
|
|
||||||
await connection.ExecuteAsync(query, parameters);
|
await connection.ExecuteAsync(query, parameters);
|
||||||
@@ -228,5 +356,64 @@ namespace WeaponPaints
|
|||||||
Utility.Log($"Error syncing weapon paints to database: {e.Message}");
|
Utility.Log($"Error syncing weapon paints to database: {e.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal async Task SyncMusicToDatabase(PlayerInfo player, ushort music)
|
||||||
|
{
|
||||||
|
if (!_config.Additional.MusicEnabled || string.IsNullOrEmpty(player.SteamId)) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using var connection = await _database.GetConnectionAsync();
|
||||||
|
const string query = "INSERT INTO `wp_player_music` (`steamid`, `music_id`) VALUES(@steamid, @newMusic) ON DUPLICATE KEY UPDATE `music_id` = @newMusic";
|
||||||
|
await connection.ExecuteAsync(query, new { steamid = player.SteamId, newMusic = music });
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Utility.Log($"Error syncing music kit to database: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task SyncStatTrakToDatabase(PlayerInfo player, ConcurrentDictionary<int,WeaponInfo> weaponInfos)
|
||||||
|
{
|
||||||
|
if (WeaponPaints.WeaponSync == null || weaponInfos.IsEmpty) return;
|
||||||
|
|
||||||
|
var statTrakWeapons = weaponInfos
|
||||||
|
.Where(w => w.Value is { StatTrak: true, StatTrakCount: > 0 })
|
||||||
|
.ToDictionary(w => w.Key, w => w.Value.StatTrakCount);
|
||||||
|
|
||||||
|
if (statTrakWeapons.Count == 0) return;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(player.SteamId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using var connection = await _database.GetConnectionAsync();
|
||||||
|
await using var transaction = await connection.BeginTransactionAsync();
|
||||||
|
|
||||||
|
foreach (var (defindex, statTrakCount) in statTrakWeapons)
|
||||||
|
{
|
||||||
|
const string query = @"
|
||||||
|
INSERT INTO `wp_player_skins` (`steamid`, `weapon_defindex`, `weapon_stattrak_count`)
|
||||||
|
VALUES (@steamid, @weaponDefIndex, @StatTrakCount)
|
||||||
|
ON DUPLICATE KEY UPDATE `weapon_stattrak_count` = @StatTrakCount";
|
||||||
|
|
||||||
|
var parameters = new
|
||||||
|
{
|
||||||
|
steamid = player.SteamId,
|
||||||
|
weaponDefIndex = defindex,
|
||||||
|
StatTrakCount = statTrakCount
|
||||||
|
};
|
||||||
|
|
||||||
|
await connection.ExecuteAsync(query, parameters, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
await transaction.CommitAsync();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Utility.Log($"Error syncing stattrak to database: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
{
|
{
|
||||||
"ChangeSubclass": {
|
"ChangeSubclass": {
|
||||||
"signatures": {
|
"signatures": {
|
||||||
"library": "server",
|
"library": "server",
|
||||||
"windows": "\\x48\\x89\\x5C\\x24\\x08\\x57\\x48\\x83\\xEC\\x20\\x48\\x8B\\xDA\\x48\\x8B\\xF9\\xE8\\x2A\\x2A\\x2A\\x2A\\x84\\xC0\\x74\\x2A\\x41\\xB0\\x01",
|
"windows": "48 89 6C 24 ? 56 48 83 EC ? 48 8B EA 48 8B F1 E8 ? ? ? ? 84 C0 0F 84",
|
||||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x41\\x55\\x49\\x89\\xF5\\x41\\x54\\x49\\x89\\xFC\\x53\\x48\\x81\\xEC\\xA8\\x00\\x00\\x00"
|
"linux": "55 48 89 E5 41 57 41 56 41 55 49 89 F5 41 54 49 89 FC 53 48 81 EC A8 00 00 00"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"CAttributeList_SetOrAddAttributeValueByName": {
|
"CAttributeList_SetOrAddAttributeValueByName": {
|
||||||
"signatures": {
|
"signatures": {
|
||||||
"library": "server",
|
"library": "server",
|
||||||
"windows": "\\x40\\x53\\x41\\x56\\x41\\x57\\x48\\x81\\xEC\\x90\\x00\\x00\\x00\\x0F\\x29\\x74\\x24\\x70",
|
"windows": "40 53 41 56 41 57 48 81 EC 90 00 00 00 0F 29 74 24 70",
|
||||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x57\\x41\\x56\\x49\\x89\\xFE\\x41\\x55\\x41\\x54\\x49\\x89\\xF4\\x53\\x48\\x83\\xEC\\x78"
|
"linux": "55 48 89 E5 41 57 41 56 49 89 FE 41 55 41 54 49 89 F4 53 48 83 EC 78"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"CBaseModelEntity_SetBodygroup": {
|
"CBaseModelEntity_SetBodygroup": {
|
||||||
"signatures": {
|
"signatures": {
|
||||||
"library": "server",
|
"library": "server",
|
||||||
"windows": "\\x48\\x89\\x5C\\x24\\x08\\x48\\x89\\x74\\x24\\x10\\x57\\x48\\x83\\xEC\\x20\\x41\\x8B\\xF8\\x48\\x8B\\xF2\\x48\\x8B\\xD9\\xE8\\x2A\\x2A\\x2A\\x2A",
|
"windows": "48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 20 41 8B F8 48 8B F2 48 8B D9 E8 ? ? ? ?",
|
||||||
"linux": "\\x55\\x48\\x89\\xE5\\x41\\x56\\x49\\x89\\xF6\\x41\\x55\\x41\\x89\\xD5\\x41\\x54\\x49\\x89\\xFC\\x48\\x83\\xEC\\x08"
|
"linux": "55 48 89 E5 41 56 49 89 F6 41 55 41 89 D5 41 54 49 89 FC 48 83 EC 08"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
"wp_info_refresh": "Type {lime}!wp{default} to synchronize chosen skins",
|
"wp_info_refresh": "Type {lime}!wp{default} to synchronize chosen skins",
|
||||||
"wp_info_knife": "Type {lime}!knife{default} to open knife menu",
|
"wp_info_knife": "Type {lime}!knife{default} to open knife menu",
|
||||||
"wp_info_glove": "Type {lime}!gloves{default} to open gloves menu",
|
"wp_info_glove": "Type {lime}!gloves{default} to open gloves menu",
|
||||||
|
"wp_info_agent": "Type {lime}!agents{default} to open agents menu",
|
||||||
|
"wp_info_music": "Type {lime}!music{default} to open music menu",
|
||||||
"wp_command_cooldown": "{lightred}You can't refresh weapon paints right now",
|
"wp_command_cooldown": "{lightred}You can't refresh weapon paints right now",
|
||||||
"wp_command_refresh_done": "{lime}Refreshing weapon paints",
|
"wp_command_refresh_done": "{lime}Refreshing weapon paints",
|
||||||
"wp_knife_menu_select": "You have chosen {lime}{0}{default} as your knife",
|
"wp_knife_menu_select": "You have chosen {lime}{0}{default} as your knife",
|
||||||
@@ -13,6 +15,8 @@
|
|||||||
"wp_glove_menu_title": "Gloves Menu",
|
"wp_glove_menu_title": "Gloves Menu",
|
||||||
"wp_agent_menu_select": "You have chosen {lime}{0}{default} as your agent",
|
"wp_agent_menu_select": "You have chosen {lime}{0}{default} as your agent",
|
||||||
"wp_agent_menu_title": "Agents Menu",
|
"wp_agent_menu_title": "Agents Menu",
|
||||||
|
"wp_music_menu_title": "Music Menu",
|
||||||
|
"wp_music_menu_select": "You have chosen {lime}{0}{default} as your music kit",
|
||||||
"wp_skin_menu_weapon_title": "Weapon Menu",
|
"wp_skin_menu_weapon_title": "Weapon Menu",
|
||||||
"wp_skin_menu_skin_title": "Select skin for {lime}{0}{default}",
|
"wp_skin_menu_skin_title": "Select skin for {lime}{0}{default}",
|
||||||
"wp_skin_menu_select": "You have chosen {lime}{0}{default} as your skin",
|
"wp_skin_menu_select": "You have chosen {lime}{0}{default} as your skin",
|
||||||
|
|||||||
20
lang/lv.json
20
lang/lv.json
@@ -1,20 +1,24 @@
|
|||||||
{
|
{
|
||||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||||
"wp_info_website": "Apmeklējiet {lime}{0}{default}, kur varat mainīt ādas",
|
"wp_info_website": "Apmeklē {lime}{0}{default}, kur varat mainīt ādas",
|
||||||
"wp_info_refresh": "Ievadiet {lime}!wp{default}, lai sinhronizētu izvēlētās ādas",
|
"wp_info_refresh": "Ievadiet {lime}!wp{default}, lai sinhronizētu izvēlētās ādas",
|
||||||
"wp_info_knife": "Ievadiet {lime}!knife{default}, lai atvērtu nazis izvēlni",
|
"wp_info_knife": "Ievadiet {lime}!knife{default}, lai atvērtu nazis izvēlni",
|
||||||
"wp_info_glove": "Ievadiet {lime}!gloves{default}, lai atvērtu cimdi izvēlni",
|
"wp_info_glove": "Ievadiet {lime}!gloves{default}, lai atvērtu cimdi izvēlni",
|
||||||
"wp_command_cooldown": "{lightred}Šobrīd jūs nevarat atjaunot ieroču ādas",
|
"wp_info_agent": "Ievadiet {lime}!agents{default}, lai atvērtu aģentu izvēlni",
|
||||||
"wp_command_refresh_done": "{lime}Atjauno ieroču ādas",
|
"wp_info_music": "Ievadiet {lime}!music{default}, lai atvērtu mūzikas izvēlni",
|
||||||
|
"wp_command_cooldown": "{lightred}Šobrīd nevarat atsvaidzināt ieroča krāsas",
|
||||||
|
"wp_command_refresh_done": "{lime}Atsvaidzinot ieroča krāsas",
|
||||||
"wp_knife_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savu nazi",
|
"wp_knife_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savu nazi",
|
||||||
"wp_knife_menu_kill": "",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "Nazis Izvēlne",
|
"wp_knife_menu_title": "Nazi Izvēlne",
|
||||||
"wp_glove_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savus cimdus",
|
"wp_glove_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savu cimdu",
|
||||||
"wp_glove_menu_title": "Cimdu Izvēlne",
|
"wp_glove_menu_title": "Cimdu Izvēlne",
|
||||||
"wp_agent_menu_select": "Jūs esat izvēlējušies {lime}{0}{default} kā savu aģentu",
|
"wp_agent_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savu aģentu",
|
||||||
"wp_agent_menu_title": "Aģentu izvēlnes",
|
"wp_agent_menu_title": "Aģentu Izvēlne",
|
||||||
|
"wp_music_menu_title": "Mūzikas Izvēlne",
|
||||||
|
"wp_music_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savu mūzikas komplektu",
|
||||||
"wp_skin_menu_weapon_title": "Ieroču Izvēlne",
|
"wp_skin_menu_weapon_title": "Ieroču Izvēlne",
|
||||||
"wp_skin_menu_skin_title": "Izvēlieties ādu {lime}{0}{default}",
|
"wp_skin_menu_skin_title": "Izvēlieties ādu priekš {lime}{0}{default}",
|
||||||
"wp_skin_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savu ādu",
|
"wp_skin_menu_select": "Jūs esat izvēlējies {lime}{0}{default} kā savu ādu",
|
||||||
|
|
||||||
"None": "Nav"
|
"None": "Nav"
|
||||||
|
|||||||
16
lang/pl.json
16
lang/pl.json
@@ -3,16 +3,20 @@
|
|||||||
"wp_info_website": "Odwiedź {lime}{0}{default}, gdzie możesz zmieniać skórki",
|
"wp_info_website": "Odwiedź {lime}{0}{default}, gdzie możesz zmieniać skórki",
|
||||||
"wp_info_refresh": "Wpisz {lime}!wp{default}, aby zsynchronizować wybrane skórki",
|
"wp_info_refresh": "Wpisz {lime}!wp{default}, aby zsynchronizować wybrane skórki",
|
||||||
"wp_info_knife": "Wpisz {lime}!knife{default}, aby otworzyć menu noży",
|
"wp_info_knife": "Wpisz {lime}!knife{default}, aby otworzyć menu noży",
|
||||||
"wp_info_glove": "Wpisz {lime}!gloves{default}, aby otworzyć menu rękawiczek",
|
"wp_info_glove": "Wpisz {lime}!gloves{default}, aby otworzyć menu rękawic",
|
||||||
"wp_command_cooldown": "{lightred}Nie możesz teraz odświeżyć skórek broni",
|
"wp_info_agent": "Wpisz {lime}!agents{default}, aby otworzyć menu agentów",
|
||||||
"wp_command_refresh_done": "{lime}Odświeżanie skórek broni",
|
"wp_info_music": "Wpisz {lime}!music{default}, aby otworzyć menu muzyczne",
|
||||||
|
"wp_command_cooldown": "{lightred}Nie możesz teraz odświeżyć kolorów broni",
|
||||||
|
"wp_command_refresh_done": "{lime}Odświeżanie kolorów broni",
|
||||||
"wp_knife_menu_select": "Wybrałeś {lime}{0}{default} jako swój nóż",
|
"wp_knife_menu_select": "Wybrałeś {lime}{0}{default} jako swój nóż",
|
||||||
"wp_knife_menu_kill": "{lime}Wybrane skiny będą ustawione dopiero po ponownym wejściu na serwer lub wpisaniu komendy {orange}!kill",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "Menu Noży",
|
"wp_knife_menu_title": "Menu Noży",
|
||||||
"wp_glove_menu_select": "Wybrałeś {lime}{0}{default} jako swoje rękawiczki",
|
"wp_glove_menu_select": "Wybrałeś {lime}{0}{default} jako swoją rękawiczkę",
|
||||||
"wp_glove_menu_title": "Menu Rękawiczek",
|
"wp_glove_menu_title": "Menu Rękawiczek",
|
||||||
"wp_agent_menu_select": "Wybrałeś {lime}{0}{default} jako swojego agenta",
|
"wp_agent_menu_select": "Wybrałeś {lime}{0}{default} jako swojego agenta",
|
||||||
"wp_agent_menu_title": "Menu agentów",
|
"wp_agent_menu_title": "Menu Agentów",
|
||||||
|
"wp_music_menu_title": "Menu Muzyczne",
|
||||||
|
"wp_music_menu_select": "Wybrałeś {lime}{0}{default} jako swój zestaw muzyczny",
|
||||||
"wp_skin_menu_weapon_title": "Menu Broni",
|
"wp_skin_menu_weapon_title": "Menu Broni",
|
||||||
"wp_skin_menu_skin_title": "Wybierz skórkę dla {lime}{0}{default}",
|
"wp_skin_menu_skin_title": "Wybierz skórkę dla {lime}{0}{default}",
|
||||||
"wp_skin_menu_select": "Wybrałeś {lime}{0}{default} jako swoją skórkę",
|
"wp_skin_menu_select": "Wybrałeś {lime}{0}{default} jako swoją skórkę",
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
{
|
{
|
||||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||||
"wp_info_website": "Visite {lime}{0}{default}, onde você pode alterar skins",
|
"wp_info_website": "Visite {lime}{0}{default}, onde você pode alterar as skins",
|
||||||
"wp_info_refresh": "Digite {lime}!wp{default} para sincronizar as skins selecionadas",
|
"wp_info_refresh": "Digite {lime}!wp{default} para sincronizar as skins escolhidas",
|
||||||
"wp_info_knife": "Digite {lime}!knife{default} para abrir o menu de facas",
|
"wp_info_knife": "Digite {lime}!knife{default} para abrir o menu de facas",
|
||||||
"wp_info_glove": "Digite {lime}!gloves{default} para abrir o menu de luvas",
|
"wp_info_glove": "Digite {lime}!gloves{default} para abrir o menu de luvas",
|
||||||
"wp_command_cooldown": "{lightred}Você não pode atualizar as skins de arma agora",
|
"wp_info_agent": "Digite {lime}!agents{default} para abrir o menu de agentes",
|
||||||
"wp_command_refresh_done": "{lime}Atualizando as skins de arma",
|
"wp_info_music": "Digite {lime}!music{default} para abrir o menu de música",
|
||||||
|
"wp_command_cooldown": "{lightred}Você não pode atualizar as skins de armas agora",
|
||||||
|
"wp_command_refresh_done": "{lime}Atualizando as skins de armas",
|
||||||
"wp_knife_menu_select": "Você escolheu {lime}{0}{default} como sua faca",
|
"wp_knife_menu_select": "Você escolheu {lime}{0}{default} como sua faca",
|
||||||
"wp_knife_menu_kill": "",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "Menu de Facas",
|
"wp_knife_menu_title": "Menu de Facas",
|
||||||
"wp_glove_menu_select": "Você escolheu {lime}{0}{default} como suas luvas",
|
"wp_glove_menu_select": "Você escolheu {lime}{0}{default} como sua luva",
|
||||||
"wp_glove_menu_title": "Menu de Luvas",
|
"wp_glove_menu_title": "Menu de Luvas",
|
||||||
"wp_agent_menu_select": "Você escolheu {lime}{0}{default} como seu agente",
|
"wp_agent_menu_select": "Você escolheu {lime}{0}{default} como seu agente",
|
||||||
"wp_agent_menu_title": "Menu de Agentes",
|
"wp_agent_menu_title": "Menu de Agentes",
|
||||||
|
"wp_music_menu_title": "Menu de Música",
|
||||||
|
"wp_music_menu_select": "Você escolheu {lime}{0}{default} como seu kit de música",
|
||||||
"wp_skin_menu_weapon_title": "Menu de Armas",
|
"wp_skin_menu_weapon_title": "Menu de Armas",
|
||||||
"wp_skin_menu_skin_title": "Selecione uma skin para {lime}{0}{default}",
|
"wp_skin_menu_skin_title": "Selecione a skin para {lime}{0}{default}",
|
||||||
"wp_skin_menu_select": "Você escolheu {lime}{0}{default} como sua skin",
|
"wp_skin_menu_select": "Você escolheu {lime}{0}{default} como sua skin",
|
||||||
|
|
||||||
"None": "Nenhum"
|
"None": "Nenhum"
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
{
|
{
|
||||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||||
"wp_info_website": "Visite {lime}{0}{default}, onde pode alterar skins",
|
"wp_info_website": "Visite {lime}{0}{default}, onde pode alterar as skins",
|
||||||
"wp_info_refresh": "Digite {lime}!wp{default} para sincronizar as skins selecionadas",
|
"wp_info_refresh": "Digite {lime}!wp{default} para sincronizar as skins escolhidas",
|
||||||
"wp_info_knife": "Digite {lime}!knife{default} para abrir o menu de facas",
|
"wp_info_knife": "Digite {lime}!knife{default} para abrir o menu de facas",
|
||||||
"wp_info_glove": "Digite {lime}!gloves{default} para abrir o menu de luvas",
|
"wp_info_glove": "Digite {lime}!gloves{default} para abrir o menu de luvas",
|
||||||
"wp_command_cooldown": "{lightred}Você não pode atualizar as skins de arma agora",
|
"wp_info_agent": "Digite {lime}!agents{default} para abrir o menu de agentes",
|
||||||
"wp_command_refresh_done": "{lime}Atualizando as skins de arma",
|
"wp_info_music": "Digite {lime}!music{default} para abrir o menu de música",
|
||||||
"wp_knife_menu_select": "Você escolheu {lime}{0}{default} como sua faca",
|
"wp_command_cooldown": "{lightred}Não pode atualizar as skins de armas de momento",
|
||||||
|
"wp_command_refresh_done": "{lime}Atualizando as skins de armas",
|
||||||
|
"wp_knife_menu_select": "Escolheu {lime}{0}{default} como a sua faca",
|
||||||
"wp_knife_menu_kill": "",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "Menu de Facas",
|
"wp_knife_menu_title": "Menu de Facas",
|
||||||
"wp_glove_menu_select": "Você escolheu {lime}{0}{default} como suas luvas",
|
"wp_glove_menu_select": "Escolheu {lime}{0}{default} como a sua luva",
|
||||||
"wp_glove_menu_title": "Menu de Luvas",
|
"wp_glove_menu_title": "Menu de Luvas",
|
||||||
"wp_agent_menu_select": "Escolheste {lime}{0}{default} como teu agente",
|
"wp_agent_menu_select": "Escolheu {lime}{0}{default} como o seu agente",
|
||||||
"wp_agent_menu_title": "Menu de Agentes",
|
"wp_agent_menu_title": "Menu de Agentes",
|
||||||
|
"wp_music_menu_title": "Menu de Música",
|
||||||
|
"wp_music_menu_select": "Escolheu {lime}{0}{default} como o seu kit de música",
|
||||||
"wp_skin_menu_weapon_title": "Menu de Armas",
|
"wp_skin_menu_weapon_title": "Menu de Armas",
|
||||||
"wp_skin_menu_skin_title": "Selecione uma skin para {lime}{0}{default}",
|
"wp_skin_menu_skin_title": "Selecione a skin para {lime}{0}{default}",
|
||||||
"wp_skin_menu_select": "Você escolheu {lime}{0}{default} como sua skin",
|
"wp_skin_menu_select": "Escolheu {lime}{0}{default} como a sua skin",
|
||||||
|
|
||||||
"None": "Nenhum"
|
"None": "Nenhum"
|
||||||
}
|
}
|
||||||
12
lang/ru.json
12
lang/ru.json
@@ -4,15 +4,19 @@
|
|||||||
"wp_info_refresh": "Введите {lime}!wp{default}, чтобы синхронизировать выбранные скины",
|
"wp_info_refresh": "Введите {lime}!wp{default}, чтобы синхронизировать выбранные скины",
|
||||||
"wp_info_knife": "Введите {lime}!knife{default}, чтобы открыть меню ножей",
|
"wp_info_knife": "Введите {lime}!knife{default}, чтобы открыть меню ножей",
|
||||||
"wp_info_glove": "Введите {lime}!gloves{default}, чтобы открыть меню перчаток",
|
"wp_info_glove": "Введите {lime}!gloves{default}, чтобы открыть меню перчаток",
|
||||||
"wp_command_cooldown": "{lightred}Вы не можете обновить скины оружия сейчас",
|
"wp_info_agent": "Введите {lime}!agents{default}, чтобы открыть меню агентов",
|
||||||
"wp_command_refresh_done": "{lime}Обновление скинов оружия",
|
"wp_info_music": "Введите {lime}!music{default}, чтобы открыть меню музыки",
|
||||||
|
"wp_command_cooldown": "{lightred}Вы не можете обновить раскраску оружия сейчас",
|
||||||
|
"wp_command_refresh_done": "{lime}Обновление раскраски оружия",
|
||||||
"wp_knife_menu_select": "Вы выбрали {lime}{0}{default} в качестве вашего ножа",
|
"wp_knife_menu_select": "Вы выбрали {lime}{0}{default} в качестве вашего ножа",
|
||||||
"wp_knife_menu_kill": "",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "Меню Ножей",
|
"wp_knife_menu_title": "Меню Ножей",
|
||||||
"wp_glove_menu_select": "Вы выбрали {lime}{0}{default} в качестве ваших перчаток",
|
"wp_glove_menu_select": "Вы выбрали {lime}{0}{default} в качестве ваших перчаток",
|
||||||
"wp_glove_menu_title": "Меню Перчаток",
|
"wp_glove_menu_title": "Меню Перчаток",
|
||||||
"wp_agent_menu_select": "Вы выбрали {lime}{0}{default} в качестве своего агента",
|
"wp_agent_menu_select": "Вы выбрали {lime}{0}{default} в качестве вашего агента",
|
||||||
"wp_agent_menu_title": "Меню агентов",
|
"wp_agent_menu_title": "Меню Агентов",
|
||||||
|
"wp_music_menu_title": "Меню Музыки",
|
||||||
|
"wp_music_menu_select": "Вы выбрали {lime}{0}{default} в качестве вашего музыкального набора",
|
||||||
"wp_skin_menu_weapon_title": "Меню Оружия",
|
"wp_skin_menu_weapon_title": "Меню Оружия",
|
||||||
"wp_skin_menu_skin_title": "Выберите скин для {lime}{0}{default}",
|
"wp_skin_menu_skin_title": "Выберите скин для {lime}{0}{default}",
|
||||||
"wp_skin_menu_select": "Вы выбрали {lime}{0}{default} в качестве вашего скина",
|
"wp_skin_menu_select": "Вы выбрали {lime}{0}{default} в качестве вашего скина",
|
||||||
|
|||||||
22
lang/tr.json
22
lang/tr.json
@@ -1,21 +1,25 @@
|
|||||||
{
|
{
|
||||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||||
"wp_info_website": "Ziyaret edin {lime}{0}{default}, burada skinleri değiştirebilirsiniz",
|
"wp_info_website": "Ziyaret edin {lime}{0}{default}, nerede derileri değiştirebilirsiniz",
|
||||||
"wp_info_refresh": "Senkronize edilen skinleri görmek için {lime}!wp{default} yazın",
|
"wp_info_refresh": "Senkronize etmek için {lime}!wp{default} yazın seçilen deriler",
|
||||||
"wp_info_knife": "Bıçak menüsünü açmak için {lime}!knife{default} yazın",
|
"wp_info_knife": "Bıçak menüsünü açmak için {lime}!knife{default} yazın",
|
||||||
"wp_info_glove": "Eldiven menüsünü açmak için {lime}!gloves{default} yazın",
|
"wp_info_glove": "Handskar menüsünü açmak için {lime}!gloves{default} yazın",
|
||||||
"wp_command_cooldown": "{lightred}Şu anda silah skinlerini yenileyemezsiniz",
|
"wp_info_agent": "Ajan menüsünü açmak için {lime}!agents{default} yazın",
|
||||||
"wp_command_refresh_done": "{lime}Silah skinleri yenileniyor",
|
"wp_info_music": "Müzik menüsünü açmak için {lime}!music{default} yazın",
|
||||||
|
"wp_command_cooldown": "{lightred}Şu anda silah boyalarını yenileyemezsiniz",
|
||||||
|
"wp_command_refresh_done": "{lime}Silah boyaları yenileniyor",
|
||||||
"wp_knife_menu_select": "{lime}{0}{default} olarak bıçağınızı seçtiniz",
|
"wp_knife_menu_select": "{lime}{0}{default} olarak bıçağınızı seçtiniz",
|
||||||
"wp_knife_menu_kill": "",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "Bıçak Menüsü",
|
"wp_knife_menu_title": "Bıçak Menüsü",
|
||||||
"wp_glove_menu_select": "{lime}{0}{default} olarak eldiveninizi seçtiniz",
|
"wp_glove_menu_select": "{lime}{0}{default} olarak eldiveninizi seçtiniz",
|
||||||
"wp_glove_menu_title": "Eldiven Menüsü",
|
"wp_glove_menu_title": "Eldiven Menüsü",
|
||||||
"wp_agent_menu_select": "Ajanınız olarak {lime}{0}{default} seçtiniz",
|
"wp_agent_menu_select": "{lime}{0}{default} olarak ajanınızı seçtiniz",
|
||||||
"wp_agent_menu_title": "Ajan Menüsü",
|
"wp_agent_menu_title": "Ajanlar Menüsü",
|
||||||
|
"wp_music_menu_title": "Müzik Menüsü",
|
||||||
|
"wp_music_menu_select": "{lime}{0}{default} olarak müzik setinizi seçtiniz",
|
||||||
"wp_skin_menu_weapon_title": "Silah Menüsü",
|
"wp_skin_menu_weapon_title": "Silah Menüsü",
|
||||||
"wp_skin_menu_skin_title": "{lime}{0}{default} için bir skin seçin",
|
"wp_skin_menu_skin_title": "{lime}{0}{default} için cilt seçin",
|
||||||
"wp_skin_menu_select": "{lime}{0}{default} olarak bir skin seçtiniz",
|
"wp_skin_menu_select": "{lime}{0}{default} olarak cildinizi seçtiniz",
|
||||||
|
|
||||||
"None": "Hiçbiri"
|
"None": "Hiçbiri"
|
||||||
}
|
}
|
||||||
18
lang/ua.json
18
lang/ua.json
@@ -4,18 +4,22 @@
|
|||||||
"wp_info_refresh": "Введіть {lime}!wp{default}, щоб синхронізувати обрані шкури",
|
"wp_info_refresh": "Введіть {lime}!wp{default}, щоб синхронізувати обрані шкури",
|
||||||
"wp_info_knife": "Введіть {lime}!knife{default}, щоб відкрити меню ножів",
|
"wp_info_knife": "Введіть {lime}!knife{default}, щоб відкрити меню ножів",
|
||||||
"wp_info_glove": "Введіть {lime}!gloves{default}, щоб відкрити меню рукавичок",
|
"wp_info_glove": "Введіть {lime}!gloves{default}, щоб відкрити меню рукавичок",
|
||||||
"wp_command_cooldown": "{lightred}Наразі ви не можете оновлювати шкіри зброї",
|
"wp_info_agent": "Введіть {lime}!agents{default}, щоб відкрити меню агентів",
|
||||||
"wp_command_refresh_done": "{lime}Оновлення шкірок зброї",
|
"wp_info_music": "Введіть {lime}!music{default}, щоб відкрити меню музики",
|
||||||
"wp_knife_menu_select": "Ви вибрали {lime}{0}{default} як ваш ніж",
|
"wp_command_cooldown": "{lightred}Ви не можете оновити фарби зброї зараз",
|
||||||
|
"wp_command_refresh_done": "{lime}Оновлення фарби зброї",
|
||||||
|
"wp_knife_menu_select": "Ви обрали {lime}{0}{default} як свій ніж",
|
||||||
"wp_knife_menu_kill": "",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "Меню Ножів",
|
"wp_knife_menu_title": "Меню Ножів",
|
||||||
"wp_glove_menu_select": "Ви вибрали {lime}{0}{default} як ваші рукавички",
|
"wp_glove_menu_select": "Ви обрали {lime}{0}{default} як свої рукавички",
|
||||||
"wp_glove_menu_title": "Меню Рукавичок",
|
"wp_glove_menu_title": "Меню Рукавичок",
|
||||||
"wp_agent_menu_select": "Ви обрали {lime}{0}{default} як вашого агента",
|
"wp_agent_menu_select": "Ви обрали {lime}{0}{default} як свого агента",
|
||||||
"wp_agent_menu_title": "Меню агентів",
|
"wp_agent_menu_title": "Меню Агентів",
|
||||||
|
"wp_music_menu_title": "Меню Музики",
|
||||||
|
"wp_music_menu_select": "Ви обрали {lime}{0}{default} як свій набір музики",
|
||||||
"wp_skin_menu_weapon_title": "Меню Зброї",
|
"wp_skin_menu_weapon_title": "Меню Зброї",
|
||||||
"wp_skin_menu_skin_title": "Виберіть шкіру для {lime}{0}{default}",
|
"wp_skin_menu_skin_title": "Виберіть шкіру для {lime}{0}{default}",
|
||||||
"wp_skin_menu_select": "Ви вибрали {lime}{0}{default} як вашу шкіру",
|
"wp_skin_menu_select": "Ви обрали {lime}{0}{default} як свою шкіру",
|
||||||
|
|
||||||
"None": "Немає"
|
"None": "Немає"
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,25 @@
|
|||||||
{
|
{
|
||||||
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
"wp_prefix": "{lightblue}[WeaponPaints] {default}",
|
||||||
"wp_info_website": "访问 {lime}{0}{default},您可以更改皮肤",
|
"wp_info_website": "访问 {lime}{0}{default},您可以更改皮肤",
|
||||||
"wp_info_refresh": "输入 {lime}!wp{default} 同步已选择的皮肤",
|
"wp_info_refresh": "输入 {lime}!wp{default} 同步选择的皮肤",
|
||||||
"wp_info_knife": "输入 {lime}!knife{default} 打开刀具菜单",
|
"wp_info_knife": "输入 {lime}!knife{default} 打开刀具菜单",
|
||||||
"wp_info_glove": "输入 {lime}!gloves{default} 打开手套菜单",
|
"wp_info_glove": "输入 {lime}!gloves{default} 打开手套菜单",
|
||||||
"wp_command_cooldown": "{lightred}您现在无法刷新武器皮肤",
|
"wp_info_agent": "输入 {lime}!agents{default} 打开代理菜单",
|
||||||
"wp_command_refresh_done": "{lime}刷新武器皮肤",
|
"wp_info_music": "输入 {lime}!music{default} 打开音乐菜单",
|
||||||
"wp_knife_menu_select": "您已选择 {lime}{0}{default} 作为您的刀具",
|
"wp_command_cooldown": "{lightred}您现在无法刷新武器涂装",
|
||||||
|
"wp_command_refresh_done": "{lime}正在刷新武器涂装",
|
||||||
|
"wp_knife_menu_select": "您选择了 {lime}{0}{default} 作为您的刀具",
|
||||||
"wp_knife_menu_kill": "",
|
"wp_knife_menu_kill": "",
|
||||||
"wp_knife_menu_title": "刀具菜单",
|
"wp_knife_menu_title": "刀具菜单",
|
||||||
"wp_glove_menu_select": "您已选择 {lime}{0}{default} 作为您的手套",
|
"wp_glove_menu_select": "您选择了 {lime}{0}{default} 作为您的手套",
|
||||||
"wp_glove_menu_title": "手套菜单",
|
"wp_glove_menu_title": "手套菜单",
|
||||||
"wp_agent_menu_select": "您选择了{lime}{0}{default}作为您的代理",
|
"wp_agent_menu_select": "您选择了 {lime}{0}{default} 作为您的代理",
|
||||||
"wp_agent_menu_title": "代理菜单",
|
"wp_agent_menu_title": "代理菜单",
|
||||||
|
"wp_music_menu_title": "音乐菜单",
|
||||||
|
"wp_music_menu_select": "您选择了 {lime}{0}{default} 作为您的音乐包",
|
||||||
"wp_skin_menu_weapon_title": "武器菜单",
|
"wp_skin_menu_weapon_title": "武器菜单",
|
||||||
"wp_skin_menu_skin_title": "为 {lime}{0}{default} 选择皮肤",
|
"wp_skin_menu_skin_title": "选择 {lime}{0}{default} 的皮肤",
|
||||||
"wp_skin_menu_select": "您已选择 {lime}{0}{default} 作为您的皮肤",
|
"wp_skin_menu_select": "您选择了 {lime}{0}{default} 作为您的皮肤",
|
||||||
|
|
||||||
"None": "无"
|
"None": "无"
|
||||||
}
|
}
|
||||||
@@ -1,386 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "",
|
|
||||||
"model": "null",
|
|
||||||
"agent_name": "Agent | Default"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "",
|
|
||||||
"model": "null",
|
|
||||||
"agent_name": "Agent | Default"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4619.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_variantj",
|
|
||||||
"agent_name": "'Blueberries' Buckshot | NSWC SEAL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4680.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_variantl",
|
|
||||||
"agent_name": "'Two Times' McCoy | TACP Cavalry"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4711.png",
|
|
||||||
"model": "ctm_swat/ctm_swat_variante",
|
|
||||||
"agent_name": "Cmdr. Mae 'Dead Cold' Jamison | SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4712.png",
|
|
||||||
"model": "ctm_swat/ctm_swat_variantf",
|
|
||||||
"agent_name": "1st Lieutenant Farlow | SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4713.png",
|
|
||||||
"model": "ctm_swat/ctm_swat_variantg",
|
|
||||||
"agent_name": "John 'Van Healen' Kask | SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4714.png",
|
|
||||||
"model": "ctm_swat/ctm_swat_varianth",
|
|
||||||
"agent_name": "Bio-Haz Specialist | SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4715.png",
|
|
||||||
"model": "ctm_swat/ctm_swat_varianti",
|
|
||||||
"agent_name": "Sergeant Bombson | SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4716.png",
|
|
||||||
"model": "ctm_swat/ctm_swat_variantj",
|
|
||||||
"agent_name": "Chem-Haz Specialist | SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4718.png",
|
|
||||||
"model": "tm_balkan/tm_balkan_variantk",
|
|
||||||
"agent_name": "Rezan the Redshirt | Sabre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4726.png",
|
|
||||||
"model": "tm_professional/tm_professional_varf",
|
|
||||||
"agent_name": "Sir Bloody Miami Darryl | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4727.png",
|
|
||||||
"model": "tm_professional/tm_professional_varg",
|
|
||||||
"agent_name": "Safecracker Voltzmann | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4728.png",
|
|
||||||
"model": "tm_professional/tm_professional_varh",
|
|
||||||
"agent_name": "Little Kev | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4730.png",
|
|
||||||
"model": "tm_professional/tm_professional_varj",
|
|
||||||
"agent_name": "Getaway Sally | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4732.png",
|
|
||||||
"model": "tm_professional/tm_professional_vari",
|
|
||||||
"agent_name": "Number K | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4733.png",
|
|
||||||
"model": "tm_professional/tm_professional_varf1",
|
|
||||||
"agent_name": "Sir Bloody Silent Darryl | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4734.png",
|
|
||||||
"model": "tm_professional/tm_professional_varf2",
|
|
||||||
"agent_name": "Sir Bloody Skullhead Darryl | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4735.png",
|
|
||||||
"model": "tm_professional/tm_professional_varf3",
|
|
||||||
"agent_name": "Sir Bloody Darryl Royale | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4736.png",
|
|
||||||
"model": "tm_professional/tm_professional_varf4",
|
|
||||||
"agent_name": "Sir Bloody Loudmouth Darryl | The Professionals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4749.png",
|
|
||||||
"model": "ctm_gendarmerie/ctm_gendarmerie_varianta",
|
|
||||||
"agent_name": "Sous-Lieutenant Medic | Gendarmerie Nationale"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4750.png",
|
|
||||||
"model": "ctm_gendarmerie/ctm_gendarmerie_variantb",
|
|
||||||
"agent_name": "Chem-Haz Capitaine | Gendarmerie Nationale"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4751.png",
|
|
||||||
"model": "ctm_gendarmerie/ctm_gendarmerie_variantc",
|
|
||||||
"agent_name": "Chef d'Escadron Rouchard | Gendarmerie Nationale"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4752.png",
|
|
||||||
"model": "ctm_gendarmerie/ctm_gendarmerie_variantd",
|
|
||||||
"agent_name": "Aspirant | Gendarmerie Nationale"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4753.png",
|
|
||||||
"model": "ctm_gendarmerie/ctm_gendarmerie_variante",
|
|
||||||
"agent_name": "Officer Jacques Beltram | Gendarmerie Nationale"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4756.png",
|
|
||||||
"model": "ctm_swat/ctm_swat_variantk",
|
|
||||||
"agent_name": "Lieutenant 'Tree Hugger' Farlow | SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4757.png",
|
|
||||||
"model": "ctm_diver/ctm_diver_varianta",
|
|
||||||
"agent_name": "Cmdr. Davida 'Goggles' Fernandez | SEAL Frogman"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4771.png",
|
|
||||||
"model": "ctm_diver/ctm_diver_variantb",
|
|
||||||
"agent_name": "Cmdr. Frank 'Wet Sox' Baroud | SEAL Frogman"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4772.png",
|
|
||||||
"model": "ctm_diver/ctm_diver_variantc",
|
|
||||||
"agent_name": "Lieutenant Rex Krikey | SEAL Frogman"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4773.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_varianta",
|
|
||||||
"agent_name": "Elite Trapper Solman | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4774.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_variantb",
|
|
||||||
"agent_name": "Crasswater The Forgotten | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4775.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_variantc",
|
|
||||||
"agent_name": "Arno The Overgrown | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4776.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_variantd",
|
|
||||||
"agent_name": "Col. Mangos Dabisi | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4777.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_variante",
|
|
||||||
"agent_name": "Vypa Sista of the Revolution | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4778.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_variantf",
|
|
||||||
"agent_name": "Trapper Aggressor | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4780.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_variantb2",
|
|
||||||
"agent_name": "'Medium Rare' Crasswater | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-4781.png",
|
|
||||||
"model": "tm_jungle_raider/tm_jungle_raider_variantf2",
|
|
||||||
"agent_name": "Trapper | Guerrilla Warfare"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5105.png",
|
|
||||||
"model": "tm_leet/tm_leet_variantg",
|
|
||||||
"agent_name": "Ground Rebel | Elite Crew"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5106.png",
|
|
||||||
"model": "tm_leet/tm_leet_varianth",
|
|
||||||
"agent_name": "Osiris | Elite Crew"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5107.png",
|
|
||||||
"model": "tm_leet/tm_leet_varianti",
|
|
||||||
"agent_name": "Prof. Shahmat | Elite Crew"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5108.png",
|
|
||||||
"model": "tm_leet/tm_leet_variantf",
|
|
||||||
"agent_name": "The Elite Mr. Muhlik | Elite Crew"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5109.png",
|
|
||||||
"model": "tm_leet/tm_leet_variantj",
|
|
||||||
"agent_name": "Jungle Rebel | Elite Crew"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5205.png",
|
|
||||||
"model": "tm_phoenix/tm_phoenix_varianth",
|
|
||||||
"agent_name": "Soldier | Phoenix"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5206.png",
|
|
||||||
"model": "tm_phoenix/tm_phoenix_variantf",
|
|
||||||
"agent_name": "Enforcer | Phoenix"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5207.png",
|
|
||||||
"model": "tm_phoenix/tm_phoenix_variantg",
|
|
||||||
"agent_name": "Slingshot | Phoenix"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5208.png",
|
|
||||||
"model": "tm_phoenix/tm_phoenix_varianti",
|
|
||||||
"agent_name": "Street Soldier | Phoenix"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5305.png",
|
|
||||||
"model": "ctm_fbi/ctm_fbi_variantf",
|
|
||||||
"agent_name": "Operator | FBI SWAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5306.png",
|
|
||||||
"model": "ctm_fbi/ctm_fbi_variantg",
|
|
||||||
"agent_name": "Markus Delrow | FBI HRT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5307.png",
|
|
||||||
"model": "ctm_fbi/ctm_fbi_varianth",
|
|
||||||
"agent_name": "Michael Syfers | FBI Sniper"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5308.png",
|
|
||||||
"model": "ctm_fbi/ctm_fbi_variantb",
|
|
||||||
"agent_name": "Special Agent Ava | FBI"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5400.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_variantk",
|
|
||||||
"agent_name": "3rd Commando Company | KSK"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5401.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_variante",
|
|
||||||
"agent_name": "Seal Team 6 Soldier | NSWC SEAL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5402.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_variantg",
|
|
||||||
"agent_name": "Buckshot | NSWC SEAL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5403.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_variantm",
|
|
||||||
"agent_name": "'Two Times' McCoy | USAF TACP"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5404.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_varianti",
|
|
||||||
"agent_name": "Lt. Commander Ricksaw | NSWC SEAL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5405.png",
|
|
||||||
"model": "ctm_st6/ctm_st6_variantn",
|
|
||||||
"agent_name": "Primeiro Tenente | Brazilian 1st Battalion"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5500.png",
|
|
||||||
"model": "tm_balkan/tm_balkan_variantf",
|
|
||||||
"agent_name": "Dragomir | Sabre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5501.png",
|
|
||||||
"model": "tm_balkan/tm_balkan_varianti",
|
|
||||||
"agent_name": "Maximus | Sabre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5502.png",
|
|
||||||
"model": "tm_balkan/tm_balkan_variantg",
|
|
||||||
"agent_name": "Rezan The Ready | Sabre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5503.png",
|
|
||||||
"model": "tm_balkan/tm_balkan_variantj",
|
|
||||||
"agent_name": "Blackwolf | Sabre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5504.png",
|
|
||||||
"model": "tm_balkan/tm_balkan_varianth",
|
|
||||||
"agent_name": "'The Doctor' Romanov | Sabre"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 2,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5505.png",
|
|
||||||
"model": "tm_balkan/tm_balkan_variantl",
|
|
||||||
"agent_name": "Dragomir | Sabre Footsoldier"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5601.png",
|
|
||||||
"model": "ctm_sas/ctm_sas_variantf",
|
|
||||||
"agent_name": "B Squadron Officer | SAS"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"team": 3,
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/agent-5602.png",
|
|
||||||
"model": "ctm_sas/ctm_sas_variantg",
|
|
||||||
"agent_name": "D Squadron Officer | NZSAS"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
1
website/data/agents_bg.json
Normal file
1
website/data/agents_bg.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_cs.json
Normal file
1
website/data/agents_cs.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_da.json
Normal file
1
website/data/agents_da.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_de.json
Normal file
1
website/data/agents_de.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_el.json
Normal file
1
website/data/agents_el.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_en.json
Normal file
1
website/data/agents_en.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_es-ES.json
Normal file
1
website/data/agents_es-ES.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_es-MX.json
Normal file
1
website/data/agents_es-MX.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_fi.json
Normal file
1
website/data/agents_fi.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_fr.json
Normal file
1
website/data/agents_fr.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_hu.json
Normal file
1
website/data/agents_hu.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_it.json
Normal file
1
website/data/agents_it.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_ja.json
Normal file
1
website/data/agents_ja.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_ko.json
Normal file
1
website/data/agents_ko.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_nl.json
Normal file
1
website/data/agents_nl.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_no.json
Normal file
1
website/data/agents_no.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_pl.json
Normal file
1
website/data/agents_pl.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_pt-BR.json
Normal file
1
website/data/agents_pt-BR.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_pt-PT.json
Normal file
1
website/data/agents_pt-PT.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_ro.json
Normal file
1
website/data/agents_ro.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_ru.json
Normal file
1
website/data/agents_ru.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_sv.json
Normal file
1
website/data/agents_sv.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_th.json
Normal file
1
website/data/agents_th.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_tr.json
Normal file
1
website/data/agents_tr.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_uk.json
Normal file
1
website/data/agents_uk.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_vi.json
Normal file
1
website/data/agents_vi.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_zh-CN.json
Normal file
1
website/data/agents_zh-CN.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/agents_zh-TW.json
Normal file
1
website/data/agents_zh-TW.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,440 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"weapon_defindex": 0,
|
|
||||||
"paint": "0",
|
|
||||||
"image": "",
|
|
||||||
"paint_name": "Gloves | Default"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 4725,
|
|
||||||
"paint": "10085",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_brokenfang_gloves-10085.png",
|
|
||||||
"paint_name": "★ Broken Fang Gloves | Jade"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 4725,
|
|
||||||
"paint": "10086",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_brokenfang_gloves-10086.png",
|
|
||||||
"paint_name": "★ Broken Fang Gloves | Yellow-banded"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 4725,
|
|
||||||
"paint": "10087",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_brokenfang_gloves-10087.png",
|
|
||||||
"paint_name": "★ Broken Fang Gloves | Needle Point"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 4725,
|
|
||||||
"paint": "10088",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_brokenfang_gloves-10088.png",
|
|
||||||
"paint_name": "★ Broken Fang Gloves | Unhinged"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5027,
|
|
||||||
"paint": "10006",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_bloodhound_gloves-10006.png",
|
|
||||||
"paint_name": "★ Bloodhound Gloves | Charred"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5027,
|
|
||||||
"paint": "10007",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_bloodhound_gloves-10007.png",
|
|
||||||
"paint_name": "★ Bloodhound Gloves | Snakebite"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5027,
|
|
||||||
"paint": "10008",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_bloodhound_gloves-10008.png",
|
|
||||||
"paint_name": "★ Bloodhound Gloves | Bronzed"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5027,
|
|
||||||
"paint": "10039",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_bloodhound_gloves-10039.png",
|
|
||||||
"paint_name": "★ Bloodhound Gloves | Guerrilla"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10018",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10018.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Superconductor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10019",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10019.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Arid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10037",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10037.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Pandora's Box"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10038",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10038.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Hedge Maze"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10045",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10045.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Amphibious"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10046",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10046.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Bronze Morph"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10047",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10047.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Omega"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10048",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10048.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Vice"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10073",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10073.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Slingshot"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10074",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10074.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Big Game"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10075",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10075.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Scarlet Shamagh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5030,
|
|
||||||
"paint": "10076",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/sporty_gloves-10076.png",
|
|
||||||
"paint_name": "★ Sport Gloves | Nocts"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10013",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10013.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Lunar Weave"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10015",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10015.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Convoy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10016",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10016.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Crimson Weave"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10040",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10040.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Diamondback"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10041",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10041.png",
|
|
||||||
"paint_name": "★ Driver Gloves | King Snake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10042",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10042.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Imperial Plaid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10043",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10043.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Overtake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10044",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10044.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Racing Green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10069",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10069.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Rezan the Red"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10070",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10070.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Snow Leopard"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10071",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10071.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Queen Jaguar"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5031,
|
|
||||||
"paint": "10072",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/slick_gloves-10072.png",
|
|
||||||
"paint_name": "★ Driver Gloves | Black Tie"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10009",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10009.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Leather"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10010",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10010.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Spruce DDPAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10021",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10021.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Slaughter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10036",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10036.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Badlands"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10053",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10053.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Cobalt Skulls"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10054",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10054.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Overprint"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10055",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10055.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Duct Tape"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10056",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10056.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Arboreal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10081",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10081.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Desert Shamagh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10082",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10082.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Giraffe"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10083",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10083.png",
|
|
||||||
"paint_name": "★ Hand Wraps | Constrictor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5032,
|
|
||||||
"paint": "10084",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/leather_handwraps-10084.png",
|
|
||||||
"paint_name": "★ Hand Wraps | CAUTION!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10024",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10024.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Eclipse"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10026",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10026.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Spearmint"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10027",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10027.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Boom!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10028",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10028.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Cool Mint"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10049",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10049.png",
|
|
||||||
"paint_name": "★ Moto Gloves | POW!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10050",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10050.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Turtle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10051",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10051.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Transport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10052",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10052.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Polygon"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10077",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10077.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Finish Line"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10078",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10078.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Smoke Out"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10079",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10079.png",
|
|
||||||
"paint_name": "★ Moto Gloves | Blood Pressure"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5033,
|
|
||||||
"paint": "10080",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/motorcycle_gloves-10080.png",
|
|
||||||
"paint_name": "★ Moto Gloves | 3rd Commando Company"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10030",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10030.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Forest DDPAT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10033",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10033.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Crimson Kimono"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10034",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10034.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Emerald Web"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10035",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10035.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Foundation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10061",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10061.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Crimson Web"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10062",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10062.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Buckshot"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10063",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10063.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Fade"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10064",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10064.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Mogul"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10065",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10065.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Marble Fade"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10066",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10066.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Lt. Commander"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10067",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10067.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Tiger Strike"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5034,
|
|
||||||
"paint": "10068",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/specialist_gloves-10068.png",
|
|
||||||
"paint_name": "★ Specialist Gloves | Field Agent"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5035,
|
|
||||||
"paint": "10057",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_hydra_gloves-10057.png",
|
|
||||||
"paint_name": "★ Hydra Gloves | Emerald"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5035,
|
|
||||||
"paint": "10058",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_hydra_gloves-10058.png",
|
|
||||||
"paint_name": "★ Hydra Gloves | Mangrove"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5035,
|
|
||||||
"paint": "10059",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_hydra_gloves-10059.png",
|
|
||||||
"paint_name": "★ Hydra Gloves | Rattler"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"weapon_defindex": 5035,
|
|
||||||
"paint": "10060",
|
|
||||||
"image": "https://raw.githubusercontent.com/daffyyyy/cs2-WeaponPaints/main/website/img/skins/studded_hydra_gloves-10060.png",
|
|
||||||
"paint_name": "★ Hydra Gloves | Case Hardened"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
1
website/data/gloves_bg.json
Normal file
1
website/data/gloves_bg.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_cs.json
Normal file
1
website/data/gloves_cs.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_da.json
Normal file
1
website/data/gloves_da.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_de.json
Normal file
1
website/data/gloves_de.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_el.json
Normal file
1
website/data/gloves_el.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_en.json
Normal file
1
website/data/gloves_en.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/gloves_es-ES.json
Normal file
1
website/data/gloves_es-ES.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_es-MX.json
Normal file
1
website/data/gloves_es-MX.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_fi.json
Normal file
1
website/data/gloves_fi.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_fr.json
Normal file
1
website/data/gloves_fr.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_hu.json
Normal file
1
website/data/gloves_hu.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_it.json
Normal file
1
website/data/gloves_it.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_ja.json
Normal file
1
website/data/gloves_ja.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_ko.json
Normal file
1
website/data/gloves_ko.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_nl.json
Normal file
1
website/data/gloves_nl.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_no.json
Normal file
1
website/data/gloves_no.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_pl.json
Normal file
1
website/data/gloves_pl.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_pt-BR.json
Normal file
1
website/data/gloves_pt-BR.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_pt-PT.json
Normal file
1
website/data/gloves_pt-PT.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_ro.json
Normal file
1
website/data/gloves_ro.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_ru.json
Normal file
1
website/data/gloves_ru.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_sv.json
Normal file
1
website/data/gloves_sv.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_th.json
Normal file
1
website/data/gloves_th.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_tr.json
Normal file
1
website/data/gloves_tr.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_uk.json
Normal file
1
website/data/gloves_uk.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_vi.json
Normal file
1
website/data/gloves_vi.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_zh-CN.json
Normal file
1
website/data/gloves_zh-CN.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/gloves_zh-TW.json
Normal file
1
website/data/gloves_zh-TW.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"weapon_defindex":0,"paint":0,"image":"","paint_name":"Gloves | Default"}]
|
||||||
1
website/data/music_bg.json
Normal file
1
website/data/music_bg.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_cs.json
Normal file
1
website/data/music_cs.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_da.json
Normal file
1
website/data/music_da.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_de.json
Normal file
1
website/data/music_de.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_el.json
Normal file
1
website/data/music_el.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_en.json
Normal file
1
website/data/music_en.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_es-ES.json
Normal file
1
website/data/music_es-ES.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_es-MX.json
Normal file
1
website/data/music_es-MX.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_fi.json
Normal file
1
website/data/music_fi.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_fr.json
Normal file
1
website/data/music_fr.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_hu.json
Normal file
1
website/data/music_hu.json
Normal file
File diff suppressed because one or more lines are too long
1
website/data/music_it.json
Normal file
1
website/data/music_it.json
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user