├── Dapper.dll
├── TagsApi.dll
├── Tomlyn.dll
├── MySqlConnector.dll
├── .gitignore
├── StoreApi
├── StoreApi.csproj
├── IStoreApi.cs
└── Store.cs
├── Store
├── src
│ ├── item
│ │ ├── items
│ │ │ ├── link.cs
│ │ │ ├── respawn.cs
│ │ │ ├── sound.cs
│ │ │ ├── weapon.cs
│ │ │ ├── gravity.cs
│ │ │ ├── armor.cs
│ │ │ ├── open.cs
│ │ │ ├── bunnyhop.cs
│ │ │ ├── godmode.cs
│ │ │ ├── speed.cs
│ │ │ ├── health.cs
│ │ │ ├── coloredskin.cs
│ │ │ ├── smoke.cs
│ │ │ ├── tracer.cs
│ │ │ ├── grenadetrail.cs
│ │ │ ├── wings.cs
│ │ │ ├── equipment.cs
│ │ │ ├── tags.cs
│ │ │ ├── trail.cs
│ │ │ └── playerskin.cs
│ │ ├── ItemModuleManager.cs
│ │ └── item.cs
│ ├── Extension
│ │ ├── TomlExtensions.cs
│ │ ├── VectorExtensions.cs
│ │ ├── JsonExtensions.cs
│ │ └── PlayerExtensions.cs
│ ├── gamerules
│ │ └── gamerules.cs
│ ├── credits
│ │ └── credits.cs
│ ├── log
│ │ └── log.cs
│ ├── cs2-store.cs
│ ├── menu
│ │ ├── menubase.cs
│ │ └── menu.cs
│ ├── api
│ │ └── api.cs
│ ├── findtarget
│ │ └── findtarget.cs
│ ├── config
│ │ └── config.cs
│ ├── command
│ │ └── command.cs
│ └── event
│ │ └── event.cs
├── cs2-store.csproj
└── lang
│ ├── zh-Hans.json
│ ├── en.json
│ ├── tr.json
│ ├── pl.json
│ ├── pt-BR.json
│ ├── sl.json
│ ├── ua.json
│ ├── ru.json
│ ├── ro.json
│ └── fr.json
├── cs2-store.sln
├── .github
└── workflows
│ └── build.yml
├── config-example.toml
├── README.md
└── cs2-store-example.json
/Dapper.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schwarper/cs2-store/HEAD/Dapper.dll
--------------------------------------------------------------------------------
/TagsApi.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schwarper/cs2-store/HEAD/TagsApi.dll
--------------------------------------------------------------------------------
/Tomlyn.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schwarper/cs2-store/HEAD/Tomlyn.dll
--------------------------------------------------------------------------------
/MySqlConnector.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schwarper/cs2-store/HEAD/MySqlConnector.dll
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | **/obj
3 | **/bin
4 |
5 | # Ignore everything in BuildOutput directory
6 | BuildOutput/
--------------------------------------------------------------------------------
/StoreApi/StoreApi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | $(ProjectDir)..\BuildOutput\shared\StoreApi\
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Store/src/item/items/link.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using static StoreApi.Store;
4 |
5 | namespace Store;
6 |
7 | [StoreItemType("link")]
8 | public class Item_Link : IItemModule
9 | {
10 | public bool Equipable => false;
11 | public bool? RequiresAlive => null;
12 |
13 | public void OnPluginStart() { }
14 |
15 | public void OnMapStart() { }
16 |
17 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
18 |
19 | public bool OnEquip(CCSPlayerController player, Dictionary item)
20 | {
21 | player.ExecuteClientCommandFromServer(item["link"]);
22 | return true;
23 | }
24 |
25 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
26 | {
27 | return true;
28 | }
29 | }
--------------------------------------------------------------------------------
/Store/src/item/items/respawn.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using static StoreApi.Store;
4 |
5 | namespace Store;
6 |
7 | [StoreItemType("respawn")]
8 | public class Item_Respawn : IItemModule
9 | {
10 | public bool Equipable => false;
11 | public bool? RequiresAlive => false;
12 |
13 | public void OnPluginStart() { }
14 |
15 | public void OnMapStart() { }
16 |
17 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
18 |
19 | public bool OnEquip(CCSPlayerController player, Dictionary item)
20 | {
21 | if (player.Team is not (CsTeam.Terrorist or CsTeam.CounterTerrorist))
22 | return false;
23 |
24 | player.Respawn();
25 | return true;
26 | }
27 |
28 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
29 | {
30 | return true;
31 | }
32 | }
--------------------------------------------------------------------------------
/Store/src/item/items/sound.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API;
2 | using CounterStrikeSharp.API.Core;
3 | using CounterStrikeSharp.API.Modules.Utils;
4 | using static StoreApi.Store;
5 |
6 | namespace Store;
7 |
8 | [StoreItemType("sound")]
9 | public class Item_Sound : IItemModule
10 | {
11 | public bool Equipable => false;
12 | public bool? RequiresAlive => null;
13 |
14 | public void OnPluginStart() { }
15 |
16 | public void OnMapStart() { }
17 |
18 | public void OnServerPrecacheResources(ResourceManifest manifest)
19 | {
20 | Item.GetItemsByType("sound").ForEach(item => manifest.AddResource(item.Value["sound"]));
21 | }
22 |
23 | public bool OnEquip(CCSPlayerController player, Dictionary item)
24 | {
25 | Utilities.GetPlayers()
26 | .Where(target => target != null && target.IsValid)
27 | .ToList()
28 | .ForEach(target => target.ExecuteClientCommand($"play {item["sound"]}"));
29 |
30 | return true;
31 | }
32 |
33 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
34 | {
35 | return true;
36 | }
37 | }
--------------------------------------------------------------------------------
/Store/src/item/items/weapon.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Store.Extension;
4 | using static StoreApi.Store;
5 |
6 | namespace Store;
7 |
8 | [StoreItemType("weapon")]
9 | public class Item_Weapon : IItemModule
10 | {
11 | public bool Equipable => false;
12 | public bool? RequiresAlive => true;
13 |
14 | public void OnPluginStart() { }
15 |
16 | public void OnMapStart() { }
17 |
18 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
19 |
20 | public bool OnEquip(CCSPlayerController player, Dictionary item)
21 | {
22 | if (item.TryGetValue("no_pistol_round", out string? nopistolround) && nopistolround == "true" && GameRules.IsPistolRound())
23 | {
24 | player.PrintToChatMessage("No in pistol round", Item.GetItemName(player, item));
25 | return false;
26 | }
27 |
28 | player.GiveNamedItem(item["weapon"]);
29 | return true;
30 | }
31 |
32 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
33 | {
34 | return true;
35 | }
36 | }
--------------------------------------------------------------------------------
/Store/src/item/items/gravity.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using System.Globalization;
4 | using static StoreApi.Store;
5 |
6 | namespace Store;
7 |
8 | [StoreItemType("gravity")]
9 | public class Item_Gravity : IItemModule
10 | {
11 | public bool Equipable => false;
12 | public bool? RequiresAlive => true;
13 |
14 | public void OnPluginStart() { }
15 |
16 | public void OnMapStart() { }
17 |
18 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
19 |
20 | public bool OnEquip(CCSPlayerController player, Dictionary item)
21 | {
22 | if (!float.TryParse(item["gravityValue"], CultureInfo.InvariantCulture, out float gravityValue))
23 | {
24 | return false;
25 | }
26 |
27 | if (player.PlayerPawn?.Value is not { } playerPawn) return false;
28 |
29 | playerPawn.GravityScale = gravityValue;
30 | return true;
31 | }
32 |
33 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
34 | {
35 | if (player.PlayerPawn?.Value is { } playerPawn)
36 | {
37 | playerPawn.GravityScale = 1.0f;
38 | }
39 | return true;
40 | }
41 | }
--------------------------------------------------------------------------------
/Store/src/item/items/armor.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Store.Extension;
4 | using static Store.Config_Config;
5 | using static StoreApi.Store;
6 |
7 | namespace Store;
8 |
9 | [StoreItemType("armor")]
10 | public class Item_Armor : IItemModule
11 | {
12 | public bool Equipable => false;
13 | public bool? RequiresAlive => true;
14 |
15 | public void OnPluginStart() { }
16 |
17 | public void OnMapStart() { }
18 |
19 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
20 |
21 | public bool OnEquip(CCSPlayerController player, Dictionary item)
22 | {
23 | if (!int.TryParse(item["armorValue"], out int armor))
24 | return false;
25 |
26 | if (player.PlayerPawn?.Value is not { } playerPawn)
27 | return false;
28 |
29 | int maxArmor = Config.Settings.MaxArmor;
30 | if (maxArmor > 0 && playerPawn.ArmorValue >= maxArmor)
31 | return false;
32 |
33 | playerPawn.GiveArmor(Math.Min(armor, maxArmor - playerPawn.ArmorValue));
34 | return true;
35 | }
36 |
37 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
38 | {
39 | return true;
40 | }
41 | }
--------------------------------------------------------------------------------
/Store/src/Extension/TomlExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Tomlyn.Model;
3 |
4 | namespace Store.Extension;
5 |
6 | public static class TomlExtensions
7 | {
8 | public static T? GetSection(this TomlTable model, string sectionName) where T : new()
9 | {
10 | if (!model.TryGetValue(sectionName, out object? sectionObj) || sectionObj is not TomlTable section)
11 | return default;
12 |
13 | return MapTomlTableToObject(section);
14 | }
15 |
16 | public static T MapTomlTableToObject(this TomlTable table) where T : new()
17 | {
18 | T obj = new();
19 | PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
20 |
21 | foreach (PropertyInfo prop in props)
22 | {
23 | if (!prop.CanWrite || !table.TryGetValue(prop.Name, out object? value))
24 | continue;
25 |
26 | try
27 | {
28 | if (prop.PropertyType == typeof(List) && value is TomlArray array)
29 | prop.SetValue(obj, array.OfType().ToList());
30 | else
31 | prop.SetValue(obj, Convert.ChangeType(value, prop.PropertyType));
32 | }
33 | catch
34 | { }
35 | }
36 |
37 | return obj;
38 | }
39 | }
--------------------------------------------------------------------------------
/Store/src/Extension/VectorExtensions.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 |
4 | namespace Store.Extension;
5 |
6 | public static class VectorExtensions
7 | {
8 | public static Vector GetEyePosition(CCSPlayerController player)
9 | {
10 | if (player.PlayerPawn?.Value is not { } pawn || pawn.CameraServices == null)
11 | {
12 | throw new ArgumentException("Player pawn or camera services are not valid.");
13 | }
14 |
15 | Vector absOrigin = pawn.AbsOrigin!;
16 | float viewOffsetZ = pawn.CameraServices.OldPlayerViewOffsetZ;
17 |
18 | return new Vector(absOrigin.X, absOrigin.Y, absOrigin.Z + viewOffsetZ);
19 | }
20 |
21 | public static float CalculateDistance(Vector vector1, Vector vector2)
22 | {
23 | float dx = vector2.X - vector1.X;
24 | float dy = vector2.Y - vector1.Y;
25 | float dz = vector2.Z - vector1.Z;
26 |
27 | return MathF.Sqrt((dx * dx) + (dy * dy) + (dz * dz));
28 | }
29 |
30 | public static void Copy(Vector source, Vector destination)
31 | {
32 | destination.X = source.X;
33 | destination.Y = source.Y;
34 | destination.Z = source.Z;
35 | }
36 |
37 | public static bool IsZero(Vector vector)
38 | {
39 | return vector.LengthSqr() == 0;
40 | }
41 | }
--------------------------------------------------------------------------------
/Store/src/item/ItemModuleManager.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using static StoreApi.Store;
3 |
4 | namespace Store;
5 |
6 | public static class ItemModuleManager
7 | {
8 | public static readonly Dictionary Modules = [];
9 |
10 | public static void RegisterModules(Assembly assembly)
11 | {
12 | foreach (Type type in assembly.GetTypes().Where(t => t is { IsClass: true, IsAbstract: false } && typeof(IItemModule).IsAssignableFrom(t)))
13 | {
14 | if (Activator.CreateInstance(type) is not IItemModule module)
15 | continue;
16 |
17 | if (type.GetCustomAttribute() is { } attr)
18 | {
19 | LoadModule(attr.Name, module);
20 | }
21 | else if (type.GetCustomAttribute()?.Names is { } attrs)
22 | {
23 | foreach (string attrName in attrs)
24 | {
25 | LoadModule(attrName, module);
26 | }
27 | }
28 | }
29 | }
30 |
31 | private static void LoadModule(string name, IItemModule module)
32 | {
33 | Modules[name] = module;
34 | Console.WriteLine($"[CS2-Store] Module '{name}' has been added.");
35 | module.OnPluginStart();
36 | }
37 | }
--------------------------------------------------------------------------------
/Store/src/item/items/open.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API;
2 | using CounterStrikeSharp.API.Core;
3 | using CounterStrikeSharp.API.Modules.Utils;
4 | using static StoreApi.Store;
5 |
6 | namespace Store;
7 |
8 | [StoreItemType("open")]
9 | public class Item_Open : IItemModule
10 | {
11 | private static readonly string[] DoorNames =
12 | [
13 | "func_door",
14 | "func_movelinear",
15 | "func_door_rotating",
16 | "prop_door_rotating"
17 | ];
18 |
19 | public bool Equipable => false;
20 | public bool? RequiresAlive => null;
21 |
22 | public void OnPluginStart() { }
23 |
24 | public void OnMapStart() { }
25 |
26 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
27 |
28 | public bool OnEquip(CCSPlayerController player, Dictionary item)
29 | {
30 | foreach (string doorName in DoorNames)
31 | {
32 | IEnumerable doors = Utilities.FindAllEntitiesByDesignerName(doorName);
33 | foreach (CBaseEntity door in doors)
34 | {
35 | door.AcceptInput("Open");
36 | }
37 | }
38 |
39 | return true;
40 | }
41 |
42 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
43 | {
44 | return true;
45 | }
46 | }
--------------------------------------------------------------------------------
/Store/src/item/items/bunnyhop.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Store.Extension;
4 | using static Store.Store;
5 | using static StoreApi.Store;
6 |
7 | namespace Store;
8 |
9 | [StoreItemType("bunnyhop")]
10 | public class Item_Bunnyhop : IItemModule
11 | {
12 | public bool Equipable => true;
13 | public bool? RequiresAlive => null;
14 |
15 | private static bool _bunnyhopExists = false;
16 |
17 | public void OnPluginStart()
18 | {
19 | _bunnyhopExists = Item.IsAnyItemExistInType("bunnyhop");
20 | }
21 |
22 | public void OnMapStart() { }
23 |
24 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
25 |
26 | public bool OnEquip(CCSPlayerController player, Dictionary item)
27 | {
28 | return true;
29 | }
30 |
31 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
32 | {
33 | return true;
34 | }
35 |
36 | public static void OnTick(CCSPlayerController player)
37 | {
38 | if (!_bunnyhopExists) return;
39 |
40 | Store_Equipment? playerBunnyhop = Instance.GlobalStorePlayerEquipments.FirstOrDefault(p => p.SteamID == player.SteamID && p.Type == "bunnyhop");
41 | if (playerBunnyhop == null) return;
42 |
43 | if (player.PlayerPawn?.Value is not { } playerPawn) return;
44 |
45 | playerPawn.BunnyHop(player);
46 | }
47 | }
--------------------------------------------------------------------------------
/Store/src/item/items/godmode.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Store.Extension;
4 | using System.Globalization;
5 | using static Store.Store;
6 | using static StoreApi.Store;
7 |
8 | namespace Store;
9 |
10 | [StoreItemType("godmode")]
11 | public class Item_Godmode : IItemModule
12 | {
13 | public bool Equipable => false;
14 | public bool? RequiresAlive => true;
15 |
16 | public void OnPluginStart() { }
17 |
18 | public void OnMapStart() { }
19 |
20 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
21 |
22 | public bool OnEquip(CCSPlayerController player, Dictionary item)
23 | {
24 | if (!float.TryParse(item["godmodeTimerValue"], CultureInfo.InvariantCulture, out float godmodeTimerValue))
25 | {
26 | return false;
27 | }
28 |
29 | if (player.PlayerPawn?.Value is not { } playerPawn) return false;
30 |
31 | if (godmodeTimerValue > 0.0f)
32 | {
33 | Instance.AddTimer(godmodeTimerValue, () =>
34 | {
35 | playerPawn.TakesDamage = true;
36 | player.PrintToChatMessage("Godmode expired");
37 | });
38 | }
39 |
40 | playerPawn.TakesDamage = false;
41 | return true;
42 | }
43 |
44 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
45 | {
46 | return true;
47 | }
48 | }
--------------------------------------------------------------------------------
/Store/src/gamerules/gamerules.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API;
2 | using CounterStrikeSharp.API.Core;
3 | using CounterStrikeSharp.API.Modules.Cvars;
4 | using static Store.Config_Config;
5 |
6 | namespace Store;
7 |
8 | public static class GameRules
9 | {
10 | private static CCSGameRulesProxy? _gameRulesProxy;
11 | private static readonly ConVar _mpHalftime = ConVar.Find("mp_halftime")!;
12 | private static readonly ConVar _mpMaxrounds = ConVar.Find("mp_maxrounds")!;
13 |
14 | public static bool IgnoreWarmUp()
15 | {
16 | if (_gameRulesProxy?.IsValid != true)
17 | {
18 | _gameRulesProxy = Utilities.FindAllEntitiesByDesignerName("cs_gamerules").FirstOrDefault();
19 | }
20 |
21 | return Config.Credits["default"].IgnoreWarmup && (_gameRulesProxy?.GameRules?.WarmupPeriod ?? false);
22 | }
23 |
24 | public static bool IsPistolRound()
25 | {
26 | if (_gameRulesProxy?.IsValid != true)
27 | {
28 | _gameRulesProxy = Utilities.FindAllEntitiesByDesignerName("cs_gamerules").FirstOrDefault();
29 | }
30 |
31 | bool isHalftime = _mpHalftime.GetPrimitiveValue();
32 | int maxRounds = _mpMaxrounds.GetPrimitiveValue();
33 |
34 | return _gameRulesProxy?.GameRules?.TotalRoundsPlayed == 0 ||
35 | (isHalftime && maxRounds / 2 == _gameRulesProxy?.GameRules?.TotalRoundsPlayed) ||
36 | (_gameRulesProxy?.GameRules?.GameRestart ?? false);
37 | }
38 | }
--------------------------------------------------------------------------------
/Store/src/item/items/speed.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Store.Extension;
4 | using System.Globalization;
5 | using static Store.Store;
6 | using static StoreApi.Store;
7 |
8 | namespace Store;
9 |
10 | [StoreItemType("speed")]
11 | public class Item_Speed : IItemModule
12 | {
13 | public bool Equipable => false;
14 | public bool? RequiresAlive => true;
15 |
16 | public void OnPluginStart() { }
17 |
18 | public void OnMapStart() { }
19 |
20 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
21 |
22 | public bool OnEquip(CCSPlayerController player, Dictionary item)
23 | {
24 | if (!float.TryParse(item["speedValue"], CultureInfo.InvariantCulture, out float speed) ||
25 | !float.TryParse(item["speedTimerValue"], CultureInfo.InvariantCulture, out float speedtimer))
26 | return false;
27 |
28 | CCSPlayerPawn? playerPawn = player.PlayerPawn.Value;
29 | if (playerPawn == null)
30 | return false;
31 |
32 | playerPawn.VelocityModifier = speed;
33 |
34 | if (speedtimer > 0.0)
35 | {
36 | Instance.AddTimer(speedtimer, () =>
37 | {
38 | playerPawn.VelocityModifier = 1.0f;
39 | player.PrintToChatMessage("Speed expired");
40 | });
41 | }
42 |
43 | return true;
44 | }
45 |
46 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
47 | {
48 | return true;
49 | }
50 | }
--------------------------------------------------------------------------------
/Store/src/credits/credits.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using static Store.Store;
3 | using static StoreApi.Store;
4 |
5 | namespace Store;
6 |
7 | public static class Credits
8 | {
9 | public static Store_Player? GetStorePlayer(CCSPlayerController player)
10 | {
11 | return Instance.GlobalStorePlayers.FirstOrDefault(p => p.SteamID == player.SteamID);
12 | }
13 |
14 | public static int Get(CCSPlayerController player)
15 | {
16 | return GetStorePlayer(player)?.Credits ?? -1;
17 | }
18 |
19 | public static int GetOriginal(CCSPlayerController player)
20 | {
21 | return GetStorePlayer(player)?.OriginalCredits ?? -1;
22 | }
23 |
24 | public static int SetOriginal(CCSPlayerController player, int credits)
25 | {
26 | Store_Player? storePlayer = GetStorePlayer(player);
27 | if (storePlayer == null) return -1;
28 |
29 | storePlayer.OriginalCredits = credits;
30 | return storePlayer.OriginalCredits;
31 | }
32 |
33 | public static int Set(CCSPlayerController player, int credits)
34 | {
35 | Store_Player? storePlayer = GetStorePlayer(player);
36 | if (storePlayer == null) return -1;
37 |
38 | storePlayer.Credits = credits;
39 | return storePlayer.Credits;
40 | }
41 |
42 | public static int Give(CCSPlayerController player, int credits)
43 | {
44 | Store_Player? storePlayer = GetStorePlayer(player);
45 | if (storePlayer == null) return -1;
46 |
47 | storePlayer.Credits = Math.Max(storePlayer.Credits + credits, 0);
48 | return storePlayer.Credits;
49 | }
50 | }
--------------------------------------------------------------------------------
/cs2-store.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.10.35013.160
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cs2-store", "Store\cs2-store.csproj", "{6E4C86F8-8E8E-4E22-9815-339EED9BCC7E}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StoreApi", "StoreApi\StoreApi.csproj", "{3FB0AFB3-316A-4D08-9CB3-63CFD720AC3D}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {6E4C86F8-8E8E-4E22-9815-339EED9BCC7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {6E4C86F8-8E8E-4E22-9815-339EED9BCC7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {6E4C86F8-8E8E-4E22-9815-339EED9BCC7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {6E4C86F8-8E8E-4E22-9815-339EED9BCC7E}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {3FB0AFB3-316A-4D08-9CB3-63CFD720AC3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {3FB0AFB3-316A-4D08-9CB3-63CFD720AC3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {3FB0AFB3-316A-4D08-9CB3-63CFD720AC3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {3FB0AFB3-316A-4D08-9CB3-63CFD720AC3D}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {A9FC1EA6-0A7A-4B04-B5A3-0FB63C74290A}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/Store/src/item/items/health.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Store.Extension;
4 | using static Store.Config_Config;
5 | using static StoreApi.Store;
6 |
7 | namespace Store;
8 |
9 | [StoreItemType("health")]
10 | public class Item_Health : IItemModule
11 | {
12 | public bool Equipable => false;
13 | public bool? RequiresAlive => true;
14 |
15 | public void OnPluginStart() { }
16 |
17 | public void OnMapStart() { }
18 |
19 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
20 |
21 | public bool OnEquip(CCSPlayerController player, Dictionary item)
22 | {
23 | if (!int.TryParse(item["healthValue"], out int healthValue))
24 | return false;
25 |
26 | if (player.PlayerPawn?.Value is not { } playerPawn)
27 | return false;
28 |
29 | int currentHealth = playerPawn.GetHealth();
30 | int maxHealth = Config.Settings.MaxHealth;
31 | int pawnMaxHealth = playerPawn.MaxHealth;
32 |
33 | if (maxHealth > 0 && currentHealth >= maxHealth)
34 | return false;
35 | else if (maxHealth == -1 && currentHealth >= pawnMaxHealth)
36 | return false;
37 |
38 | int newHealth = currentHealth + healthValue;
39 |
40 | if (maxHealth > 0)
41 | {
42 | newHealth = Math.Min(newHealth, maxHealth);
43 | }
44 | else if (maxHealth == -1)
45 | {
46 | newHealth = Math.Min(newHealth, pawnMaxHealth);
47 | }
48 |
49 | player.SetHealth(newHealth);
50 | return true;
51 | }
52 |
53 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
54 | {
55 | return true;
56 | }
57 | }
--------------------------------------------------------------------------------
/Store/src/Extension/JsonExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 |
3 | namespace Store.Extension;
4 |
5 | public static class JsonExtensions
6 | {
7 | public static bool IsValueKindObject(this JsonValueKind valueKind)
8 | {
9 | return valueKind == JsonValueKind.Object;
10 | }
11 |
12 | public static List GetElementJsonProperty(this JsonElement element, List ignorePropNameList)
13 | {
14 | return [.. element.EnumerateObject().Where(prop => !ignorePropNameList.Contains(prop.Name))];
15 | }
16 |
17 | public static Dictionary> ExtractItems(this JsonElement category)
18 | {
19 | Dictionary> itemsDictionary = [];
20 |
21 | foreach (JsonProperty subItem in category.EnumerateObject())
22 | {
23 | if (subItem.Value.ValueKind == JsonValueKind.Object)
24 | {
25 | if (subItem.Value.TryGetProperty("uniqueid", out JsonElement uniqueIdElement))
26 | {
27 | string uniqueId = uniqueIdElement.GetString() ?? $"unknown_{subItem.Name}";
28 | Dictionary itemData = subItem.Value.EnumerateObject()
29 | .ToDictionary(prop => prop.Name, prop => prop.Value.ToString());
30 |
31 | itemData["name"] = subItem.Name;
32 | itemsDictionary[uniqueId] = itemData;
33 | }
34 | else
35 | {
36 | Dictionary> nestedItems = ExtractItems(subItem.Value);
37 | foreach (KeyValuePair> nestedItem in nestedItems)
38 | {
39 | itemsDictionary[nestedItem.Key] = nestedItem.Value;
40 | }
41 | }
42 | }
43 | }
44 |
45 | return itemsDictionary;
46 | }
47 | }
--------------------------------------------------------------------------------
/Store/cs2-store.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | true
8 | $(ProjectDir)..\BuildOutput\plugins\cs2-store\
9 | false
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ..\TagsApi.dll
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/StoreApi/IStoreApi.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Core.Capabilities;
3 | using System.Reflection;
4 | using static StoreApi.Store;
5 |
6 | namespace StoreApi;
7 |
8 | public interface IStoreApi
9 | {
10 | static readonly PluginCapability Capability = new("cs2-store:api");
11 |
12 | event Action>? OnPlayerPurchaseItem;
13 | event Action>? OnPlayerEquipItem;
14 | event Action>? OnPlayerUnequipItem;
15 | event Action>? OnPlayerSellItem;
16 |
17 | string GetDatabaseString();
18 | int GetPlayerCredits(CCSPlayerController player);
19 | int SetPlayerCredits(CCSPlayerController player, int credits);
20 | int GetPlayerOriginalCredits(CCSPlayerController player);
21 | int SetPlayerOriginalCredits(CCSPlayerController player, int credits);
22 | int GivePlayerCredits(CCSPlayerController player, int credits);
23 | bool Item_Give(CCSPlayerController player, Dictionary item);
24 | bool Item_Purchase(CCSPlayerController player, Dictionary item);
25 | bool Item_Equip(CCSPlayerController player, Dictionary item);
26 | bool Item_Unequip(CCSPlayerController player, Dictionary item, bool update);
27 | bool Item_Sell(CCSPlayerController player, Dictionary item);
28 | bool Item_PlayerHas(CCSPlayerController player, string type, string uniqueId, bool ignoreVip);
29 | bool Item_PlayerUsing(CCSPlayerController player, string type, string uniqueId);
30 | bool Item_IsInJson(string uniqueId);
31 | bool IsPlayerVip(CCSPlayerController player);
32 | Dictionary? GetItem(string uniqueId);
33 | List>> GetItemsByType(string type);
34 | List GetPlayerItems(CCSPlayerController player, string? type);
35 | List GetPlayerEquipments(CCSPlayerController player, string? type);
36 | void RegisterModules(Assembly assembly);
37 | }
--------------------------------------------------------------------------------
/Store/src/item/items/coloredskin.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Store.Extension;
4 | using System.Drawing;
5 | using static Store.Store;
6 | using static StoreApi.Store;
7 |
8 | namespace Store;
9 |
10 | [StoreItemType("coloredskin")]
11 | public class Item_ColoredSkin : IItemModule
12 | {
13 | public bool Equipable => true;
14 | public bool? RequiresAlive => null;
15 |
16 | private static bool _coloredSkinExists = false;
17 |
18 | public void OnPluginStart()
19 | {
20 | _coloredSkinExists = Item.IsAnyItemExistInType("coloredskin");
21 | }
22 |
23 | public void OnMapStart() { }
24 |
25 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
26 |
27 | public bool OnEquip(CCSPlayerController player, Dictionary item)
28 | {
29 | return true;
30 | }
31 |
32 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
33 | {
34 | player.PlayerPawn.Value?.ColorSkin(Color.White);
35 | return true;
36 | }
37 |
38 | public static void OnTick(CCSPlayerController player)
39 | {
40 | if (!_coloredSkinExists) return;
41 |
42 | Store_Equipment? playerColoredSkin = Instance.GlobalStorePlayerEquipments.FirstOrDefault(p => p.SteamID == player.SteamID && p.Type == "coloredskin");
43 | if (playerColoredSkin == null) return;
44 |
45 | Dictionary? itemData = Item.GetItem(playerColoredSkin.UniqueId);
46 | if (itemData == null) return;
47 |
48 | Color color;
49 |
50 | if (itemData.TryGetValue("color", out string? scolor) && !string.IsNullOrEmpty(scolor))
51 | {
52 | string[] colorValues = scolor.Split(' ');
53 | color = Color.FromArgb(int.Parse(colorValues[0]), int.Parse(colorValues[1]), int.Parse(colorValues[2]));
54 | }
55 | else
56 | {
57 | Array knownColors = Enum.GetValues(typeof(KnownColor));
58 | KnownColor? randomColorName = (KnownColor?)knownColors.GetValue(Instance.Random.Next(knownColors.Length));
59 |
60 | if (!randomColorName.HasValue) return;
61 |
62 | color = Color.FromKnownColor(randomColorName.Value);
63 | }
64 |
65 | player.PlayerPawn.Value?.ColorSkin(color);
66 | }
67 | }
--------------------------------------------------------------------------------
/Store/src/item/items/smoke.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API;
2 | using CounterStrikeSharp.API.Core;
3 | using CounterStrikeSharp.API.Modules.Utils;
4 | using System.Globalization;
5 | using static Store.Store;
6 | using static StoreApi.Store;
7 |
8 | namespace Store;
9 |
10 | [StoreItemType("smoke")]
11 | public class Item_Smoke : IItemModule
12 | {
13 | private static bool smokeExists = false;
14 |
15 | public bool Equipable => true;
16 | public bool? RequiresAlive => null;
17 |
18 | public void OnPluginStart()
19 | {
20 | smokeExists = Item.IsAnyItemExistInType("smoke");
21 | }
22 |
23 | public void OnMapStart() { }
24 |
25 | public void OnServerPrecacheResources(ResourceManifest manifest) { }
26 |
27 | public bool OnEquip(CCSPlayerController player, Dictionary item)
28 | {
29 | return true;
30 | }
31 |
32 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
33 | {
34 | return true;
35 | }
36 |
37 | public static void OnEntityCreated(CEntityInstance entity)
38 | {
39 | if (!smokeExists || entity.DesignerName != "smokegrenade_projectile")
40 | return;
41 |
42 | CSmokeGrenadeProjectile grenade = new(entity.Handle);
43 | if (grenade.Handle == IntPtr.Zero)
44 | return;
45 |
46 | Server.NextFrame(() =>
47 | {
48 | CBasePlayerController? player = grenade.Thrower.Value?.Controller.Value;
49 | if (player == null)
50 | return;
51 |
52 | Store_Equipment? item = Instance.GlobalStorePlayerEquipments.FirstOrDefault(p => p.SteamID == player.SteamID && p.Type == "smoke");
53 | if (item == null)
54 | return;
55 |
56 | if (item.UniqueId == "colorsmoke")
57 | {
58 | grenade.SmokeColor.X = Instance.Random.NextSingle() * 255.0f;
59 | grenade.SmokeColor.Y = Instance.Random.NextSingle() * 255.0f;
60 | grenade.SmokeColor.Z = Instance.Random.NextSingle() * 255.0f;
61 | }
62 | else
63 | {
64 | Dictionary? itemdata = Item.GetItem(item.UniqueId);
65 | if (itemdata == null)
66 | return;
67 |
68 | string[] colorValues = itemdata["color"].Split(' ');
69 | grenade.SmokeColor.X = float.Parse(colorValues[0], CultureInfo.InvariantCulture);
70 | grenade.SmokeColor.Y = float.Parse(colorValues[1], CultureInfo.InvariantCulture);
71 | grenade.SmokeColor.Z = float.Parse(colorValues[2], CultureInfo.InvariantCulture);
72 | }
73 | });
74 | }
75 | }
--------------------------------------------------------------------------------
/StoreApi/Store.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Modules.Utils;
3 | using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
4 |
5 | namespace StoreApi;
6 |
7 | public abstract class Store
8 | {
9 | public class Store_Player
10 | {
11 | public required ulong SteamID { get; set; }
12 | public required string PlayerName { get; set; }
13 | public int Credits { get; set; }
14 | public int OriginalCredits { get; set; }
15 | public DateTime DateOfJoin { get; set; }
16 | public DateTime DateOfLastJoin { get; set; }
17 | public bool? bPlayerIsLoaded;
18 | }
19 |
20 | public class Store_Item
21 | {
22 | public required ulong SteamID { get; set; }
23 | public int Price { get; set; }
24 | public required string Type { get; set; }
25 | public required string UniqueId { get; set; }
26 | public DateTime DateOfPurchase { get; set; }
27 | public DateTime DateOfExpiration { get; set; }
28 | }
29 |
30 | public class Store_Equipment
31 | {
32 | public required ulong SteamID { get; set; }
33 | public required string Type { get; set; }
34 | public required string UniqueId { get; set; }
35 | public int Slot { get; set; }
36 | }
37 |
38 | public class Store_Item_Types
39 | {
40 | public required string Type;
41 | public required Action MapStart;
42 | public required Action ServerPrecacheResources;
43 | public required Func, bool> Equip;
44 | public required Func, bool, bool> Unequip;
45 | public required bool Equipable;
46 | public bool? Alive;
47 | }
48 | public class PlayerTimer
49 | {
50 | public Timer? CreditIntervalTimer { get; set; }
51 | }
52 |
53 | public interface IItemModule
54 | {
55 | void OnPluginStart();
56 | void OnMapStart();
57 | void OnServerPrecacheResources(ResourceManifest manifest);
58 | bool OnEquip(CCSPlayerController player, Dictionary item);
59 | bool OnUnequip(CCSPlayerController player, Dictionary item, bool update);
60 | bool Equipable { get; }
61 | bool? RequiresAlive { get; }
62 | }
63 |
64 | [AttributeUsage(AttributeTargets.Class)]
65 | public class StoreItemTypeAttribute(string name) : Attribute
66 | {
67 | public string Name { get; } = name;
68 | }
69 |
70 | [AttributeUsage(AttributeTargets.Class)]
71 | public class StoreItemTypesAttribute(string[] name) : Attribute
72 | {
73 | public string[] Names { get; } = name;
74 | }
75 | }
--------------------------------------------------------------------------------
/Store/src/log/log.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using CounterStrikeSharp.API;
3 |
4 | namespace Store;
5 |
6 | public static class Log
7 | {
8 | public enum LogType
9 | {
10 | GiveCredit,
11 | GiftCredit
12 | }
13 |
14 | public class LogEntry
15 | {
16 | public string Date { get; set; } = string.Empty;
17 | public string From { get; set; } = string.Empty;
18 | public string FromId { get; set; } = string.Empty;
19 | public string To { get; set; } = string.Empty;
20 | public string ToId { get; set; } = string.Empty;
21 | public int CreditsGiven { get; set; }
22 | }
23 |
24 | private static readonly JsonSerializerOptions JsonOptions = new()
25 | {
26 | WriteIndented = true,
27 | Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
28 | };
29 |
30 | public static void SaveLog(
31 | string fromName,
32 | string fromSteamId,
33 | string toName,
34 | string toSteamId,
35 | int creditsAmount,
36 | LogType logType)
37 | {
38 | try
39 | {
40 | string logFolder = Path.Combine(
41 | Server.GameDirectory,
42 | "csgo",
43 | "addons",
44 | "counterstrikesharp",
45 | "logs",
46 | "Store"
47 | );
48 |
49 | Directory.CreateDirectory(logFolder);
50 |
51 | string logFile = Path.Combine(
52 | logFolder,
53 | $"{DateTime.Now:dd.MM.yyyy}-{logType.ToString().ToLower()}-log.json"
54 | );
55 |
56 | List logs = LoadLogs(logFile);
57 |
58 | LogEntry logEntry = new()
59 | {
60 | Date = DateTime.Now.ToString("HH:mm:ss"),
61 | From = fromName,
62 | FromId = fromSteamId,
63 | To = toName,
64 | ToId = toSteamId,
65 | CreditsGiven = creditsAmount
66 | };
67 |
68 | logs.Add(logEntry);
69 |
70 | File.WriteAllText(logFile, JsonSerializer.Serialize(logs, JsonOptions));
71 | }
72 | catch (Exception ex)
73 | {
74 | Server.PrintToConsole($"credit log error: {ex.Message}");
75 | }
76 | }
77 |
78 | private static List LoadLogs(string logFile)
79 | {
80 | if (!File.Exists(logFile))
81 | return [];
82 |
83 | try
84 | {
85 | string existing = File.ReadAllText(logFile);
86 | return string.IsNullOrWhiteSpace(existing)
87 | ? []
88 | : JsonSerializer.Deserialize>(existing) ?? [];
89 | }
90 | catch
91 | {
92 | return [];
93 | }
94 | }
95 | }
--------------------------------------------------------------------------------
/Store/src/item/items/tracer.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API;
2 | using CounterStrikeSharp.API.Core;
3 | using CounterStrikeSharp.API.Modules.Utils;
4 | using Store.Extension;
5 | using System.Globalization;
6 | using static Store.Store;
7 | using static StoreApi.Store;
8 |
9 | namespace Store;
10 |
11 | [StoreItemType("tracer")]
12 | public class Item_Tracer : IItemModule
13 | {
14 | public bool Equipable => true;
15 | public bool? RequiresAlive => null;
16 |
17 | public void OnPluginStart()
18 | {
19 | if (Item.IsAnyItemExistInType("tracer"))
20 | Instance.RegisterEventHandler(OnBulletImpact);
21 | }
22 |
23 | public void OnMapStart() { }
24 |
25 | public void OnServerPrecacheResources(ResourceManifest manifest)
26 | {
27 | Item.GetItemsByType("tracer").ForEach(item => manifest.AddResource(item.Value["model"]));
28 | }
29 |
30 | public bool OnEquip(CCSPlayerController player, Dictionary item)
31 | {
32 | return true;
33 | }
34 |
35 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
36 | {
37 | return true;
38 | }
39 |
40 | private static HookResult OnBulletImpact(EventBulletImpact @event, GameEventInfo info)
41 | {
42 | CCSPlayerController? player = @event.Userid;
43 | if (player == null || !player.IsValid)
44 | return HookResult.Continue;
45 |
46 | Store_Equipment? playertracer = Instance.GlobalStorePlayerEquipments.FirstOrDefault(p => p.SteamID == player.SteamID && p.Type == "tracer");
47 | if (playertracer == null)
48 | return HookResult.Continue;
49 |
50 | Dictionary? itemdata = Item.GetItem(playertracer.UniqueId);
51 | if (itemdata == null)
52 | return HookResult.Continue;
53 |
54 | CBeam? entity = Utilities.CreateEntityByName("beam");
55 | if (entity == null || !entity.IsValid)
56 | return HookResult.Continue;
57 |
58 | string acceptinputvalue = itemdata.GetValueOrDefault("acceptInputValue", "Start");
59 | entity.SetModel(itemdata["model"]);
60 | entity.DispatchSpawn();
61 | entity.AcceptInput(acceptinputvalue);
62 |
63 | Vector position = VectorExtensions.GetEyePosition(player);
64 | entity.Teleport(position, new QAngle(), new Vector());
65 |
66 | entity.EndPos.X = @event.X;
67 | entity.EndPos.Y = @event.Y;
68 | entity.EndPos.Z = @event.Z;
69 | Utilities.SetStateChanged(entity, "CBeam", "m_vecEndPos");
70 |
71 | float lifetime = itemdata.TryGetValue("lifetime", out string? value) && float.TryParse(value, CultureInfo.InvariantCulture, out float lt) ? lt : 0.3f;
72 |
73 | Instance.AddTimer(lifetime, () =>
74 | {
75 | if (entity.IsValid)
76 | entity.Remove();
77 | });
78 |
79 | return HookResult.Continue;
80 | }
81 | }
--------------------------------------------------------------------------------
/Store/src/cs2-store.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API;
2 | using CounterStrikeSharp.API.Core;
3 | using CounterStrikeSharp.API.Core.Capabilities;
4 | using CS2MenuManager.API.Class;
5 | using Store.Extension;
6 | using StoreApi;
7 | using System.Reflection;
8 | using System.Text.Json;
9 | using static StoreApi.Store;
10 |
11 | namespace Store;
12 |
13 | public class Store : BasePlugin, IPluginConfig
14 | {
15 | public override string ModuleName => "Store";
16 | public override string ModuleVersion => "v24";
17 | public override string ModuleAuthor => "schwarper";
18 |
19 | public Item_Config Config { get; set; } = new();
20 | public List GlobalStorePlayers { get; set; } = [];
21 | public List GlobalStorePlayerItems { get; set; } = [];
22 | public List GlobalStorePlayerEquipments { get; set; } = [];
23 | public Dictionary GlobalDictionaryPlayer { get; set; } = [];
24 | public int GlobalTickrate { get; set; } = 0;
25 | public static Store Instance { get; set; } = new();
26 | public Random Random { get; set; } = new();
27 | public Dictionary GlobalGiftTimeout { get; set; } = [];
28 | public static StoreAPI Api { get; set; } = new();
29 | public Dictionary> Items { get; set; } = [];
30 | public Dictionary InspectList { get; set; } = [];
31 |
32 | public override void Load(bool hotReload)
33 | {
34 | Capabilities.RegisterPluginCapability(IStoreApi.Capability, () => Api);
35 | Instance = this;
36 |
37 | Event.Load();
38 | Command.Load();
39 |
40 | if (hotReload)
41 | {
42 | List players = Utilities.GetPlayers();
43 | foreach (CCSPlayerController player in players)
44 | {
45 | if (player.IsBot)
46 | continue;
47 |
48 | Database.LoadPlayer(player);
49 | MenuManager.CloseActiveMenu(player);
50 | }
51 | }
52 | }
53 |
54 | public override void Unload(bool hotReload)
55 | {
56 | Event.Unload();
57 | Item_Tags.OnPluginEnd();
58 |
59 | List players = Utilities.GetPlayers();
60 | foreach (CCSPlayerController player in players)
61 | {
62 | if (player.IsBot)
63 | continue;
64 |
65 | MenuManager.CloseActiveMenu(player);
66 | }
67 | }
68 |
69 | public override void OnAllPluginsLoaded(bool hotReload)
70 | {
71 | ItemModuleManager.RegisterModules(Assembly.GetExecutingAssembly());
72 | }
73 |
74 | public void OnConfigParsed(Item_Config config)
75 | {
76 | Config_Config.Load();
77 |
78 | if (!config.Items.ValueKind.IsValueKindObject())
79 | throw new JsonException();
80 |
81 | Items = config.Items.ExtractItems();
82 | Config = config;
83 | }
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/Store/lang/zh-Hans.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}用户不匹配",
3 | "More than one client matched": "{white}没有匹配的用户",
4 | "Must be an integer": "{white}数量必须为整数",
5 | "Must be higher than zero": "{white}数量不能为0",
6 | "Must be a steamid": "{white}请输入有效的steamid",
7 | "No credits enough": "{white}积分余额不足",
8 | "You are not alive": "{white}死亡状态无法购买",
9 | "You are alive": "{white}只有死亡后才可购买",
10 | "No in pistol round": "{white}手枪局无法购买{green}{0}{white}",
11 | "No gift yourself": "{white}无法给自己赠送积分",
12 | "No type found": "{white}没有找到这个类型,请重新输入. {red}{0}",
13 | "Gift timeout": "{white}你需要等待{green}{0}秒{white}后才能赠送",
14 | "No purchase because team": "{white}您需要加入{red}{0}{white}阵营才能购买此皮肤!",
15 | "No equip because team": "{white}您需要加入{red}{0}{white}阵营才能装备此皮肤!",
16 | "You need correct weapon": "{white}你需要拿着{red}{0}{white}才能检视!",
17 | "Players' credits are refreshed": "{white}玩家积分已刷新!",
18 |
19 | "t team players": "{green}T阵营{white}玩家",
20 | "ct team players": "{green}CT阵营{white}玩家",
21 | "alive players": "{green}存活{white}玩家",
22 | "all players": "{green}所有{white}玩家",
23 | "dead players": "{green}死亡{white}玩家",
24 | "Console": "{white}控制台",
25 |
26 | "Purchase Succeeded": "{white}你购买了{green}{0}{white}",
27 | "Purchase Equip": "{white}你装备了{green}{0}{white}",
28 | "Purchase Unequip": "{white}你取消装备了{green}{0}{white}",
29 | "Item Sell": "{white}你{white}卖掉了{green}{0}{white}",
30 | "Godmode expired": "{white}你的无敌模式已到期",
31 | "Speed expired": "{white}你的加速模式已到期",
32 | "Hidetrails off": "{white}轨迹显示{green}已开启{white}!",
33 | "Hidetrails on": "{white}轨迹显示{red}已关闭{white}!",
34 |
35 | "menu_store": "商店【 积分余额: {0} 】",
36 |
37 | "menu_store": "通用模型",
38 | "menu_store": "T阵营模型",
39 | "menu_store": "CT阵营模型",
40 | "menu_store": "{0} - [{1}]",
41 | "menu_store": "{0}",
42 | "menu_store": "装备",
43 | "menu_store": "取消装备",
44 | "menu_store": "出售 [{0}]",
45 | "menu_store": "确认购买吗?",
46 | "menu_store": "是",
47 | "menu_store": "否",
48 | "menu_store": "{0} - {1} 积分",
49 | "menu_store": "检视",
50 |
51 | "css_credits": "{white}积分余额: {green}{0} {white}",
52 | "css_givecredits": "{blue}{0}{white}给了{green}{2}积分{white}到{green}{1}{white}的账户里",
53 | "css_givecredits": "{blue}{0}{white}给了{green}{2}积分{white}到{green}{1}{white}的账户里",
54 | "css_givecredits": "{blue}{0}{white}给了{green}{2}积分{white}到{green}{1}{white}的账户里",
55 |
56 | "css_gift": "{white}你赠送了{green}{1}{white}积分给{blue}{0}{white}",
57 | "css_gift": "{blue}{0}{white}赠送了{green}{1}{white}积分给你",
58 |
59 | "css_reset": "{blue}{0}{white}重置了{green}{1}{white}的商店数据",
60 |
61 | "credits_earned": "{white}活跃奖励,{gold}积分{white}+{green}{0}{white}",
62 | "credits_earned": "{white}非活跃奖励,{gold}积分{white}+{green}{0}{white}",
63 | "credits_earned": "{white}击杀玩家,{gold}积分{white}+{green}{0}{white}",
64 |
65 | "css_model0": "{blue}{0}{white}开启了强制默认模型",
66 | "css_model1": "{blue}{0}{white}关闭了强制默认模型",
67 |
68 | "FreePlayerSkin": "免费玩家皮肤",
69 | "CT": "反恐精英",
70 | "Fernandez Frogman [CT]": "费尔南德斯蛙人 [CT]"
71 | }
--------------------------------------------------------------------------------
/Store/src/item/items/grenadetrail.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API;
2 | using CounterStrikeSharp.API.Core;
3 | using CounterStrikeSharp.API.Modules.Utils;
4 | using static Store.Store;
5 | using static StoreApi.Store;
6 |
7 | namespace Store;
8 |
9 | [StoreItemType("grenadetrail")]
10 | public class Item_GrenadeTrail : IItemModule
11 | {
12 | public bool Equipable => true;
13 | public bool? RequiresAlive => null;
14 |
15 | public static Dictionary GlobalGrenadeTrail { get; set; } = [];
16 | private static bool _grenadeTrailExists = false;
17 |
18 | public void OnPluginStart()
19 | {
20 | _grenadeTrailExists = Item.IsAnyItemExistInType("grenadetrail");
21 | }
22 |
23 | public void OnMapStart()
24 | {
25 | GlobalGrenadeTrail.Clear();
26 | }
27 |
28 | public void OnServerPrecacheResources(ResourceManifest manifest)
29 | {
30 | List>> items = Item.GetItemsByType("grenadetrail");
31 |
32 | foreach (KeyValuePair> item in items)
33 | {
34 | manifest.AddResource(item.Value["model"]);
35 | }
36 | }
37 |
38 | public bool OnEquip(CCSPlayerController player, Dictionary item)
39 | {
40 | return true;
41 | }
42 |
43 | public bool OnUnequip(CCSPlayerController player, Dictionary item, bool update)
44 | {
45 | return true;
46 | }
47 |
48 | public static void OnEntityCreated(CEntityInstance entity)
49 | {
50 | if (!_grenadeTrailExists || !entity.DesignerName.EndsWith("_projectile")) return;
51 |
52 | CBaseCSGrenadeProjectile grenade = new(entity.Handle);
53 | if (grenade.Handle == IntPtr.Zero) return;
54 |
55 | Server.NextFrame(() =>
56 | {
57 | CBasePlayerController? player = grenade.Thrower.Value?.Controller.Value;
58 | if (player == null) return;
59 |
60 | Store_Equipment? item = Instance.GlobalStorePlayerEquipments.FirstOrDefault(p => p.SteamID == player.SteamID && p.Type == "grenadetrail");
61 | if (item == null) return;
62 |
63 | CParticleSystem? particle = Utilities.CreateEntityByName("info_particle_system");
64 | if (particle == null || !particle.IsValid) return;
65 |
66 | Dictionary? itemData = Item.GetItem(item.UniqueId);
67 | if (itemData == null) return;
68 |
69 | string acceptInputValue = itemData.TryGetValue("acceptInputValue", out string? value) && !string.IsNullOrEmpty(value) ? value : "Start";
70 |
71 | particle.EffectName = itemData["model"];
72 | particle.StartActive = true;
73 | particle.Teleport(grenade.AbsOrigin);
74 | particle.DispatchSpawn();
75 | particle.AcceptInput("FollowEntity", grenade, particle, "!activator");
76 | particle.AcceptInput(acceptInputValue);
77 |
78 | GlobalGrenadeTrail[grenade] = particle;
79 | });
80 | }
81 | }
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build & Publish cs2-store
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | paths-ignore:
8 | - 'README.md'
9 | - '.github/workflows/**'
10 | - 'config-example.toml'
11 | - 'cs2-store-example.json'
12 |
13 | jobs:
14 | setup:
15 | permissions:
16 | contents: write
17 | runs-on: ubuntu-latest
18 | outputs:
19 | buildnumber: ${{ steps.buildnumber.outputs.build_number }}
20 | steps:
21 | - name: Generate build number
22 | id: buildnumber
23 | uses: onyxmueller/build-tag-number@v1
24 | with:
25 | token: ${{ secrets.GITHUB_TOKEN }}
26 |
27 | build:
28 | needs: setup
29 | runs-on: ubuntu-latest
30 | permissions:
31 | contents: write
32 | steps:
33 | - name: Prepare Environment Variables
34 | shell: bash
35 | run: |
36 | echo "GITHUB_SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
37 | echo "BUILD_NUMBER=${{ needs.setup.outputs.buildnumber }}" >> $GITHUB_ENV
38 |
39 | - name: Checkout Repository
40 | uses: actions/checkout@v3
41 |
42 | - name: Setup .NET
43 | uses: actions/setup-dotnet@v3
44 | with:
45 | dotnet-version: '8.0.x'
46 |
47 | - name: Restore Dependencies
48 | run: dotnet restore
49 |
50 | - name: Build
51 | run: |
52 | dotnet build cs2-store.sln -c Release --no-restore /p:Version=${{ env.BUILD_NUMBER }}
53 |
54 | - name: Create Release Artifact (ZIP) from BuildOutput
55 | run: |
56 | mkdir -p release
57 | cd BuildOutput
58 | zip -r ../cs2-store-v${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}.zip * --exclude '*.nupkg' '*.xml'
59 |
60 | - name: Create GitHub Release
61 | id: create_release
62 | uses: actions/create-release@v1
63 | env:
64 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
65 | with:
66 | tag_name: v${{ env.BUILD_NUMBER }}
67 | release_name: v${{ env.BUILD_NUMBER }}
68 | draft: false
69 | prerelease: false
70 | body: |
71 | ## Release Notes for v${{ env.BUILD_NUMBER }}
72 |
73 | ---
74 | ### Changes:
75 | - ${{ github.event.pull_request.title || github.event.head_commit.message }}
76 |
77 | ---
78 | ### Feedback:
79 | If you encounter any issues, please report them [here](https://github.com/${{ github.repository }}/issues).
80 |
81 | ---
82 | ### Support:
83 | If you'd like to support the continued development of this project, you can do so by [buying me a coffee](https://buymeacoffee.com/schwarper). Your support is genuinely appreciated.
84 |
85 | - name: Upload Release Asset
86 | uses: actions/upload-release-asset@v1
87 | env:
88 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89 | with:
90 | upload_url: ${{ steps.create_release.outputs.upload_url }}
91 | asset_path: ./cs2-store-v${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}.zip
92 | asset_name: cs2-store-v${{ env.BUILD_NUMBER }}-${{ env.GITHUB_SHA_SHORT }}.zip
93 | asset_content_type: application/zip
94 |
--------------------------------------------------------------------------------
/Store/src/menu/menubase.cs:
--------------------------------------------------------------------------------
1 | using CounterStrikeSharp.API.Core;
2 | using CounterStrikeSharp.API.Core.Translations;
3 | using CounterStrikeSharp.API.Modules.Admin;
4 | using CS2MenuManager.API.Class;
5 | using CS2MenuManager.API.Enum;
6 | using CS2MenuManager.API.Interface;
7 | using System.Text.Json;
8 | using static Store.Config_Config;
9 | using static Store.Store;
10 | using static StoreApi.Store;
11 |
12 | namespace Store;
13 |
14 | public static class MenuBase
15 | {
16 | public static void DisplayStoreMenu(CCSPlayerController? player, bool inventory)
17 | {
18 | if (player == null)
19 | return;
20 |
21 | Menu.DisplayStore(player, inventory);
22 | }
23 |
24 | public static int GetSellingPrice(Dictionary item, Store_Item playerItem)
25 | {
26 | float sellRatio = Config.Settings.SellRatio;
27 | bool usePurchaseCredit = Config.Settings.SellUsePurchaseCredit;
28 |
29 | int purchasePrice = usePurchaseCredit && playerItem != null ? playerItem.Price : int.Parse(item["price"]);
30 | return (int)(purchasePrice * sellRatio);
31 | }
32 |
33 | public static bool CheckFlag(CCSPlayerController player, Dictionary item, bool sell = false)
34 | {
35 | item.TryGetValue("flag", out string? flag);
36 | return CheckFlag(player, flag, !sell);
37 | }
38 |
39 | public static bool CheckFlag(CCSPlayerController player, string? flagAll, bool trueIfNull)
40 | {
41 | return string.IsNullOrEmpty(flagAll)
42 | ? trueIfNull
43 | : flagAll.Split(',')
44 | .Any(flag => (flag.StartsWith('@') && AdminManager.PlayerHasPermissions(player, flag)) ||
45 | (flag.StartsWith('#') && AdminManager.PlayerInGroup(player, flag)) ||
46 | (flag == player.SteamID.ToString()));
47 | }
48 |
49 | public static string GetCategoryName(CCSPlayerController player, JsonProperty category)
50 | {
51 | return Instance.Localizer.ForPlayer(player, category.Name);
52 | }
53 |
54 | public static void InspectAction(CCSPlayerController player, Dictionary item, string type)
55 | {
56 | switch (type)
57 | {
58 | case "playerskin":
59 | item.TryGetValue("skin", out string? skn);
60 | Item_PlayerSkin.Inspect(player, item["model"], skn);
61 | break;
62 | /*
63 | case "customweapon":
64 | Item_CustomWeapon.Inspect(player, item["viewmodel"], item["weapon"]);
65 | break;
66 | */
67 | }
68 | }
69 |
70 | public static void AddMenuOption(this IMenu menu, CCSPlayerController player, DisableOption disableOption, string display, params object[] args)
71 | {
72 | menu.AddItem(Instance.Localizer.ForPlayer(player, display, args), disableOption);
73 | }
74 |
75 | public static void AddMenuOption(this IMenu menu, CCSPlayerController player, Action callback, string display, params object[] args)
76 | {
77 | menu.AddItem(Instance.Localizer.ForPlayer(player, display, args), callback);
78 | }
79 |
80 | public static void AddMenuOption(this IMenu menu, CCSPlayerController player, Action callback, DisableOption disableOption, string display, params object[] args)
81 | {
82 | menu.AddItem(Instance.Localizer.ForPlayer(player, display, args), callback, disableOption);
83 | }
84 |
85 | public static BaseMenu CreateMenuByType(string title)
86 | {
87 | return MenuManager.MenuByType(Config.Menu.MenuType, title, Instance);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Store/lang/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}There is no matching client",
3 | "More than one client matched": "{white}There are more than one client matched",
4 | "Must be an integer": "{white}The value you entered must be an integer",
5 | "Must be higher than zero": "{white}The value you entered must be higher than zero.",
6 | "Must be a steamid": "{white}The value you entered must be a valid steamid",
7 | "No credits enough": "{white}You do not have enough credits.",
8 | "You are not alive": "{white}You can buy it only when you are alive.",
9 | "You are alive": "{white}You can buy it only when you are dead.",
10 | "No in pistol round": "{white}You cannot buy this item {green}{0} {white} in pistol round.",
11 | "No gift yourself": "{white}You cannot gift credits to yourself.",
12 | "No type found": "{white}No type found. {red}{0}",
13 | "Gift timeout": "{white}You need to wait {green}{0} seconds {white}to gift.",
14 | "No purchase because team": "{white}You cannot purchase this item. You need to be in {red}{0} {white}team.",
15 | "No equip because team": "{white}You cannot equip this item. You need to be in {red}{0} {white}team.",
16 | "You need correct weapon": "{white}You need {red}{0} {white}to inspect.",
17 | "Players' credits are refreshed": "Players' credits are refreshed.",
18 |
19 | "t team players": "{green}t team {white}players",
20 | "ct team players": "{green}ct team {white}players",
21 | "alive players": "{green}alive {white}players",
22 | "all players": "{green}all {white}players",
23 | "dead players": "{green}dead {white}players",
24 | "Console": "Console",
25 |
26 | "Purchase Succeeded": "{white}You {white}bought {green}{0}{white}.",
27 | "Purchase Equip": "{white}You {white}equipped {green}{0}{white}.",
28 | "Purchase Unequip": "{white}You {white}unequipped {green}{0}{white}.",
29 | "Item Sell": "{white}You {white}sold {green}{0}{white}.",
30 | "Godmode expired": "{white}Your godmode time is expired.",
31 | "Speed expired": "{white}Your speed time is expired.",
32 | "Hidetrails off": "{white}You can see trails now.",
33 | "Hidetrails on": "{white}You cannot see trails now.",
34 |
35 | "menu_store": "Store [Your credits: {0}]",
36 |
37 | "menu_store": "Models in common",
38 | "menu_store": "T Models",
39 | "menu_store": "CT Models",
40 | "menu_store": "{0} - [{1}]",
41 | "menu_store": "{0}",
42 | "menu_store": "EQUIP",
43 | "menu_store": "UNEQUIP",
44 | "menu_store": "SELL [{0}]",
45 | "menu_store": "Buying?",
46 | "menu_store": "Yes",
47 | "menu_store": "No",
48 | "menu_store": "{0} - {1} credits",
49 | "menu_store": "Inspect",
50 |
51 | "css_credits": "{white}You have {green}{0} {white}credits.",
52 | "css_givecredits": "{blue}{0} {white}gave {green}{2} credits {white}to {green}{1}{white}.",
53 | "css_givecredits": "{blue}{0} {white}gave {green}{2} credits {white}to {green}{1}{white}.",
54 | "css_givecredits": "{blue}{0} {white}gave {green}{2} credits {white}to {green}{1}{white}.",
55 |
56 | "css_gift": "{white}You have sent {green}{1}{white}credits to {blue}{0}{white}.",
57 | "css_gift": "{blue}{0} {white}sent you {green}{1} {white}credits.",
58 |
59 | "css_reset": "{blue}{0}{white} resetted {green}{1}{white}'s store datas.",
60 |
61 | "credits_earned": "{white}You earned {green}{0} credits {white}for being active on the server.",
62 | "credits_earned": "{white}You earned {green}{0} credits {white}for being inactive on the server.",
63 | "credits_earned": "{white}You earned {green}{0} credits {white}for killing a player.",
64 |
65 | "css_model0": "{blue}{0}{white} turned on the default forcing of player models.",
66 | "css_model1": "{blue}{0}{white} turned off the default forcing of player models.",
67 |
68 | "FreePlayerSkin": "Free Player Skin",
69 | "CT": "CT Skins",
70 | "Fernandez Frogman [CT]": "*Fernandez Frogman [CT]*"
71 | }
--------------------------------------------------------------------------------
/Store/lang/tr.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}Eşleşen alıcı bulunamadı.",
3 | "More than one client matched": "{white}Verilen biçim düzeniyle birden fazla alıcı eşleşti.",
4 | "Must be an integer": "{white}Girdiğiniz değer bir sayı olmalıdır.",
5 | "Must be higher than zero": "{white}Girdiğiniz değer sıfırdan büyük olmalıdır.",
6 | "Must be a steamid": "{white}Girdiğiniz değer steamid olmalıdır.",
7 | "No credits enough": "{white}Yeterli krediniz bulunmamaktadır.",
8 | "You are not alive": "{white}Sadece yaşarken alabilirsiniz.",
9 | "You are alive": "{white}Sadece ölüyken alabilirsiniz.",
10 | "No in pistol round": "{white}Bu ürünü {green}{0} {white}tabanca turunda alamazsınız.",
11 | "No gift yourself": "{white}Kendine kredi hediye edemezsin.",
12 | "No type found": "{white}Böyle bir type bulunamadı. {red}{0}",
13 | "Gift timeout": "{white}Kredi hediye etmek için {green}{0} saniye {white}beklemelisin.",
14 | "No purchase because team": "{white}Bu ürünü satın alamazsınız. {red}{0} {white}takımında olmanız gerekiyor.",
15 | "No equip because team": "{white}Bu ürünü kuşanamazsınız. {red}{0} {white}takımında olmanız gerekiyor.",
16 | "You need correct weapon": "{white}İncelemek için {red}{0} {white}gerekli.",
17 | "Players' credits are refreshed": "Oyuncuların kredileri yenilendi.",
18 |
19 | "t team players": "{green}t takımı {white}oyuncularını",
20 | "ct team players": "{green}ct takımı {white}oyuncularını",
21 | "alive players": "{green}yaşayan {white}oyuncuları",
22 | "all players": "{green}bütün {white}oyuncuları",
23 | "dead players": "{green}ölü {white}oyuncuları",
24 | "Console": "PANEL",
25 |
26 | "Purchase Succeeded": "{green}{0} {white}satın aldın.",
27 | "Purchase Equip": "{green}{0} {white}kuşandın.",
28 | "Purchase Unequip": "{green}{0} {white}bıraktın.",
29 | "Item Sell": "{green}{0} {white}sattın.",
30 | "Godmode expired": "{white}Godmode süreniz bitti.",
31 | "Speed expired": "{white}Hızlı koşma süreniz bitti.",
32 | "Hidetrails off": "{white}Artık izleri görebilirsiniz.",
33 | "Hidetrails on": "{white}Artık izleri göremezsiniz.",
34 |
35 | "menu_store": "Market [Krediniz: {0}]",
36 |
37 | "menu_store": "Ortak Modeller",
38 | "menu_store": "T Modelleri",
39 | "menu_store": "CT Modelleri",
40 | "menu_store": "{0} - [{1}]",
41 | "menu_store": "{0}",
42 | "menu_store": "KUŞAN",
43 | "menu_store": "BIRAK",
44 | "menu_store": "SAT [{0}]",
45 | "menu_store": "Satın alıyor musun?",
46 | "menu_store": "Evet",
47 | "menu_store": "Hayır",
48 | "menu_store": "{0} - {1} kredi",
49 | "menu_store": "İncele",
50 |
51 | "css_credits": "{green}{0} {white}kredin bulunmaktadır.",
52 | "css_givecredits": "{blue}{0}{white}, {green}{1} {white}adlı oyuncuya {green}{2} kredi {white}verdi.",
53 | "css_givecredits": "{blue}{0}{white}, {green}{1} {white}steamidye {green}{2} kredi {white}verdi.",
54 | "css_givecredits": "{blue}{0}{white}, {green}{1} {green}{2} kredi {white}verdi.",
55 |
56 | "css_gift": "{blue}{0}{white} adlı kişiye {green}{1} {white}kredi yolladınız.",
57 | "css_gift": "{blue}{0}{white}, size {green}{1} {white}kredi yolladı.",
58 |
59 | "css_reset": "{blue}{0}{white}, {green}{1} {white}adlı oyuncunun marketini sıfırladı",
60 |
61 | "credits_earned": "{white}Sunucuda aktif vakit geçirdiğiniz için {green}{0} kredi {white}kazandınız.",
62 | "credits_earned": "{white}Sunucuda pasif vakit geçirdiğiniz için {green}{0} kredi {white}kazandınız.",
63 | "credits_earned": "{white}Oyuncu öldürdüğünüz için {green}{0} {white}kredi kazandınız.",
64 |
65 | "css_model0": "{blue}{0}{white}, oyuncu modellerinin varsayılan zorunluluğunu açtı.",
66 | "css_model1": "{blue}{0}{white}, oyuncu modellerinin varsayılan zorunluluğunu kapattı.",
67 |
68 | "FreePlayerSkin": "Ücretsiz Oyuncu Modeli",
69 | "CT": "CT Modelleri",
70 | "Fernandez Frogman [CT]": "Fernandez Frogman [CT]"
71 | }
--------------------------------------------------------------------------------
/Store/lang/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}Nie znaleziono pasującego klienta",
3 | "More than one client matched": "{white}Znaleziono więcej niż jeden pasujący klient",
4 | "Must be an integer": "{white}Wartość, którą wpisałeś, musi być liczbą całkowitą",
5 | "Must be higher than zero": "{white}Wartość, którą wpisałeś, musi być większa od zera.",
6 | "Must be a steamid": "{white}Wartość, którą wpisałeś, musi być prawidłowym steamid",
7 | "No credits enough": "{white}Nie masz wystarczającej liczby kredytów.",
8 | "You are not alive": "{white}Możesz to kupić tylko, gdy jesteś żywy.",
9 | "You are alive": "{white}Możesz to kupić tylko, gdy jesteś martwy.",
10 | "No in pistol round": "{white}Nie możesz kupić tego przedmiotu {green}{0} {white}w rundzie pistoletowej.",
11 | "No gift yourself": "{white}Nie możesz podarować kredytów sobie.",
12 | "No type found": "{white}Nie znaleziono typu. {red}{0}",
13 | "Gift timeout": "{white}Musisz poczekać {green}{0} sekund {white}na możliwość podarowania.",
14 | "No purchase because team": "{white}Nie możesz kupić tego przedmiotu. Musisz być w drużynie {red}{0} {white}.",
15 | "No equip because team": "{white}Nie możesz wyposażyć się w ten przedmiot. Musisz być w drużynie {red}{0} {white}.",
16 | "You need correct weapon": "{white}Potrzebujesz {red}{0} {white}, aby sprawdzić.",
17 | "Players' credits are refreshed": "Kredyty graczy zostały odświeżone.",
18 |
19 | "t team players": "{green}gracze drużyny t {white}",
20 | "ct team players": "{green}gracze drużyny ct {white}",
21 | "alive players": "{green}żywi gracze {white}",
22 | "all players": "{green}wszyscy gracze {white}",
23 | "dead players": "{green}martwi gracze {white}",
24 | "Console": "Konsola",
25 |
26 | "Purchase Succeeded": "{white}Zakupiłeś {green}{0}{white}.",
27 | "Purchase Equip": "{white}Wyposażyłeś {green}{0}{white}.",
28 | "Purchase Unequip": "{white}Zdjąłeś {green}{0}{white}.",
29 | "Item Sell": "{white}Sprzedałeś {green}{0}{white}.",
30 | "Godmode expired": "{white}Twój czas trybu boga wygasł.",
31 | "Speed expired": "{white}Twój czas szybkości wygasł.",
32 | "Hidetrails off": "{white}Teraz możesz widzieć ślady.",
33 | "Hidetrails on": "{white}Teraz nie możesz widzieć śladów.",
34 |
35 | "menu_store": "Sklep [Twoje kredyty: {0}]",
36 |
37 | "menu_store": "Modele ogólne",
38 | "menu_store": "Modele T",
39 | "menu_store": "Modele CT",
40 | "menu_store": "{0} - [{1}]",
41 | "menu_store": "{0}",
42 | "menu_store": "Wyposaż",
43 | "menu_store": "Zdejmij",
44 | "menu_store": "Sprzedaj [{0}]",
45 | "menu_store": "Kupujesz?",
46 | "menu_store": "Tak",
47 | "menu_store": "Nie",
48 | "menu_store": "{0} - {1} kredytów",
49 | "menu_store": "Zbadaj",
50 |
51 | "css_credits": "{white}Masz {green}{0} {white}kredytów.",
52 | "css_givecredits": "{blue}{0} {white}dał {green}{2} kredytów {white}graczowi {green}{1}{white}.",
53 | "css_givecredits": "{blue}{0} {white}dał {green}{2} kredytów {white}graczowi {green}{1}{white}.",
54 | "css_givecredits": "{blue}{0} {white}dał {green}{2} kredytów {white}graczom {green}{1}{white}.",
55 |
56 | "css_gift": "{white}Wysłałeś {green}{1}{white} kredytów do {blue}{0}{white}.",
57 | "css_gift": "{blue}{0} {white}wysłał Ci {green}{1} {white}kredytów.",
58 |
59 | "css_reset": "{blue}{0}{white} zresetował dane sklepu gracza {green}{1}{white}.",
60 |
61 | "credits_earned": "{white}Zarobiłeś {green}{0} kredytów {white}za bycie aktywnym na serwerze.",
62 | "credits_earned": "{white}Zarobiłeś {green}{0} kredytów {white}za bycie nieaktywnym na serwerze.",
63 | "credits_earned": "{white}Zarobiłeś {green}{0} kredytów {white}za zabicie gracza.",
64 |
65 | "css_model0": "{blue}{0}{white} włączył wymuszanie domyślnych modeli graczy.",
66 | "css_model1": "{blue}{0}{white} wyłączył wymuszanie domyślnych modeli graczy.",
67 |
68 | "FreePlayerSkin": "Darmowa skórka gracza",
69 | "CT": "Skórki CT",
70 | "Fernandez Frogman [CT]": "Fernandez Frogman [CT]"
71 | }
72 |
--------------------------------------------------------------------------------
/Store/lang/pt-BR.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}Não há nenhum cliente correspondente",
3 | "More than one client matched": "{white>Há mais de um cliente correspondente",
4 | "Must be an integer": "{white}O valor inserido deve ser um número inteiro",
5 | "Must be higher than zero": "{white}O valor inserido deve ser maior que zero.",
6 | "Must be a steamid": "{white}O valor inserido deve ser um steamid válido",
7 | "No credits enough": "{white}Você não possui créditos suficientes.",
8 | "You are not alive": "{white}Você só pode comprar quando estiver vivo.",
9 | "You are alive": "{white}Você só pode comprar quando estiver morto.",
10 | "No in pistol round": "{white}Você não pode comprar este item {green}{0} {white} na rodada de pistola.",
11 | "No gift yourself": "{white}Você não pode presentear a si mesmo.",
12 | "No type found": "{white}Nenhum tipo encontrado. {red}{0}",
13 | "Gift timeout": "{white}Você precisa esperar {green}{0} segundos {white}para enviar o presente.",
14 | "No purchase because team": "{white}Você não pode comprar este item. Você precisa estar no time {red}{0} {white}.",
15 | "No equip because team": "{white}Você não pode equipar este item. Você precisa estar no time {red}{0} {white}.",
16 | "You need correct weapon": "{white}Você precisa de {red}{0} {white}para inspecionar.",
17 | "Players' credits are refreshed": "Os créditos dos jogadores foram atualizados.",
18 |
19 | "t team players": "{green}Jogadores de team t{white}",
20 | "ct team players": "{green}Jogadores de team ct{white}",
21 | "alive players": "{green}jogadores vivos{white}",
22 | "all players": "{green}todos os jogadores{white}",
23 | "dead players": "{green}jogadores mortos{white}",
24 | "Console": "Console",
25 |
26 | "Purchase Succeeded": "{white}Você comprou {green}{0}{white}.",
27 | "Purchase Equip": "{white}Você equipou {green}{0}{white}.",
28 | "Purchase Unequip": "{white}Você desequipou {green}{0}{white}.",
29 | "Item Sell": "{white}Você vendeu {green}{0}{white}.",
30 | "Godmode expired": "{white}Seu tempo de godmode expirou.",
31 | "Speed expired": "{white}Seu tempo de velocidade expirou.",
32 | "Hidetrails off": "{white}Agora você pode ver os rastros.",
33 | "Hidetrails on": "{white}Agora você não pode ver os rastros.",
34 |
35 | "menu_store": "Loja [Seus créditos: {0}]",
36 |
37 | "menu_store": "Modelos em comum",
38 | "menu_store": "Modelos T",
39 | "menu_store": "Modelos CT",
40 | "menu_store": "{0} - [{1}]",
41 | "menu_store": "{0}",
42 | "menu_store": "EQUIPAR",
43 | "menu_store": "DESEQUIPAR",
44 | "menu_store": "VENDER [{0}]",
45 | "menu_store": "Comprando?",
46 | "menu_store": "Sim",
47 | "menu_store": "Não",
48 | "menu_store": "{0} - {1} créditos",
49 | "menu_store": "Inspecionar",
50 |
51 | "css_credits": "{white}Você possui {green}{0} {white}créditos.",
52 | "css_givecredits": "{blue}{0} {white}deu {green}{2} créditos {white}para {green}{1}{white}.",
53 | "css_givecredits": "{blue}{0} {white}deu {green}{2} créditos {white}para {green}{1}{white}.",
54 | "css_givecredits": "{blue}{0} {white}deu {green}{2} créditos {white}para {green}{1}{white}.",
55 |
56 | "css_gift": "{white}Você enviou {green}{1} {white}créditos para {blue}{0}{white}.",
57 | "css_gift": "{blue}{0} {white}enviou {green}{1} {white}créditos para você.",
58 |
59 | "css_reset": "{blue}{0}{white} redefiniu os dados da loja de {green}{1}{white}.",
60 |
61 | "credits_earned": "{white}Você ganhou {green}{0} créditos {white}por estar ativo no servidor.",
62 | "credits_earned": "{white}Você ganhou {green}{0} créditos {white}por estar inativo no servidor.",
63 | "credits_earned": "{white}Você ganhou {green}{0} créditos {white}por matar um jogador.",
64 |
65 | "css_model0": "{blue}{0}{white} ativou o forçamento padrão dos modelos de jogadores",
66 | "css_model1": "{blue}{0}{white} desativou o forçamento padrão dos modelos de jogadores.",
67 |
68 | "FreePlayerSkin": "Skin de jogador grátis",
69 | "CT": "Skins CT",
70 | "Fernandez Frogman [CT]": "Fernandez Frogman [CT]"
71 | }
--------------------------------------------------------------------------------
/Store/lang/sl.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}Trenutno ni ustrezne stranke.",
3 | "More than one client matched": "{white}Ujema se več kot ena stranka.",
4 | "Must be an integer": "{white}Vrednost, ki ste jo vnesli, mora biti celo število.",
5 | "Must be higher than zero": "{white}Vrednost, ki ste jo vnesli, mora biti večja od nič.",
6 | "Must be a steamid": "{white}Vrednost, ki ste jo vnesli, mora biti veljavni steamid.",
7 | "No credits enough": "{white}Nimate dovolj kreditov za nakup.",
8 | "You are not alive": "{white}Ta predmet lahko kupiš le, ko si živ.",
9 | "You are alive": "{white}Ta predmet lahko kupiš le, ko si mrtev.",
10 | "No in pistol round": "{white}Tento predmet nemôžete použiť {green}{0} {white}v pištoľnom kole.",
11 | "No gift yourself": "{white}Ne morete darovati kreditov samemu sebi.",
12 | "No type found": "{white}Samemu sebi ne morete podariti kreditov. {red}{0}",
13 | "Gift timeout": "{white}Počakati moraš {green}{0} sekund {white}preden lahko podariš darilo.",
14 | "No purchase because team": "{white}Te predmete ne morete kupiti. Morate biti v ekipi {red}{0} {white}.",
15 | "No equip because team": "{white}Te predmete ne morete opremiti. Morate biti v ekipi {red}{0} {white}.",
16 | "You need correct weapon": "{white}Potrebujete {red}{0} {white}za pregled.",
17 | "Players' credits are refreshed": "Krediti igralcev so bili osveženi.",
18 |
19 | "t team players": "{green}Zaporniki",
20 | "ct team players": "{green}Pazniki",
21 | "alive players": "{green}Živi {white}igralci",
22 | "all players": "{green}Vsi {white}igralci",
23 | "dead players": "{green}Mrtvi {white}igralci",
24 | "Console": "Konzola",
25 |
26 | "Purchase Succeeded": "{white}Kupil {white}si {green}{0}{white}.",
27 | "Purchase Equip": "{white}Opremljeni {white}ste z {green}{0}{white}.",
28 | "Purchase Unequip": "{white}Odstranil {white}si {green}{0}{white}.",
29 | "Item Sell": "{white}Prodal {white}si {green}{0}{white}.",
30 | "Godmode expired": "{white}Vaš čas boga načina je potekel.",
31 | "Speed expired": "{white}Vaš hitrostni čas je potekel.",
32 | "Hidetrails off": "{white}Zdaj lahko vidite sledi.",
33 | "Hidetrails on": "{white}Zdaj ne morete videti sledi.",
34 |
35 | "menu_store": "Trgovina [Vaši krediti: {0}]",
36 |
37 | "menu_store": "Skupni Modeli",
38 | "menu_store": "T Modeli",
39 | "menu_store": "CT Modeli",
40 | "menu_store": "{0} - [{1}]",
41 | "menu_store": "{0}",
42 | "menu_store": "AKTIVIRAJ",
43 | "menu_store": "DEAKTIVIRAJ",
44 | "menu_store": "PRODAJ [{0}]",
45 | "menu_store": "Nakup?",
46 | "menu_store": "Da",
47 | "menu_store": "Ne",
48 | "menu_store": "{0} - {1} krediti",
49 | "menu_store": "Pregledati",
50 |
51 | "css_credits": "{white}Trenutno imaš {green}{0} {white}kreditov.",
52 | "css_givecredits": "{blue}{0} {white}je dal {lightblue}{2} kredite {white}igralcu {green}{1}{white}.",
53 | "css_givecredits": "{blue}{0} {white}je dal {lightblue}{2} kredite {white}igralcu {green}{1}{white}.",
54 | "css_givecredits": "{blue}{0} {white}je dal {lightblue}{2} kredite {white} {green}{1}{white}.",
55 |
56 | "css_gift": "{white}Poslal/a si {green}{1}{white}kredite igralcu {blue}{0}{white}.",
57 | "css_gift": "{blue}{0} {white}Poslal/a je {green}{1} {white} stevilo kreditov.",
58 |
59 | "css_reset": "{blue}{0}{white} restartal bazo {green}{1}{white}'s trgovine.",
60 |
61 | "credits_earned": "{white}Prislužil si {green}{0} kreditov {white}, zaradi igranja na strežniku.",
62 | "credits_earned": "{white}Prislužil si {green}{0} kreditov {white}, zaradi neaktivnosti na strežniku.",
63 | "credits_earned": "{white}Dobil si {green}{0} kreditov {white}za uboj igralca.",
64 |
65 | "css_model0": "{blue}{0}{white} vklopil privzeto vsiljevanje modelov igralcev.",
66 | "css_model1": "{blue}{0}{white} izklopil privzeto vsiljevanje modelov igralcev.",
67 |
68 | "FreePlayerSkin": "Brezplačna skin igralca",
69 | "CT": "CT Skini",
70 | "Fernandez Frogman [CT]": "Fernandez Frogman [CT]"
71 | }
--------------------------------------------------------------------------------
/Store/lang/ua.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}Не знайдено відповідного клієнта",
3 | "More than one client matched": "{white}Знайдено більше одного відповідного клієнта",
4 | "Must be an integer": "{white}Введене значення повинно бути цілим числом",
5 | "Must be higher than zero": "{white}Значення, яке ви ввели, має бути більше нуля.",
6 | "Must be a steamid": "{white}Значення, яке ви ввели, має бути дійсним паролем",
7 | "No credits enough": "{white}У вас недостатньо кредитів.",
8 | "You are not alive": "{white}Ви можете купити це лише тоді, коли ви живі.",
9 | "You are alive": "{white}Ви можете купити це лише тоді, коли ви мертві.",
10 | "No in pistol round": "{white}Ви не зможете купити цей предмет {green}{0} {white} у пістолетному раунді.",
11 | "No gift yourself": "{white}Ви не можете подарувати кредити самому собі.",
12 | "No type found": "{white}Тип не знайдено. {red}{0}",
13 | "Gift timeout": "{white}Вам потрібно зачекати {green}{0} секунд {white}щоб зробити подарунок.",
14 | "No purchase because team": "{white}Ви не можете придбати цей предмет. Ви повинні бути в команді {red}{0} {white}.",
15 | "No equip because team": "{white}Ви не можете екіпірувати цей предмет. Ви повинні бути в команді {red}{0} {white}.",
16 | "You need correct weapon": "{white}Вам потрібен {red}{0} {white}для огляду.",
17 | "Players' credits are refreshed": "Кредити гравців оновлено.",
18 |
19 | "t team players": "{green}Гравці {white}у команді t team",
20 | "ct team players": "{green}Гравці {white}у команді ct team",
21 | "alive players": "{green}Живі {white}гравці",
22 | "all players": "{green}Всі {white}гравці",
23 | "dead players": "{green}Мертві {white}гравці",
24 | "Console": "Консоль",
25 |
26 | "Purchase Succeeded": "{white}Ви {white}купили {green}{0}{white}.",
27 | "Purchase Equip": "{white}Ви {white}екіпіровали {green}{0}{white}.",
28 | "Purchase Unequip": "{white}Ви {white}зняли екіпіровку з {green}{0}{white}.",
29 | "Item Sell": "{white}Ви {white}продали {green}{0}{white}.",
30 | "Godmode expired": "{white}Час вашого богомоду закінчився.",
31 | "Speed expired": "{white}Час вашої швидкості закінчився.",
32 | "Hidetrails off": "{white}Тепер ви можете бачити сліди.",
33 | "Hidetrails on": "{white}Тепер ви не можете бачити сліди.",
34 |
35 | "menu_store": "Магазин [Ваші кредити: {0}]",
36 |
37 | "menu_store": "Загальні моделі",
38 | "menu_store": "Моделі t",
39 | "menu_store": "Моделі ct",
40 | "menu_store": "{0} - [{1}]",
41 | "menu_store": "{0}",
42 | "menu_store": "ЕКІПІРОВАТИ",
43 | "menu_store": "ЗНЯТИ",
44 | "menu_store": "ПРОДАТИ [{0}]",
45 | "menu_store": "Купуєш?",
46 | "menu_store": "Так",
47 | "menu_store": "Ні",
48 | "menu_store": "{0} - {1} креді",
49 | "menu_store": "Перевірити",
50 |
51 | "css_credits": "{white}У вас {green}{0} {white}кредитів.",
52 | "css_givecredits": "{blue}{0} {white}передав {green}{2} кредитів {white}{green}{1}{white}.",
53 | "css_givecredits": "{blue}{0} {white}передав {green}{2} кредитів {white}{green}{1}{white}.",
54 | "css_givecredits": "{blue}{0} {white}передали {green}{2} кредитів {white}гравцям: {green}{1}{white}.",
55 |
56 | "css_gift": "{white}Ви відправили {green}{1} кредитів {white}гравцю {blue}{0}{white}.",
57 | "css_gift": "{blue}{0} {white}передав вам {green}{1} кредитів{white}.",
58 |
59 | "css_reset": "{blue}{0}{white} скинув дані магазину для {green}{1}{white}.",
60 |
61 | "credits_earned": "{white}Ви заробили {green}{0} кредитів {white}за активну присутність на сервері.",
62 | "credits_earned": "{white}Ви заробили {green}{0} кредитів {white}за неактивну присутність на сервері.",
63 | "credits_earned": "{white}Ви заробили {green}{0} кредитів {white}за вбивство гравця.",
64 |
65 | "css_model0": "{blue}{0}{white} увімкнено форсування моделей гравців за замовчуванням.",
66 | "css_model1": "{blue}{0}{white} вимкнено вирівнювання моделей гравців за замовчуванням.",
67 |
68 | "FreePlayerSkin": "Безкоштовний скін гравця",
69 | "CT": "Скіни CT",
70 | "Fernandez Frogman [CT]": "Фернандес Frogman [CT]"
71 | }
--------------------------------------------------------------------------------
/Store/lang/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "No matching client": "{white}Не найдено совпадений с клиентом",
3 | "More than one client matched": "{white}Найдено более одного совпадения с клиентом",
4 | "Must be an integer": "{white}Введенное значение должно быть целым числом",
5 | "Must be higher than zero": "{white}Введенное вами значение должно быть больше нуля.",
6 | "Must be a steamid": "{white}Введенное вами значение должно быть действительным steamid",
7 | "No credits enough": "{white}У вас недостаточно кредитов.",
8 | "You are not alive": "{white}Вы можете купить это только когда вы живы.",
9 | "You are alive": "{white}Вы можете купить это только когда вы мертвы.",
10 | "No in pistol round": "{white}Вы не сможете купить этот предмет {green}{0} {white} в пистолетном раунде.",
11 | "No gift yourself": "{white}Вы не можете подарить кредиты сами себе.",
12 | "No type found": "{white}Тип не найден. {red}{0}",
13 | "Gift timeout": "{white}Вам нужно подождать {green}{0} секунд {white}перед тем, как отправить подарок.",
14 | "No purchase because team": "{white}Вы не можете купить этот предмет. Вы должны быть в команде {red}{0} {white}.",
15 | "No equip because team": "{white}Вы не можете экипировать этот предмет. Вы должны быть в команде {red}{0} {white}.",
16 | "You need correct weapon": "{white}Вам нужно {red}{0} {white}для осмотра.",
17 | "Players' credits are refreshed": "Кредиты игроков обновлены.",
18 |
19 | "t team players": "{green}Игроки {white}в команде t team",
20 | "ct team players": "{green}Игроки {white}в команде ct team",
21 | "alive players": "{green}Живые {white}игроки",
22 | "all players": "{green}Все {white}игроки",
23 | "dead players": "{green}Мертвые {white}игроки",
24 | "Console": "Консоль",
25 |
26 | "Purchase Succeeded": "{white}Вы {white}купили {green}{0}{white}.",
27 | "Purchase Equip": "{white}Вы {white}экипировали {green}{0}{white}.",
28 | "Purchase Unequip": "{white}Вы {white}сняли снаряжение с {green}{0}{white}.",
29 | "Item Sell": "{white}Вы {white}продали {green}{0}{white}.",
30 | "Godmode expired": "{white}Время вашего бессмертия истекло.",
31 | "Speed expired": "{white}Время вашей скорости истекло.",
32 | "Hidetrails off": "{white}Теперь вы можете видеть следы.",
33 | "Hidetrails on": "{white}Теперь вы не можете видеть следы.",
34 |
35 | "menu_store": "Магазин [Ваши кредиты: {0}]",
36 |
37 | "menu_store": "Общие модели",
38 | "menu_store