Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
samyycX committed Apr 14, 2024
1 parent 77bed5c commit 438b220
Show file tree
Hide file tree
Showing 19 changed files with 1,241 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj
176 changes: 176 additions & 0 deletions BuffInspector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
using System.Collections;
using System.Reflection;
using System.Security.Cryptography;
using System.Timers;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using CounterStrikeSharp.API.Core.Commands;
using CounterStrikeSharp.API.Core.Plugin.Host;
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using Newtonsoft.Json;

namespace BuffInspector;

public class Config : BasePluginConfig {
public bool UseSync {get; set;} = false;
public bool EnableImagePreview {get; set;} = true;
public float ImagePreviewTime {get; set;} = 5f;
}

public partial class BuffInspector : BasePlugin, IPluginConfig<Config>
{


public override string ModuleName => "Buff Inspector";
public override string ModuleVersion => "1";
public override string ModuleAuthor => "samyyc";
private DatabaseConnection Database;
public Config Config {get; set;}

public void OnConfigParsed(Config config) {
Config = config;
}

public static Dictionary<int,string> KnifeDefIndexToName { get; } = new Dictionary<int, string>
{
{ 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 Dictionary<ulong, string> CenterImages = new Dictionary<ulong, string>();

public override void Load(bool hotReload)
{
Console.WriteLine("Buff Inspector Loaded.");
var CS2WeaponPaintsConfigPath = Path.Join(ModuleDirectory, "../../configs/plugins/WeaponPaints/WeaponPaints.json");
if (!File.Exists(CS2WeaponPaintsConfigPath)) {
throw new FileNotFoundException($"Weapon Paints Config {CS2WeaponPaintsConfigPath} Not Found.");
}

StreamReader reader = File.OpenText(CS2WeaponPaintsConfigPath);
string content = reader.ReadToEnd();
DatabaseInfo info = JsonConvert.DeserializeObject<DatabaseInfo>(content)!;

Database = new DatabaseConnection(info);

RegisterListener<Listeners.OnTick>(() => {
if (!Config.EnableImagePreview) {
return;
}
foreach (var (steamid, imgurl) in CenterImages) {
var player = Utilities.GetPlayerFromSteamId(steamid);
if (player != null && player.IsValid && player.Pawn.IsValid && player.PlayerPawn.IsValid) {
player.PrintToCenterHtml($"<img src=\"{imgurl}\" width=100 height=100></img>", 10);
}
}
});
}

[ConsoleCommand("css_buff")]
[CommandHelper(minArgs: 1, usage: "[buff分享链接]", whoCanExecute: CommandUsage.CLIENT_ONLY)]
public async void OnBuffCommand(CCSPlayerController player, CommandInfo commandInfo) {
var splited = commandInfo.GetCommandString.Split(" ");
if (splited.Length < 2) {
player.PrintToChat(Localizer["failed"]);
return;
}
string url = splited[1];
player.PrintToChat(Localizer["parsing"]);

var steamid = player.AuthorizedSteamID!.SteamId64;

if (!Config.UseSync) {
var task = new Task(async() => {
SkinInfo? skinInfo = await scrapeUrl(url);

if (skinInfo == null) {
Server.NextFrame(() => player.PrintToChat(Localizer["failed"]));
return;
}

if (KnifeDefIndexToName.ContainsKey(skinInfo.DefIndex)) {
await Database.SetKnifeInfo(steamid, KnifeDefIndexToName[skinInfo.DefIndex]);
}

// gloves
if (skinInfo.DefIndex > 600) {
await Database.SetGloveInfo(steamid, skinInfo.DefIndex);
}

await Database.SetSkinInfo(steamid, skinInfo);

await Server.NextFrameAsync(() => {
player.PrintToChat(Localizer["success"]);
player.PrintToChat(Localizer["hint.name", skinInfo.title]);
player.PrintToChat(Localizer["hint.seed", skinInfo.PaintSeed]);
player.PrintToChat(Localizer["hint.index", skinInfo.PaintIndex]);
player.PrintToChat(Localizer["hint.wear", skinInfo.PaintWear]);
player.PrintToChat(Localizer["hint.update"]);
if (CenterImages.ContainsKey(steamid)) {
CenterImages.Remove(steamid);
}
CenterImages.Add(steamid, skinInfo.img);
AddTimer(Config.ImagePreviewTime, () => {
CenterImages.Remove(steamid);
});
});

});
task.Start();
} else {
SkinInfo? skinInfo = scrapeUrl(url).Result;

if (skinInfo == null) {
player.PrintToChat(Localizer["failed"]);
return;
}

if (KnifeDefIndexToName.ContainsKey(skinInfo.DefIndex)) {
Database.SetKnifeInfo(steamid, KnifeDefIndexToName[skinInfo.DefIndex]).Wait();
}

// gloves
if (skinInfo.DefIndex > 600) {
Database.SetGloveInfo(steamid, skinInfo.DefIndex).Wait();
}

Database.SetSkinInfo(steamid, skinInfo).Wait();

player.PrintToChat(Localizer["success"]);
player.PrintToChat(Localizer["hint.name", skinInfo.title]);
player.PrintToChat(Localizer["hint.seed", skinInfo.PaintSeed]);
player.PrintToChat(Localizer["hint.index", skinInfo.PaintIndex]);
player.PrintToChat(Localizer["hint.wear", skinInfo.PaintWear]);
if (CenterImages.ContainsKey(steamid)) {
CenterImages.Remove(steamid);
}
CenterImages.Add(steamid, skinInfo.img);
AddTimer(Config.ImagePreviewTime, () => {
CenterImages.Remove(steamid);
});

player.ExecuteClientCommandFromServer("css_wp");
}
}
}
24 changes: 24 additions & 0 deletions BuffInspector.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.213">
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
<PackageReference Include="Dapper" Version="2.1.44" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.60" />
<PackageReference Include="MySQLConnector" Version="2.3.6" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<None Update="lang\**\*.*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions BuffInspector.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuffInspector", "BuffInspector.csproj", "{BA65E1FE-CDA1-4DAE-8FDF-0C8EE05DE386}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BA65E1FE-CDA1-4DAE-8FDF-0C8EE05DE386}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA65E1FE-CDA1-4DAE-8FDF-0C8EE05DE386}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA65E1FE-CDA1-4DAE-8FDF-0C8EE05DE386}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA65E1FE-CDA1-4DAE-8FDF-0C8EE05DE386}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2B564B4A-B49D-4353-9AAB-F2AFEC5E5F2E}
EndGlobalSection
EndGlobal
107 changes: 107 additions & 0 deletions Database.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System.Text.Json.Serialization;
using Dapper;
using MySqlConnector;
using Newtonsoft.Json;

namespace BuffInspector;

class DatabaseInfo {
[JsonProperty("DatabaseHost")] public string host;
[JsonProperty("DatabasePort")] public int port;
[JsonProperty("DatabaseUser")] public string user;
[JsonProperty("DatabasePassword")] public string password;
[JsonProperty("DatabaseName")] public string database;
}


class DatabaseConnection {
private MySqlConnection conn;
public DatabaseConnection(DatabaseInfo info) {
Console.WriteLine(info.host);
string connectStr = $"server={info.host};port={info.port};user={info.user};password={info.password};database={info.database};Pooling=true;MinimumPoolSize=0;MaximumPoolsize=640;ConnectionIdleTimeout=30;";
conn = new MySqlConnection(connectStr);
conn.Open();
}

public async Task SetSkinInfo(ulong steamid, SkinInfo skinInfo) {
var sql = "";
var select = "SELECT 1 FROM wp_player_skins WHERE steamid=@steamid AND weapon_defindex=@DefIndex;";
var r = conn.Query(select, new {
steamid,
skinInfo.DefIndex
});
if (r.Count() > 0) {
sql = $"""
UPDATE wp_player_skins SET weapon_paint_id=@PaintIndex, weapon_wear=@PaintWear, weapon_seed=@PaintSeed WHERE steamid=@steamid AND weapon_defindex=@DefIndex;
""";
} else {
sql = $"""
INSERT INTO wp_player_skins (steamid, weapon_defindex, weapon_paint_id, weapon_wear, weapon_seed) VALUES (@steamid, @DefIndex, @PaintIndex, @PaintWear, @PaintSeed)
""";
}

await Task.Run(async () => {
await conn.ExecuteAsync(sql,
new {
steamid,
skinInfo.PaintIndex,
skinInfo.PaintSeed,
skinInfo.PaintWear,
skinInfo.DefIndex
}
);
});
}

public async Task SetKnifeInfo(ulong steamid, string knife) {
var sql = "";
var select = "SELECT 1 FROM wp_player_knife WHERE steamid=@steamid";
var r = conn.Query(select, new {
steamid
});
if (r.Count() > 0) {
sql = $"""
UPDATE wp_player_knife SET knife=@knife WHERE steamid=@steamid
""";
} else {
sql = $"""
INSERT INTO wp_player_knife (steamid, knife) VALUES (@steamid, @knife)
""";
}

await Task.Run(async () => {
await conn.ExecuteAsync(sql,
new {
steamid,
knife
}
);
});
}

public async Task SetGloveInfo(ulong steamid, int defindex) {
var sql = "";
var select = "SELECT 1 FROM wp_player_gloves WHERE steamid=@steamid";
var r = conn.Query(select, new {
steamid
});
if (r.Count() > 0) {
sql = $"""
UPDATE wp_player_gloves SET weapon_defindex=@defindex WHERE steamid=@steamid;
""";
} else {
sql = $"""
INSERT INTO wp_player_gloves (steamid, weapon_defindex) VALUES (@steamid, @defindex)
""";
}

await Task.Run(async () => {
await conn.ExecuteAsync(sql,
new {
steamid,
defindex
}
);
});
}
}
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
# CS2-BuffInspector
基于WeaponPaints,在游戏内解析buff的分享链接并更换皮肤

# 配置项
- `UseSync` 设置为true时开启同步模式,并且解析完成后自动刷新皮肤 (默认关闭,不会自动刷新皮肤)
> [!IMPORTANT]
> 开启此选项可能会造成服务器发生严重卡顿,不建议在连接至BUFF或者皮肤数据库时有较大延迟的服务器使用
- `EnableImagePreview` 开启屏幕中心的图片预览
- `ImagePreviewTime` 图片预览的持续时间


# 使用方法
安装完插件后,使用
`!buff <buff分享链接>`
指令更换BUFF皮肤

Loading

0 comments on commit 438b220

Please sign in to comment.