Files
plugin/_old_plugin.cs
2026-07-07 16:36:30 +02:00

199 lines
8.7 KiB
C#

using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using System.Runtime.InteropServices;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
namespace OPorning;
public class OPorning : BasePlugin
{
public override string ModuleName => "p0rning";
public override string ModuleVersion => "1.0.0";
private static readonly ulong WeaponId = 16384;
private static readonly HttpClient Client = new HttpClient();
public class LegacyClass
{
[JsonPropertyName("legacy")]
public bool Legacy { get; set; }
}
private static readonly MemoryFunctionVoid<nint, string, float> CAttributeListSetOrAddAttributeValueByName = new(GameData.GetSignature("CAttributeList_SetOrAddAttributeValueByName"));
private void Info(string message) => Console.WriteLine("\x1b[38;5;129m[AINDUSTRIES PRODUCTIONS] \x1b[38;5;82m[INFO] \x1b[38;5;255m{0}\x1b[0m", message);
private void Debug(string message) => Console.WriteLine("\x1b[38;5;129m[AINDUSTRIES PRODUCTIONS] \x1b[38;5;214m[DEBUG] \x1b[38;5;255m{0}\x1b[0m", message);
public override void Load(bool hotReload)
{
RegisterListener<Listeners.OnEntitySpawned>(OnEntityCreated);
RegisterListener<Listeners.OnEntityParentChanged>((entity, parent) =>
{
var designerName = entity.DesignerName;
if (!designerName.Contains("weapon_"))
{
return;
}
Debug("Parent changed for weapon");
var weapon = new CBasePlayerWeapon(entity.Handle);
if (weapon.AttributeManager.Item.ItemID != WeaponId)
{
Debug("Weapon is not a spawned weapon");
return;
}
DebugWeapon(weapon);
bool legacy = IsWeaponLegacy(weapon);
//TODO: Check if this is necessary
// Seems not necessary, will keep it for now.
//CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit);
//CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture seed", weapon.FallbackSeed);
//CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture prefab", weapon.FallbackPaintKit);
//CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture seed", weapon.FallbackSeed);
UpdateWeaponMeshGroupMask(weapon, legacy);
});
Info("Plugin Loaded");
}
[ConsoleCommand("css_give", "Give an item to yourself")]
[CommandHelper(minArgs: 1, usage: "[name] [paint] [seed]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void Give(CCSPlayerController? player, CommandInfo commandInfo)
{
string weaponName = commandInfo.GetArg(1);
string paint = commandInfo.GetArg(2);
int paintId = 0;
if (paint != "")
{
paintId = Int32.Parse(paint);
}
string pattern = commandInfo.GetArg(3);
int patternId = 1;
if (pattern != "")
{
patternId = Int32.Parse(pattern);
}
if (player == null) return;
var entity = player.GiveNamedItem(weaponName);
var weaponEntity = new CCSWeaponBase(entity);
var baseWeapon = new CBasePlayerWeapon(weaponEntity.Handle);
commandInfo.ReplyToCommand("Weapon given");
Server.NextFrame(() =>
{
GivePlayerWeaponSkin(player, baseWeapon, paintId, patternId);
Info("Weapon given and skin applied.");
});
}
private static void UpdateWeaponMeshGroupMask(CBaseEntity weapon, bool isLegacy = false)
{
if (weapon.CBodyComponent?.SceneNode == null) return;
var skeleton = weapon.CBodyComponent.SceneNode.GetSkeletonInstance();
var value = (ulong)(isLegacy ? 2 : 1);
if (skeleton.ModelState.MeshGroupMask != value)
{
skeleton.ModelState.MeshGroupMask = value;
}
}
private static void UpdatePlayerWeaponMeshGroupMask(CCSPlayerController player, CBasePlayerWeapon weapon, bool isLegacy)
{
UpdateWeaponMeshGroupMask(weapon, isLegacy);
var viewModel = GetPlayerViewModel(player);
if (viewModel == null || viewModel.Weapon.Value == null ||
viewModel.Weapon.Value.Index != weapon.Index) return;
UpdateWeaponMeshGroupMask(viewModel, isLegacy);
Utilities.SetStateChanged(viewModel, "CBaseEntity", "m_CBodyComponent");
}
private static CBaseViewModel? GetPlayerViewModel(CCSPlayerController player)
{
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null;
CCSPlayer_ViewModelServices viewModelServices = new(player.PlayerPawn.Value.ViewModelServices!.Handle);
var ptr = viewModelServices.Handle + Schema.GetSchemaOffset("CCSPlayer_ViewModelServices", "m_hViewModel");
var references = MemoryMarshal.CreateSpan(ref ptr, 3);
var viewModel = (CHandle<CBaseViewModel>)Activator.CreateInstance(typeof(CHandle<CBaseViewModel>), references[0])!;
return viewModel.Value == null ? null : viewModel.Value;
}
private void GivePlayerWeaponSkin(CCSPlayerController? player, CBasePlayerWeapon baseWeapon, int paint, int pattern)
{
var weapon = new CEconEntity(baseWeapon.Handle);
baseWeapon.AttributeManager.Item.AttributeList.Attributes.RemoveAll();
baseWeapon.AttributeManager.Item.NetworkedDynamicAttributes.Attributes.RemoveAll();
weapon.FallbackPaintKit = paint;
weapon.FallbackSeed = pattern;
weapon.FallbackWear = 0.01f;
weapon.AttributeManager.Item.AccountID = (uint)player.SteamID;
/*
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit);
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture seed", weapon.FallbackSeed);
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture prefab", weapon.FallbackPaintKit);
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.AttributeList.Handle, "set item texture seed", weapon.FallbackSeed);
*/
weapon.AttributeManager.Item.ItemID = WeaponId;
weapon.AttributeManager.Item.ItemIDLow = (uint)WeaponId & 0xFFFFFFFF;
weapon.AttributeManager.Item.ItemIDHigh = (uint)WeaponId >> 32;
bool legacy = IsWeaponLegacy(baseWeapon);
UpdatePlayerWeaponMeshGroupMask(player, baseWeapon, legacy);
Info($"Gave weapon to {player.PlayerName}");
DebugWeapon(baseWeapon);
}
private void OnEntityCreated(CEntityInstance entity)
{
// TODO: Check if user has a loadout set, if so change the skins.
}
private void DebugWeapon(CBasePlayerWeapon weapon)
{
Debug("[WEAPON DEBUG]");
Console.WriteLine("[Entity ID]: {0}", weapon.AttributeManager.Item.ItemID);
Console.WriteLine("[Owner ID]: {0}", weapon.AttributeManager.Item.AccountID);
Console.WriteLine("[Owner ID Low]: {0}", weapon.AttributeManager.Item.ItemIDLow);
Console.WriteLine("[Owner ID High]: {0}", weapon.AttributeManager.Item.ItemIDHigh);
Console.WriteLine("[Paint]: {0}", weapon.FallbackPaintKit);
Console.WriteLine("[Pattern]: {0}", weapon.FallbackSeed);
Console.WriteLine("[DefIndex]: {0}", weapon.AttributeManager.Item.ItemDefinitionIndex);
}
private bool IsWeaponLegacy(CBasePlayerWeapon weapon)
{
var designerName = weapon.DesignerName;
var paint = weapon.FallbackPaintKit;
HttpResponseMessage response = Client.GetAsync($"http://127.0.0.1:8900/api/legacy/{designerName}/{paint}").GetAwaiter().GetResult();
LegacyClass? value = null;
if (response.IsSuccessStatusCode)
{
value = response.Content.ReadFromJsonAsync<LegacyClass>().GetAwaiter().GetResult();
}
return value?.Legacy ?? false;
}
}