From 77409269d07103e50e26fd983fd37036f96434df Mon Sep 17 00:00:00 2001 From: Dawid Bepierszcz <41084667+daffyyyy@users.noreply.github.com> Date: Mon, 4 Mar 2024 23:51:08 +0100 Subject: [PATCH] 2.1a - FINALLY WINDOWS SUPPORT - Fixed visual bug (no skin) --- Events.cs | 82 +++++++----------- README.md | 5 -- VERSION | 2 +- WeaponAction.cs | 224 +++++++++++++----------------------------------- WeaponPaints.cs | 2 +- 5 files changed, 90 insertions(+), 225 deletions(-) diff --git a/Events.cs b/Events.cs index 72575b61..02b18835 100644 --- a/Events.cs +++ b/Events.cs @@ -1,7 +1,6 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; -using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; namespace WeaponPaints @@ -105,6 +104,8 @@ namespace WeaponPaints if (isKnife && !g_playersKnife.ContainsKey(player.Slot) || isKnife && g_playersKnife[player.Slot] == "weapon_knife") return; + int[] newPaints = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 }; + if (isKnife) { var newDefIndex = WeaponDefindex.FirstOrDefault(x => x.Value == g_playersKnife[player.Slot]); @@ -139,41 +140,18 @@ namespace WeaponPaints if (fallbackPaintKit == 0) return; - var foundSkin = skinsList.FirstOrDefault(skin => - ((int?)skin?["weapon_defindex"] ?? 0) == weaponDefIndex && - ((int?)skin?["paint"] ?? 0) == fallbackPaintKit && - skin?["paint_name"] != null - ); - - if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) + if (!isKnife) { - var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode); - - int[] newPaints = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 }; - if (newPaints.Contains(fallbackPaintKit)) { - skeleton.ModelState.MeshGroupMask = 1; + UpdatePlayerWeaponMeshGroupMask(player, weapon, false); } else { - if (skeleton.ModelState.MeshGroupMask != 2) - { - skeleton.ModelState.MeshGroupMask = 2; - } + UpdatePlayerWeaponMeshGroupMask(player, weapon, true); } } - var viewModels = GetPlayerViewModels(player); - if (viewModels == null || viewModels.Length == 0) - return; - - var viewModel = viewModels[0]; - if (viewModel == null || viewModel.Value == null || viewModel.Value.Weapon == null || viewModel.Value.Weapon.Value == null) - return; - - Utilities.SetStateChanged(viewModel.Value, "CBaseEntity", "m_CBodyComponent"); - return; } @@ -193,38 +171,17 @@ namespace WeaponPaints if (fallbackPaintKit == 0) return; - var foundSkin1 = skinsList.FirstOrDefault(skin => - ((int?)skin?["weapon_defindex"] ?? 0) == weaponDefIndex && - ((int?)skin?["paint"] ?? 0) == fallbackPaintKit && - skin?["paint_name"] != null - ); - - if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) + if (!isKnife) { - var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode); - int[] newPaints = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 }; if (newPaints.Contains(fallbackPaintKit)) { - skeleton.ModelState.MeshGroupMask = 1; + UpdatePlayerWeaponMeshGroupMask(player, weapon, false); } else { - if (skeleton.ModelState.MeshGroupMask != 2) - { - skeleton.ModelState.MeshGroupMask = 2; - } + UpdatePlayerWeaponMeshGroupMask(player, weapon, true); } } - - var viewModels1 = GetPlayerViewModels(player); - if (viewModels1 == null || viewModels1.Length == 0) - return; - - var viewModel1 = viewModels1[0]; - if (viewModel1 == null || viewModel1.Value == null || viewModel1.Value.Weapon == null || viewModel1.Value.Weapon.Value == null) - return; - - Utilities.SetStateChanged(viewModel1.Value, "CBaseEntity", "m_CBodyComponent"); } private void OnMapStart(string mapName) @@ -306,6 +263,25 @@ namespace WeaponPaints return HookResult.Continue; } + public void OnEntitySpawned(CEntityInstance entity) + { + var designerName = entity.DesignerName; + + if (designerName.Contains("weapon")) + { + Server.NextFrame(() => + { + var weapon = new CBasePlayerWeapon(entity.Handle); + if (!weapon.IsValid) return; + + var player = Utilities.GetPlayerFromSteamId(weapon.OriginalOwnerXuidLow); + if (player == null || !Utility.IsPlayerValid(player)) return; + + GivePlayerWeaponSkin(player, weapon); + }); + } + } + private void RegisterListeners() { RegisterListener(OnMapStart); @@ -313,8 +289,8 @@ namespace WeaponPaints RegisterEventHandler(OnPlayerSpawn); RegisterEventHandler(OnRoundStart, HookMode.Pre); RegisterEventHandler(OnRoundEnd); - - VirtualFunctions.GiveNamedItemFunc.Hook(OnGiveNamedItemPost, HookMode.Post); + RegisterListener(OnEntitySpawned); + //VirtualFunctions.GiveNamedItemFunc.Hook(OnGiveNamedItemPost, HookMode.Post); //HookEntityOutput("weapon_knife", "OnPlayerPickup", OnPickup); } diff --git a/README.md b/README.md index 3fd41c9c..5d1b16de 100644 --- a/README.md +++ b/README.md @@ -81,11 +81,6 @@ Unfinished, unoptimized and not fully functional ugly demo weapon paints plugin - Steam login/logout - Change knife, paint, seed and wear -## Known issues -- Issue on Windows servers, no knives are given. -- You can't change knife if it's equpied in cs2 inventory -- Can cause incompatibility with plugins/maps which manipulates weapons and knives - ## Troubleshooting
**Skins are not changing:** diff --git a/VERSION b/VERSION index e2861cd4..1de7bcd1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0a \ No newline at end of file +2.1a \ No newline at end of file diff --git a/WeaponAction.cs b/WeaponAction.cs index 4aafc462..609eed7a 100644 --- a/WeaponAction.cs +++ b/WeaponAction.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Utils; @@ -10,176 +11,37 @@ namespace WeaponPaints { public partial class WeaponPaints { - internal static void ChangeWeaponAttributes(CBasePlayerWeapon? weapon, CCSPlayerController? player, bool isKnife = false) - { - if (player is null || weapon is null || !weapon.IsValid || !Utility.IsPlayerValid(player)) return; - - if (!gPlayerWeaponsInfo.ContainsKey(player.Slot)) return; - - if (isKnife && !g_playersKnife.ContainsKey(player.Slot) || isKnife && g_playersKnife[player.Slot] == "weapon_knife") return; - - if (isKnife) - { - var newDefIndex = WeaponDefindex.FirstOrDefault(x => x.Value == g_playersKnife[player.Slot]); - if (newDefIndex.Key == 0) return; - - if (weapon.AttributeManager.Item.ItemDefinitionIndex != newDefIndex.Key) - { - SubclassChange(weapon, (ushort)newDefIndex.Key); - } - - weapon.AttributeManager.Item.ItemDefinitionIndex = (ushort)newDefIndex.Key; - weapon.AttributeManager.Item.EntityQuality = 3; - } - - int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex; - int fallbackPaintKit = 0; - - if (_config.Additional.GiveRandomSkin && - !gPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex)) - { - // Random skins - weapon.AttributeManager.Item.ItemID = 16384; - weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF; - weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32; - weapon.FallbackPaintKit = GetRandomPaint(weaponDefIndex); - weapon.FallbackSeed = 0; - weapon.FallbackWear = 0.000001f; - CAttributeList_SetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit); - - fallbackPaintKit = weapon.FallbackPaintKit; - - if (fallbackPaintKit == 0) - return; - - var foundSkin = skinsList.FirstOrDefault(skin => - ((int?)skin?["weapon_defindex"] ?? 0) == weaponDefIndex && - ((int?)skin?["paint"] ?? 0) == fallbackPaintKit && - skin?["paint_name"] != null - ); - /* - string skinName = foundSkin?["paint_name"]?.ToString() ?? ""; - if (!string.IsNullOrEmpty(skinName)) - new SchemaString(weapon.AttributeManager.Item, "m_szCustomName").Set(skinName); - */ - if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) - { - var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode); - - int[] newPaints = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 }; - - if (newPaints.Contains(fallbackPaintKit)) - { - skeleton.ModelState.MeshGroupMask = 1; - } - else - { - if (skeleton.ModelState.MeshGroupMask != 2) - { - skeleton.ModelState.MeshGroupMask = 2; - } - } - } - - var viewModels = GetPlayerViewModels(player); - if (viewModels == null || viewModels.Length == 0) - return; - - var viewModel = viewModels[0]; - if (viewModel == null || viewModel.Value == null || viewModel.Value.Weapon == null || viewModel.Value.Weapon.Value == null) - return; - - Utilities.SetStateChanged(viewModel.Value, "CBaseEntity", "m_CBodyComponent"); - - return; - } - - if (!gPlayerWeaponsInfo[player.Slot].ContainsKey(weaponDefIndex)) return; - WeaponInfo weaponInfo = gPlayerWeaponsInfo[player.Slot][weaponDefIndex]; - //Log($"Apply on {weapon.DesignerName}({weapon.AttributeManager.Item.ItemDefinitionIndex}) paint {gPlayerWeaponPaints[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} seed {gPlayerWeaponSeed[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]} wear {gPlayerWeaponWear[steamId.SteamId64][weapon.AttributeManager.Item.ItemDefinitionIndex]}"); - weapon.AttributeManager.Item.ItemID = 16384; - weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF; - weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32; - weapon.FallbackPaintKit = weaponInfo.Paint; - weapon.FallbackSeed = weaponInfo.Seed; - weapon.FallbackWear = weaponInfo.Wear; - CAttributeList_SetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weapon.FallbackPaintKit); - - fallbackPaintKit = weapon.FallbackPaintKit; - - if (fallbackPaintKit == 0) - return; - - var foundSkin1 = skinsList.FirstOrDefault(skin => - ((int?)skin?["weapon_defindex"] ?? 0) == weaponDefIndex && - ((int?)skin?["paint"] ?? 0) == fallbackPaintKit && - skin?["paint_name"] != null - ); - - /* - var skinName1 = foundSkin1?["paint_name"]?.ToString() ?? ""; - if (!string.IsNullOrEmpty(skinName1)) - new SchemaString(weapon.AttributeManager.Item, "m_szCustomName").Set(skinName1); - */ - if (!isKnife && weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) - { - var skeleton = GetSkeletonInstance(weapon.CBodyComponent.SceneNode); - int[] newPaints = { 1171, 1170, 1169, 1164, 1162, 1161, 1159, 1175, 1174, 1167, 1165, 1168, 1163, 1160, 1166, 1173 }; - if (newPaints.Contains(fallbackPaintKit)) - { - skeleton.ModelState.MeshGroupMask = 1; - } - else - { - if (skeleton.ModelState.MeshGroupMask != 2) - { - skeleton.ModelState.MeshGroupMask = 2; - } - } - } - - var viewModels1 = GetPlayerViewModels(player); - if (viewModels1 == null || viewModels1.Length == 0) - return; - - var viewModel1 = viewModels1[0]; - if (viewModel1 == null || viewModel1.Value == null || viewModel1.Value.Weapon == null || viewModel1.Value.Weapon.Value == null) - return; - - Utilities.SetStateChanged(viewModel1.Value, "CBaseEntity", "m_CBodyComponent"); - } - internal static void GiveKnifeToPlayer(CCSPlayerController? player) { if (!_config.Additional.KnifeEnabled || player == null || !player.IsValid) return; if (PlayerHasKnife(player)) return; - string knifeToGive; - if (g_playersKnife.TryGetValue(player.Slot, out var knife)) - { - knifeToGive = knife; - } - else if (_config.Additional.GiveRandomKnife) - { - var knifeTypes = weaponList.Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet")).ToList(); + //string knifeToGive; + //if (g_playersKnife.TryGetValue(player.Slot, out var knife)) + //{ + // knifeToGive = knife; + //} + //else if (_config.Additional.GiveRandomKnife) + //{ + // var knifeTypes = weaponList.Where(pair => pair.Key.StartsWith("weapon_knife") || pair.Key.StartsWith("weapon_bayonet")).ToList(); - if (knifeTypes.Count == 0) - { - Utility.Log("No valid knife types found."); - return; - } + // if (knifeTypes.Count == 0) + // { + // Utility.Log("No valid knife types found."); + // return; + // } - Random random = new(); - int index = random.Next(knifeTypes.Count); - knifeToGive = knifeTypes[index].Key; - } - else - { - knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife"; - } + // Random random = new(); + // int index = random.Next(knifeTypes.Count); + // knifeToGive = knifeTypes[index].Key; + //} + //else + //{ + //} - player.GiveNamedItem(knifeToGive); + string knifeToGive = (CsTeam)player.TeamNum == CsTeam.Terrorist ? "weapon_knife_t" : "weapon_knife"; + player.GiveNamedItem(CsItem.Knife); } internal static bool PlayerHasKnife(CCSPlayerController? player) @@ -484,6 +346,35 @@ namespace WeaponPaints SubclassChangeFunc(weapon.Handle, itemD.ToString()); } + public static void UpdateWeaponMeshGroupMask(CBaseEntity weapon, bool isLegacy = false) + { + if (weapon.CBodyComponent != null && weapon.CBodyComponent.SceneNode != null) + { + var skeleton = weapon.CBodyComponent.SceneNode.GetSkeletonInstance(); + if (skeleton != null) + { + var value = (ulong)(isLegacy ? 2 : 1); + + if (skeleton.ModelState.MeshGroupMask != value) + { + skeleton.ModelState.MeshGroupMask = value; + } + } + } + } + + public 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) + { + UpdateWeaponMeshGroupMask(viewModel, isLegacy); + Utilities.SetStateChanged(viewModel, "CBaseEntity", "m_CBodyComponent"); + } + } + public static CCSPlayerController? GetPlayerFromItemServices(CCSPlayer_ItemServices itemServices) { var pawn = itemServices.Pawn.Value; @@ -498,12 +389,15 @@ namespace WeaponPaints Func GetSkeletonInstance = VirtualFunction.Create(node.Handle, 8); return new CSkeletonInstance(GetSkeletonInstance(node.Handle)); } - - private static unsafe CHandle[]? GetPlayerViewModels(CCSPlayerController player) + private static unsafe CBaseViewModel? GetPlayerViewModel(CCSPlayerController player) { if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null; - CCSPlayer_ViewModelServices viewModelServices = new CCSPlayer_ViewModelServices(player.PlayerPawn.Value.ViewModelServices!.Handle); - return GetFixedArray>(viewModelServices.Handle, "CCSPlayer_ViewModelServices", "m_hViewModel", 3); + CCSPlayer_ViewModelServices viewModelServices = new(player.PlayerPawn.Value.ViewModelServices!.Handle); + nint ptr = viewModelServices.Handle + Schema.GetSchemaOffset("CCSPlayer_ViewModelServices", "m_hViewModel"); + var references = MemoryMarshal.CreateSpan(ref ptr, 3); + var viewModel = (CHandle)Activator.CreateInstance(typeof(CHandle), references[0])!; + if (viewModel == null || viewModel.Value == null) return null; + return viewModel.Value; } public static unsafe T[] GetFixedArray(nint pointer, string @class, string member, int length) where T : CHandle diff --git a/WeaponPaints.cs b/WeaponPaints.cs index e5111f46..dcc102ae 100644 --- a/WeaponPaints.cs +++ b/WeaponPaints.cs @@ -156,7 +156,7 @@ public partial class WeaponPaints : BasePlugin, IPluginConfig "Nereziel & daffyy"; public override string ModuleDescription => "Skin, gloves and knife selector, standalone and web-based"; public override string ModuleName => "WeaponPaints"; - public override string ModuleVersion => "2.0a"; + public override string ModuleVersion => "2.1a"; public static WeaponPaintsConfig GetWeaponPaintsConfig() {