diff --git a/README.md b/README.md index 05b470a..6a019e7 100644 --- a/README.md +++ b/README.md @@ -223,14 +223,9 @@ Buying a server on pukawka? Use my [referral code](https://pukawka.pl/pp,juzlus. Game csgo ``` 3. Install **CounterStrikeSharp**. - - Download [CounterStrikeSharp-With-Runtime](https://github.com/roflmuffin/CounterStrikeSharp/releases). + - Download [CounterStrikeSharp-With-Runtime](https://github.com/roflmuffin/CounterStrikeSharp/releases) (v1.0.375 or newer). - Extract it to the `C2Server/game/csgo/` folder. -4. Install **Ray-Trace** - - Download [RayTrace-CSS-API](https://github.com/FUNPLAY-pro-CS2/Ray-Trace/releases) - - Extract folder `conterstrikesharp` to the `CS2Server/game/csgo/addons/` folder. - - Download [RayTrace-MM](https://github.com/FUNPLAY-pro-CS2/Ray-Trace/releases) - - Extract it to the `CS2Server/game/csgo/addons/` folder. -5. Install **jRandomSkills** +4. Install **jRandomSkills** - Download [jRandomSkills](https://github.com/Juzlus/jRandomSkills/releases) ## Server Commands diff --git a/WASDMenuAPI - SRC Files/WASDMenuAPI.csproj b/WASDMenuAPI - SRC Files/WASDMenuAPI.csproj index 564cd1d..152ec1f 100644 --- a/WASDMenuAPI - SRC Files/WASDMenuAPI.csproj +++ b/WASDMenuAPI - SRC Files/WASDMenuAPI.csproj @@ -7,7 +7,7 @@ - + diff --git a/jRandomSkills - SRC Files/jRandomSkills.csproj b/jRandomSkills - SRC Files/jRandomSkills.csproj index e853387..9106081 100644 --- a/jRandomSkills - SRC Files/jRandomSkills.csproj +++ b/jRandomSkills - SRC Files/jRandomSkills.csproj @@ -19,18 +19,12 @@ - + - - - libs/RayTraceApi.dll - - - diff --git a/jRandomSkills - SRC Files/libs/RayTraceApi.dll b/jRandomSkills - SRC Files/libs/RayTraceApi.dll deleted file mode 100644 index 584aea0..0000000 Binary files a/jRandomSkills - SRC Files/libs/RayTraceApi.dll and /dev/null differ diff --git a/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json b/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json index bd817d6..0c2c147 100644 --- a/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json +++ b/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json @@ -3,20 +3,20 @@ "signatures": { "library": "server", "windows": "48 8B C4 48 89 58 ? 48 89 68 ? 48 89 70 ? 57 41 56 41 57 48 81 EC ? ? ? ? 48 8B B4 24 ? ? ? ? 4D 8B F8", - "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 45 89 CE 41 55 4D 89 C5 41 54 53 48 83 EC ? 48 89 55 ? 48 89 F2 48 89 FE" + "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 45 89 CE 41 55 4D 89 C5 41 54 53 48 81 EC ? ? ? ? 48 89 95 ? ? ? ? 48 89 F2 48 89 FE 48 8D 3D" } }, "HEGrenadeProjectile_CreateFunc": { "signatures": { "library": "server", - "windows": "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B 6C 24 ? 49 8B F8 4C 8B C2 0F 29 74 24 ? 48 8B D1 48 8B D9 48 8D 0D ? ? ? ? 4C 8B CD E8 ? ? ? ? F3 0F 10 0D ? ? ? ? 48 8B C8 48 8B F0 E8 ? ? ? ? 48 8B D7 48 8B CE", + "windows": "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B AC 24 ? ? ? ? 49 8B F8 4C 8B C2 0F 29 74 24 ? 48 8B D1 0F 29 7C 24 ? 48 8B D9 4C 8B CD 48 8D 0D ? ? ? ? E8", "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 49 89 D6 48 89 F2 48 89 FE 41 55 48 8D 3D ? ? ? ? 4D 89 C5 41 54 45 89 CC 53" } }, "CMolotovProjectile_CreateFunc": { "signatures": { "library": "server", - "windows": "48 8B C4 48 89 58 10 4C 89 40 18 48 89 48 08", + "windows": "48 8B C4 48 89 58 08 48 89 70 10 48 89 78 20 4C 89 40 18 55 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 45 33 FF", "linux": "55 48 8D 05 ? ? ? ? 48 89 E5 41 57 41 56 41 55 41 54 49 89 FC 53 48 81 EC ? ? ? ? 4C 8D 35" } }, @@ -30,7 +30,7 @@ "SnapViewAngles": { "signatures": { "library": "server", - "windows": "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B DA 48 8B F1 48 8D 55", + "windows": "48 89 7C 24 ? 55 48 8B EC 48 81 EC ? ? ? ? 48 8B F9 48 8D 4D ? E8 ? ? ? ? F2 0F 10 87 ? ? ? ? 48 8B CF", "linux": "55 48 89 E5 41 57 49 89 FF 48 89 F7 41 56 41 55 41 54 53 48 81 EC ? ? ? ? E8" } }, @@ -42,8 +42,8 @@ }, "INetworkGameServer_Slots": { "offsets": { - "windows": 584, - "linux": 584 + "windows": 616, + "linux": 616 } }, "INetworkServerService_GetIGameServer": { diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs index bc39f3a..4290123 100644 --- a/jRandomSkills - SRC Files/src/jRandomSkills.cs +++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs @@ -31,7 +31,7 @@ namespace src public override string ModuleName => "[CS2] [ jRandomSkills ]"; public override string ModuleAuthor => "D3X (Original), Juzlus (Modifier), ByDexterTR (Contributor)"; public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus."; - public override string ModuleVersion => "1.2.4.b2"; + public override string ModuleVersion => "1.2.4.b3"; public override void Load(bool hotReload) { @@ -280,9 +280,6 @@ namespace src { "WASDMenuAPI", "./WASDMenuAPI.dll" }, { "MaxMind", "./MaxMind.Db.dll" }, { "GeoLite2", "./packages/GeoLite2-Country.mmdb" }, - { "RayTraceApi", "./../../shared/RayTraceApi/RayTraceApi.dll" }, - { "RayTraceImpl", "./../../plugins/RayTraceImpl/RayTraceImpl.dll" }, - { "RayTrace MetaMod", "./../../../metamod/RayTrace.vdf" }, { "jRandomSkills gamedata", "./../../gamedata/jRandomSkills.gamedata.json" } }; diff --git a/jRandomSkills - SRC Files/src/player/EntityEvents.cs b/jRandomSkills - SRC Files/src/player/EntityEvents.cs index c98cc41..17c54e9 100644 --- a/jRandomSkills - SRC Files/src/player/EntityEvents.cs +++ b/jRandomSkills - SRC Files/src/player/EntityEvents.cs @@ -98,6 +98,7 @@ namespace src.player !Instance.SkillPlayer.Any(p => !p.IsDrawing && p.Skill == Skills.Fortnite)) Instance.SkillAction("Fortnite", "OnTakeDamage", args); + SkillUtils.ApplyNativeKill(entity, info); return HookResult.Continue; } } diff --git a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs index 2d8b1b1..770161b 100644 --- a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs +++ b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs @@ -6,7 +6,6 @@ using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.UserMessages; using CounterStrikeSharp.API.Modules.Utils; -using RayTraceAPI; using src.player.skills; using src.utils; using System.Collections.Concurrent; @@ -108,6 +107,7 @@ namespace src.player TryUnhook(() => VirtualFunctions.CCSPlayer_ItemServices_CanAcquireFunc.Unhook(OnWeaponCanAcquire, HookMode.Pre)); TryUnhook(() => Instance.UnhookUserMessage(208, PlayerMakeSound)); TryUnhook(() => Instance.RemoveListener(CheckTransmit)); + TryUnhook(NoRecoil.RestoreSpread); } private static void TryUnhook(Action unhook) @@ -507,6 +507,7 @@ namespace src.player private static void OnTick() { ReportStall(); + NoRecoil.RestoreSpread(); long perfStart = PerfLog.Start(); lock (setLock) @@ -794,7 +795,7 @@ namespace src.player Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z); Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * 80; - ulong mask = (ulong)(InteractionLayers.MASK_WORLD_ONLY | InteractionLayers.Player | InteractionLayers.NPC); + ulong mask = RayTrace.WorldOnlyMask | (ulong)(Contents.Player | Contents.Npc); ulong contents = 0; var result = RayTrace.TraceShape(player, eyePos, endPos, mask, contents); diff --git a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs index d113a89..d8574c6 100644 --- a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs +++ b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs @@ -42,6 +42,7 @@ namespace src.player private static void OnMapStart(string mapName) { + skills.NoRecoil.ForgetSpread(); PlayerManager.SetServerActive(true); Instance.GameRules = null; Event.OnMapChange(); @@ -50,6 +51,8 @@ namespace src.player private static void OnMapEnd() { + skills.NoRecoil.RestoreSpread(); + skills.NoRecoil.ForgetSpread(); PerfLog.Info("===== MAP END (clean map change) ====="); Debug.WriteToDebug("===== MAP END (clean map change) ====="); BotManager.Stop(); diff --git a/jRandomSkills - SRC Files/src/player/RoundEvents.cs b/jRandomSkills - SRC Files/src/player/RoundEvents.cs index 5021177..58ce77d 100644 --- a/jRandomSkills - SRC Files/src/player/RoundEvents.cs +++ b/jRandomSkills - SRC Files/src/player/RoundEvents.cs @@ -7,7 +7,6 @@ using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.UserMessages; using CounterStrikeSharp.API.Modules.Utils; -using RayTraceAPI; using src.player.skills; using src.utils; using System.Collections.Concurrent; @@ -98,14 +97,14 @@ namespace src.player { lock (setLock) { - bool isWarmup = Instance.GameRules == null || Instance.GameRules.WarmupPeriod == true; + bool isWarmup = IsWarmupPeriod(); isTransmitRegistered = false; setSkillRetries = 0; SkillUtils.ClearKillCredits(); SkillUtils.ClearCurses(); Instance.AddTimer(.1f, () => DisableAll(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); - foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) + foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && InPlayingTeam(p))) { var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index); if (skillPlayer == null) continue; @@ -115,18 +114,21 @@ namespace src.player Instance.RemoveListener(CheckTransmit); int freezetime = SkillUtils.CvarValue("mp_freezetime", 0); - freezeTimeEnd = DateTime.Now.AddSeconds(freezetime + (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0)); + int introDelay = IsTeamIntroPeriod() ? 7 : 0; + freezeTimeEnd = DateTime.Now.AddSeconds(freezetime + introDelay); setSkillTimer?.Kill(); if (isWarmup) { setSkillTimer = Instance?.AddTimer(1f, SetSkill, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + Debug.WriteToDebug("RoundStart: warmup, SetSkill scheduled in 1.00s.", DebugCategory.Round); return HookResult.Continue; } - float timeToDraw = (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f; + float timeToDraw = introDelay + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f; setSkillTimer = Instance?.AddTimer(timeToDraw, SetSkill, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + Debug.WriteToDebug($"RoundStart: SetSkill scheduled in {timeToDraw:F2}s (freezetime={freezetime}, intro={introDelay}, timer={(setSkillTimer == null ? "null" : "ok")}).", DebugCategory.Round); return HookResult.Continue; } } @@ -293,7 +295,22 @@ namespace src.player private static void SetSkill() { long perfStart = PerfLog.Start(); - SetSkillCore(); + + try + { + SetSkillCore(); + } + catch (Exception ex) + { + Debug.WriteToDebug($"SetSkill threw: {ex}", DebugCategory.Skill); + + if (setSkillRetries < MaxSetSkillRetries) + { + setSkillRetries++; + setSkillTimer = Instance?.AddTimer(.5f, SetSkill, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); + } + } + PerfLog.End("SetSkill total", perfStart, 2.0); } @@ -472,10 +489,46 @@ namespace src.player private static int CountConnectedPlayers() { - try { return Utilities.GetPlayers().Count(p => p != null && p.IsValid && !p.IsHLTV); } + try + { + return Utilities.GetPlayers().Count(p => + { + if (p == null || !p.IsValid || p.IsHLTV) return false; + var pawn = p.PlayerPawn?.Value; + return pawn != null && pawn.IsValid; + }); + } catch { return 0; } } + private static bool InPlayingTeam(CCSPlayerController player) + { + try { return player.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist; } + catch { return false; } + } + + private static bool IsWarmupPeriod() + { + try + { + var gameRules = Instance?.GameRules; + if (gameRules == null || gameRules.Handle == IntPtr.Zero) return true; + return gameRules.WarmupPeriod; + } + catch { return true; } + } + + private static bool IsTeamIntroPeriod() + { + try + { + var gameRules = Instance?.GameRules; + if (gameRules == null || gameRules.Handle == IntPtr.Zero) return false; + return gameRules.TeamIntroPeriod; + } + catch { return false; } + } + private static void SetSkillCore() { setSkillTimer = null; @@ -484,7 +537,7 @@ namespace src.player if (Instance == null) return; // GameRules null = not ready; keep polling so skills land right after warmup ends. - if (Instance.GameRules == null || Instance.GameRules.WarmupPeriod == true) + if (IsWarmupPeriod()) { if (++gameRulesPolls % 10 == 0) Debug.WriteToDebug($"SetSkill waiting: gameRules={(Instance.GameRules == null ? "null" : "warmup")}, poll {gameRulesPolls}.", DebugCategory.Skill); diff --git a/jRandomSkills - SRC Files/src/player/skills/Cypher.cs b/jRandomSkills - SRC Files/src/player/skills/Cypher.cs index 152f113..df75b2b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Cypher.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Cypher.cs @@ -4,7 +4,6 @@ using CounterStrikeSharp.API.Modules.Commands.Targeting; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Utils; -using RayTraceAPI; using src.utils; using System.Collections.Concurrent; using System.Drawing; @@ -341,7 +340,7 @@ namespace src.player.skills Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + playerPawn.ViewOffset.Z); Vector endPos = eyePos + SkillUtils.GetForwardVector(playerPawn.V_angle) * 4096f; - ulong mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Window | InteractionLayers.PassBullets); + ulong mask = (ulong)(Contents.Solid | Contents.Window | Contents.PassBullets); var result = RayTrace.TraceShape(player, eyePos, endPos, mask); if (result.HasValue && result.Value.HitWorld(out _)) @@ -370,7 +369,7 @@ namespace src.player.skills Vector endPos = cameraVector + SkillUtils.GetForwardVector(new QAngle(0, playerPawn.V_angle.Y + 180, 0)) * -5; cameraVector += SkillUtils.GetForwardVector(new QAngle(0, playerPawn.V_angle.Y + 180, 0)) * 5; - ulong mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Window | InteractionLayers.PassBullets); + ulong mask = (ulong)(Contents.Solid | Contents.Window | Contents.PassBullets); var result = RayTrace.TraceShape(player, cameraVector, endPos, mask); if (result.HasValue && result.Value.HitWorld(out _)) diff --git a/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs b/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs index a46fa4e..a0661ab 100644 --- a/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs +++ b/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs @@ -29,10 +29,16 @@ namespace src.player.skills } public static void BombPlanted(EventBombPlanted _) + { + plantedC4 = FindPlantedC4(); + } + + private static Vector? FindPlantedC4() { var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); - if (plantedBomb == null || !plantedBomb.IsValid || plantedBomb.AbsOrigin == null) return; - plantedC4 = new(plantedBomb.AbsOrigin.X, plantedBomb.AbsOrigin.Y, plantedBomb.AbsOrigin.Z); + if (plantedBomb == null || !plantedBomb.IsValid || plantedBomb.AbsOrigin == null) return null; + if (!plantedBomb.BombTicking || plantedBomb.BombDefused) return null; + return new(plantedBomb.AbsOrigin.X, plantedBomb.AbsOrigin.Y, plantedBomb.AbsOrigin.Z); } private static void RemoveBomb() @@ -49,14 +55,21 @@ namespace src.player.skills if (lastTick == Server.TickCount) return; var player = PlayerManager.GetPlayerEvent(@event.Userid); - if (player == null || !player.IsValid || plantedC4 == null) return; - - var pos = new Vector(@event.X, @event.Y, @event.Z); + if (player == null || !player.IsValid) return; var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); if (playerInfo == null || playerInfo.Skill != skillName) return; - if (SkillUtils.Distance(plantedC4, pos) >= 8) + plantedC4 ??= FindPlantedC4(); + if (plantedC4 == null) return; + + var pawn = player.PlayerPawn.Value; + if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; + + var eyePos = new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z); + var impactPos = new Vector(@event.X, @event.Y, @event.Z); + + if (DistanceToSegment(plantedC4, eyePos, impactPos) >= 8) return; lastTick = Server.TickCount; @@ -71,6 +84,16 @@ namespace src.player.skills Localization.PrintTranslationToChatAll($" {ChatColors.Gold}{{0}}: {ChatColors.Red}{bombHealth}{ChatColors.Gold}/{ChatColors.Green}{maxBombHealth}", ["fragilebomb_bomb_health"]); } + private static float DistanceToSegment(Vector point, Vector start, Vector end) + { + float lineX = end.X - start.X, lineY = end.Y - start.Y, lineZ = end.Z - start.Z; + float lengthSquared = lineX * lineX + lineY * lineY + lineZ * lineZ; + float t = lengthSquared <= .0001f ? 0f : Math.Clamp(((point.X - start.X) * lineX + (point.Y - start.Y) * lineY + (point.Z - start.Z) * lineZ) / lengthSquared, 0f, 1f); + + float dx = start.X + lineX * t - point.X, dy = start.Y + lineY * t - point.Y, dz = start.Z + lineZ * t - point.Z; + return MathF.Sqrt(dx * dx + dy * dy + dz * dz); + } + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 1, Rarity rarity = Rarity.Common, int maxBombHealth = 1000) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity) { public int MaxBombHealth { get; set; } = maxBombHealth; diff --git a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs index a15c9df..049314b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs +++ b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs @@ -15,6 +15,7 @@ namespace src.player.skills private const string victimSound = "Player.DamageBody.Victim"; private const string heavyHitSound = "Weapon_Knife.Hit.Heavy.Flesh"; private const string lightHitSound = "Weapon_Knife.Hit.Light.Flesh"; + private const string tracerParticle = "particles/weapons/cs_weapon_fx/weapon_tracers_rifle_wisp.vpcf"; private static bool hooked = false; private const int actionCode = 503; @@ -30,6 +31,7 @@ namespace src.player.skills public static void LoadSkill() { SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); + Instance.AddToManifest(tracerParticle); } public static void NewRound() @@ -113,6 +115,9 @@ namespace src.player.skills if (result == null || !result.HasValue) return; + if (result.Value.Distance() > 70) + SkillUtils.CreateTracer(player, tracerParticle, result.Value); + if (!result.Value.HitPlayer(out CCSPlayerController? target) || target == null) return; diff --git a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs index 60f1efb..56f5dca 100644 --- a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs +++ b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs @@ -10,10 +10,12 @@ namespace src.player.skills public class LongZeus : ISkill { private const Skills skillName = Skills.LongZeus; + private const string shockParticle = "particles/blood_impact/impact_taser_bodyfx.vpcf"; public static void LoadSkill() { SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); + Instance.AddToManifest(shockParticle); } public unsafe static void WeaponFire(EventWeaponFire @event) @@ -40,7 +42,12 @@ namespace src.player.skills if (target.Handle == player.Handle) return; if (!SkillsInfo.GetValue(skillName, "friendlyFire") && player.Team == target.Team) return; - SkillUtils.TakeHealth(target.PlayerPawn.Value, 9999, player, KillfeedIcons.Taser); + var targetPawn = target.PlayerPawn.Value; + if (targetPawn == null || !targetPawn.IsValid) return; + + EntityManager.CreateEntityParticle(player.Index, shockParticle, targetPawn); + SkillUtils.RegisterNativeKill(targetPawn, pawn, activeWeapon, DamageTypes_t.DMG_SHOCK); + SkillUtils.TakeHealth(targetPawn, 9999); } public static void EnableSkill(CCSPlayerController player) diff --git a/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs b/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs index f36f62c..ac5e5c1 100644 --- a/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs +++ b/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs @@ -17,6 +17,27 @@ namespace src.player.skills private static readonly ConcurrentDictionary holders = []; private static readonly ConcurrentDictionary originalNoSpreadValues = []; + private sealed class SpreadPatch(CCSWeaponBaseVData vdata) + { + public readonly CCSWeaponBaseVData VData = vdata; + public readonly CFiringModeFloat[] Fields = + [ + vdata.Spread, vdata.InaccuracyCrouch, vdata.InaccuracyStand, vdata.InaccuracyJump, + vdata.InaccuracyLand, vdata.InaccuracyLadder, vdata.InaccuracyFire, vdata.InaccuracyMove + ]; + public readonly float[] Values = new float[16]; + public int Count; + public float JumpInitial; + public float JumpApex; + public float Reload; + public bool Active; + } + + private static readonly Dictionary spreadPatches = []; + private static readonly List activePatches = []; + private static readonly Dictionary wantedVData = []; + private static readonly HashSet blockedVData = []; + public static void LoadSkill() { SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); @@ -83,6 +104,106 @@ namespace src.player.skills catch { } } + public static void OnTick() + { + if (holders.IsEmpty) return; + + wantedVData.Clear(); + blockedVData.Clear(); + + foreach (var player in PlayerManager.GetTickPlayers()) + { + if (player == null || !player.IsValid || !player.PawnIsAlive) continue; + + var vdata = GetActiveWeaponVData(player); + if (vdata == null) continue; + + bool isHolder = holders.ContainsKey(player.Index) && PlayerManager.GetPlayerByIndex(player.Index)?.Skill == skillName; + if (isHolder) + wantedVData[vdata.Handle] = vdata; + else + blockedVData.Add(vdata.Handle); + } + + foreach (var (handle, vdata) in wantedVData) + { + if (!blockedVData.Contains(handle)) + PatchSpread(vdata); + } + } + + private static CCSWeaponBaseVData? GetActiveWeaponVData(CCSPlayerController player) + { + var weapon = player.PlayerPawn.Value?.WeaponServices?.ActiveWeapon.Value; + if (weapon == null || !weapon.IsValid) return null; + + var vdata = weapon.As().VData; + return vdata == null || vdata.Handle == IntPtr.Zero ? null : vdata; + } + + private static void PatchSpread(CCSWeaponBaseVData vdata) + { + if (!spreadPatches.TryGetValue(vdata.Handle, out var patch)) + { + patch = new SpreadPatch(vdata); + spreadPatches[vdata.Handle] = patch; + } + + if (patch.Active) return; + + int index = 0; + foreach (var field in patch.Fields) + { + var values = field.Values; + for (int i = 0; i < values.Length && index < patch.Values.Length; i++) + { + patch.Values[index++] = values[i]; + values[i] = 0f; + } + } + + patch.Count = index; + patch.JumpInitial = vdata.InaccuracyJumpInitial; + patch.JumpApex = vdata.InaccuracyJumpApex; + patch.Reload = vdata.InaccuracyReload; + + vdata.InaccuracyJumpInitial = 0f; + vdata.InaccuracyJumpApex = 0f; + vdata.InaccuracyReload = 0f; + + patch.Active = true; + activePatches.Add(patch); + } + + public static void RestoreSpread() + { + if (activePatches.Count == 0) return; + + foreach (var patch in activePatches) + { + int index = 0; + foreach (var field in patch.Fields) + { + var values = field.Values; + for (int i = 0; i < values.Length && index < patch.Count; i++) + values[i] = patch.Values[index++]; + } + + patch.VData.InaccuracyJumpInitial = patch.JumpInitial; + patch.VData.InaccuracyJumpApex = patch.JumpApex; + patch.VData.InaccuracyReload = patch.Reload; + patch.Active = false; + } + + activePatches.Clear(); + } + + public static void ForgetSpread() + { + activePatches.Clear(); + spreadPatches.Clear(); + } + public static void WeaponFire(EventWeaponFire @event) { var player = PlayerManager.GetPlayerEvent(@event.Userid); diff --git a/jRandomSkills - SRC Files/src/player/skills/Ricochet.cs b/jRandomSkills - SRC Files/src/player/skills/Ricochet.cs index 1982f5f..7a47467 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Ricochet.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Ricochet.cs @@ -1,8 +1,7 @@ -using CounterStrikeSharp.API; +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.utils; -using RayTraceAPI; using src.utils; using System.Collections.Concurrent; using System.Drawing; @@ -22,7 +21,7 @@ namespace src.player.skills private static readonly List flights = []; private static readonly object flightLock = new(); private static readonly Color tracerColor = Color.FromArgb(170, 255, 226, 140); - private static readonly ulong worldOnlyMask = (ulong)InteractionLayers.MASK_WORLD_ONLY; + private static readonly ulong worldOnlyMask = RayTrace.WorldOnlyMask; public static void LoadSkill() { diff --git a/jRandomSkills - SRC Files/src/player/skills/Tripwire.cs b/jRandomSkills - SRC Files/src/player/skills/Tripwire.cs index 7fc5f34..8a0846a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Tripwire.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Tripwire.cs @@ -1,7 +1,6 @@ -using CounterStrikeSharp.API; +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; -using RayTraceAPI; using src.utils; using System.Collections.Concurrent; using System.Drawing; @@ -104,19 +103,7 @@ namespace src.player.skills private static void DestroyWire(uint beamIndex) { - var beam = Utilities.GetEntityFromIndex((int)beamIndex); - if (beam != null && beam.IsValid) - { - beam.Width = 0; - beam.EndWidth = 0; - beam.Render = Color.FromArgb(0, 0, 0, 0); - - Utilities.SetStateChanged(beam, "CBeam", "m_fWidth"); - Utilities.SetStateChanged(beam, "CBeam", "m_fEndWidth"); - Utilities.SetStateChanged(beam, "CBaseModelEntity", "m_clrRender"); - } - - EntityManager.DestroyEntity(beamIndex); + EntityManager.DestroyBeam(beamIndex); } public static void UseSkill(CCSPlayerController player) @@ -175,7 +162,7 @@ namespace src.player.skills Vector rightDir = SkillUtils.GetForwardVector(new QAngle(0, yaw - 90, 0)); Vector leftDir = SkillUtils.GetForwardVector(new QAngle(0, yaw + 90, 0)); - ulong wallMask = (ulong)InteractionLayers.MASK_WORLD_ONLY; + ulong wallMask = RayTrace.WorldOnlyMask; var rightHit = RayTrace.TraceShape(player, origin, origin + rightDir * maxDistance, wallMask, 0); var leftHit = RayTrace.TraceShape(player, origin, origin + leftDir * maxDistance, wallMask, 0); diff --git a/jRandomSkills - SRC Files/src/utils/CustomTraceResult.cs b/jRandomSkills - SRC Files/src/utils/CustomTraceResult.cs index 85ea933..9ffd2b7 100644 --- a/jRandomSkills - SRC Files/src/utils/CustomTraceResult.cs +++ b/jRandomSkills - SRC Files/src/utils/CustomTraceResult.cs @@ -1,30 +1,55 @@ -using RayTraceAPI; +using CounterStrikeSharp.API.Modules.Utils; using System.Numerics; using Vector = CounterStrikeSharp.API.Modules.Utils.Vector; namespace jRandomSkills.src.utils { - public struct CustomTraceResult(TraceResult result, Vector startPos, ulong mask, ulong contents, bool drawBeam) + public struct CustomTraceResult { - public float StartPosX = startPos.X; - public float StartPosY = startPos.Y; - public float StartPosZ = startPos.Z; + public float StartPosX; + public float StartPosY; + public float StartPosZ; - public float EndPosX = result.EndPosX; - public float EndPosY = result.EndPosY; - public float EndPosZ = result.EndPosZ; + public float EndPosX; + public float EndPosY; + public float EndPosZ; - public nint HitEntity = result.HitEntity; - public float Fraction = result.Fraction; - public int AllSolid = result.AllSolid; + public nint HitEntity; + public float Fraction; + public int AllSolid; - public float NormalX = result.NormalX; - public float NormalY = result.NormalY; - public float NormalZ = result.NormalZ; + public float NormalX; + public float NormalY; + public float NormalZ; - public ulong InteractsWith = mask; - public ulong InteractsExclude = contents; - public bool DrawBeam = drawBeam; + public ulong InteractsWith; + public ulong InteractsExclude; + public bool DrawBeam; + + public CustomTraceResult(TraceResult result, Vector startPos, ulong mask, ulong contents, bool drawBeam) + { + StartPosX = startPos.X; + StartPosY = startPos.Y; + StartPosZ = startPos.Z; + + var end = result.EndPos; + EndPosX = end.X; + EndPosY = end.Y; + EndPosZ = end.Z; + + var normal = result.Normal; + NormalX = normal.X; + NormalY = normal.Y; + NormalZ = normal.Z; + + HitEntity = result.HitEntity().Handle; + Fraction = result.Fraction; + AllSolid = result.IsAllSolid ? 1 : 0; + + InteractsWith = mask; + InteractsExclude = contents; + DrawBeam = drawBeam; + } public readonly Vector3 StartPos => new(StartPosX, StartPosY, StartPosZ); public readonly Vector3 EndPos => new(EndPosX, EndPosY, EndPosZ); diff --git a/jRandomSkills - SRC Files/src/utils/EntityManager.cs b/jRandomSkills - SRC Files/src/utils/EntityManager.cs index ec57874..fc13d50 100644 --- a/jRandomSkills - SRC Files/src/utils/EntityManager.cs +++ b/jRandomSkills - SRC Files/src/utils/EntityManager.cs @@ -1,10 +1,12 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Entities.Constants; +using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Utils; using src.player; using System.Collections.Concurrent; using System.Drawing; +using System.Runtime.InteropServices; using static src.jRandomSkills; namespace src.utils @@ -136,6 +138,67 @@ namespace src.utils } } + public static CParticleSystem? CreateTracer(uint playerIndex, string particleName, Vector start, Vector end, float lifetime = 1f) + { + try + { + if (OverBudget()) return null; + var particle = Utilities.CreateEntityByName("info_particle_system"); + if (particle == null || !particle.IsValid) return null; + + particle.EffectName = particleName; + particle.StartActive = true; + particle.Teleport(start); + + var controlPoint = new Vector(particle.Handle + Schema.GetSchemaOffset("CParticleSystem", "m_vServerControlPoints")); + controlPoint.X = end.X; + controlPoint.Y = end.Y; + controlPoint.Z = end.Z; + particle.ServerControlPointAssignments[0] = 1; + + particle.DispatchSpawn(); + + RegisterEntity(particle.Index, playerIndex, "tracer"); + ScheduleAutoDestroy(particle.Index, lifetime); + return particle; + } + catch (Exception ex) + { + LogEntityError($"CreateTracer: {ex.Message}"); + return null; + } + } + + public static CParticleSystem? CreateEntityParticle(uint playerIndex, string particleName, CBaseEntity target, float lifetime = 5f) + { + try + { + if (OverBudget() || target.AbsOrigin == null) return null; + var particle = Utilities.CreateEntityByName("info_particle_system"); + if (particle == null || !particle.IsValid) return null; + + particle.EffectName = particleName; + particle.StartActive = true; + particle.Teleport(target.AbsOrigin); + + nint controlPointEnts = particle.Handle + Schema.GetSchemaOffset("CParticleSystem", "m_hControlPointEnts"); + Marshal.WriteInt32(controlPointEnts, (int)target.EntityHandle.Raw); + Marshal.WriteInt32(controlPointEnts + 4, (int)target.EntityHandle.Raw); + + particle.DispatchSpawn(); + particle.AcceptInput("SetParent", target, particle, "!activator"); + + RegisterEntity(particle.Index, playerIndex, "particle_system"); + ScheduleAutoDestroy(particle.Index, lifetime); + return particle; + } + catch (Exception ex) + { + LogEntityError($"CreateEntityParticle: {ex.Message}"); + return null; + } + } + public static CDynamicProp? CreateTrackedDynamicProp(uint playerIndex, string designerName = "prop_dynamic", string? trackAs = null) { try @@ -295,7 +358,7 @@ namespace src.utils public static bool SuppressKills = false; - public static bool DestroyEntity(uint entityIndex, float delay = 0.1f) + public static bool DestroyEntity(uint entityIndex, float delay = 0.1f, bool hideFromTransmit = true) { bool wasTracked = trackedEntities.TryRemove(entityIndex, out var removed); @@ -310,7 +373,8 @@ namespace src.utils var entity = Utilities.GetEntityFromIndex((int)entityIndex); if (entity != null && entity.IsValid) { - recentlyDestroyed[entityIndex] = new DyingEntity(DateTime.UtcNow.AddSeconds(delay + 0.5), entity.EntityHandle.Raw); + if (hideFromTransmit) + recentlyDestroyed[entityIndex] = new DyingEntity(DateTime.UtcNow.AddSeconds(delay + 0.5), entity.EntityHandle.Raw); // Detach first so no follower is left on a freed parent. entity.AcceptInput("ClearParent"); entity.AddEntityIOEvent("Kill", entity, delay: delay); @@ -346,7 +410,7 @@ namespace src.utils LogEntityError($"DestroyBeam {entityIndex}: {ex.Message}"); } - bool killed = DestroyEntity(entityIndex); + bool killed = DestroyEntity(entityIndex, hideFromTransmit: false); if (!SuppressKills) Server.NextFrame(() => diff --git a/jRandomSkills - SRC Files/src/utils/RayTrace.cs b/jRandomSkills - SRC Files/src/utils/RayTrace.cs index 92f314f..8f427d4 100644 --- a/jRandomSkills - SRC Files/src/utils/RayTrace.cs +++ b/jRandomSkills - SRC Files/src/utils/RayTrace.cs @@ -1,45 +1,44 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Core.Capabilities; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.utils; -using RayTraceAPI; using System.Drawing; using System.Numerics; -using TraceOptions = RayTraceAPI.TraceOptions; -using TraceResult = RayTraceAPI.TraceResult; using Vector = CounterStrikeSharp.API.Modules.Utils.Vector; namespace src.utils { public static class RayTrace { - private static PluginCapability RayTraceInterface { get; } = new("raytrace:craytraceinterface"); + public const ulong WorldOnlyMask = (ulong)(Contents.Solid | Contents.Window | Contents.PassBullets); - private static bool missingModuleLogged; + private static bool traceFailureLogged; - private static CRayTraceInterface? GetInterface() + public static bool IsAvailable => true; + + private static bool TryTraceHull(Vector startPos, Vector endPos, Vector mins, Vector maxs, CBaseEntity? ignore, ulong mask, ulong contents, out TraceResult result) { try { - var rayTrace = RayTraceInterface.Get(); - if (rayTrace != null) return rayTrace; + result = Trace.TraceHullShape(startPos, endPos, mins, maxs, ignore, new TraceOptions + { + InteractsWith = (Contents)mask, + InteractsExclude = (Contents)contents, + }); + return true; } - catch { } - - if (!missingModuleLogged) + catch (Exception ex) { - missingModuleLogged = true; - Server.PrintToConsole("[jRandomSkills] RayTrace module not found - skills that need it do nothing: " + - "LongZeus, LongKnife, Iana, Cypher, Noclip, Shade (and the skill-use button's aim check). " + - "Install RayTrace-CSS-API and RayTrace-MM: https://github.com/FUNPLAY-pro-CS2/Ray-Trace/releases"); + result = default; + if (!traceFailureLogged) + { + traceFailureLogged = true; + Server.PrintToConsole($"[jRandomSkills] Native trace failed: {ex.Message}"); + } + return false; } - - return null; } - public static bool IsAvailable => GetInterface() != null; - public static CustomTraceResult? TraceShape(CCSPlayerController player, Vector startPos, Vector endPos, ulong? mask = null, ulong? contents = null) { if (player == null || !player.IsValid) return null; @@ -53,54 +52,39 @@ namespace src.utils playerPawn.CBodyComponent?.SceneNode == null) return null; - var rayTrace = GetInterface(); - if (rayTrace == null) - return null; - if (mask == null) { try { if (playerPawn.Collision?.CollisionAttribute != null) { - mask = playerPawn.Collision.CollisionAttribute.InteractsWith | (ulong)InteractionLayers.Hitboxes; - mask &= ~(ulong)InteractionLayers.PlayerClip; + mask = playerPawn.Collision.CollisionAttribute.InteractsWith | (ulong)Contents.Hitbox; + mask &= ~(ulong)Contents.PlayerClip; } else - mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Hitboxes); + mask = (ulong)(Contents.Solid | Contents.Hitbox); } catch { - mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Hitboxes); + mask = (ulong)(Contents.Solid | Contents.Hitbox); } } contents ??= 0; bool drawBeam = Config.LoadedConfig.TraceRayBeam; - TraceOptions options = new() - { - InteractsWith = (ulong)mask, - InteractsExclude = (ulong)contents, - DrawBeam = drawBeam == true ? 1 : 0, - }; - Vector mins = new(-0.5f, -0.5f, -0.5f); Vector maxs = new(0.5f, 0.5f, 0.5f); - TraceResult result = default; - - try - { - rayTrace.TraceHullShape(startPos, endPos, mins, maxs, playerPawn, options, out result); - } - catch (Exception ex) - { - Console.WriteLine($"[jRandomSkills] A memory error was caught during RayTrace: {ex.Message}"); + if (!TryTraceHull(startPos, endPos, mins, maxs, playerPawn, (ulong)mask, (ulong)contents, out var result)) return null; - } - return new CustomTraceResult(result, startPos, (ulong)mask, (ulong)contents, drawBeam); + var traced = new CustomTraceResult(result, startPos, (ulong)mask, (ulong)contents, drawBeam); + + if (drawBeam) + CreateBeamLine(startPos, new Vector(traced.EndPosX, traced.EndPosY, traced.EndPosZ), traced.DidHit ? Color.Red : Color.Green); + + return traced; } public static CustomTraceResult? EyeTrace(CCSPlayerController player) @@ -136,10 +120,6 @@ namespace src.utils playerPawn.CBodyComponent?.SceneNode == null) return null; - var rayTrace = GetInterface(); - if (rayTrace == null) - return null; - Vector safeMins = mins ?? playerPawn.Collision.Mins; Vector safeMaxs = maxs ?? playerPawn.Collision.Maxs; @@ -148,26 +128,8 @@ namespace src.utils bool drawBeam = Config.LoadedConfig.TraceRayBeam; - TraceResult result = default; - TraceOptions options = new() - { - InteractsWith = safeMask, - InteractsExclude = safeContents, - DrawBeam = drawBeam == true ? 1 : 0, - }; - - CEntityInstance? entityToIgnore = (playerPawn.LifeState == (byte)LifeState_t.LIFE_ALIVE) - ? playerPawn - : null; - - try - { - rayTrace.TraceHullShape(startPos, endPos, safeMins, safeMaxs, entityToIgnore, options, out result); - } - catch (Exception) - { + if (!TryTraceHull(startPos, endPos, safeMins, safeMaxs, playerPawn, safeMask, safeContents, out var result)) return null; - } if (drawBeam) { @@ -260,6 +222,12 @@ namespace src.utils public static bool HitEntityByDesignerName(this CustomTraceResult result, out T? entity, string designerName, DesignerNameMatchType matchType = DesignerNameMatchType.Equals) where T : CEntityInstance { + if (result.HitEntity == IntPtr.Zero) + { + entity = null; + return false; + } + T? val = (T?)Activator.CreateInstance(typeof(T), result.HitEntity); if ((object?)val != null && matchType switch { @@ -279,6 +247,12 @@ namespace src.utils public static bool HitEntity(this CustomTraceResult result, out CBaseEntity? entity) { + if (result.HitEntity == IntPtr.Zero) + { + entity = null; + return false; + } + CEntityInstance entityInstance = new(result.HitEntity); if (string.IsNullOrEmpty(entityInstance.DesignerName)) { diff --git a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs index bff7c21..5f65b63 100644 --- a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs +++ b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs @@ -482,9 +482,48 @@ namespace src.utils return true; } + public static void CreateTracer(CCSPlayerController player, string particleName, CustomTraceResult result) + { + var pawn = player.PlayerPawn.Value; + if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; + + Vector forward = GetForwardVector(pawn.EyeAngles); + Vector start = new(pawn.AbsOrigin.X + forward.X * 16, pawn.AbsOrigin.Y + forward.Y * 16, pawn.AbsOrigin.Z + pawn.ViewOffset.Z - 6); + Vector end = new(result.EndPos.X, result.EndPos.Y, result.EndPos.Z); + + EntityManager.CreateTracer(player.Index, particleName, start, end); + } + public static void ClearKillCredits() { pendingKillCredits.Clear(); + pendingNativeKills.Clear(); + } + + private static readonly ConcurrentDictionary pendingNativeKills = []; + + public static void RegisterNativeKill(CCSPlayerPawn victimPawn, CBaseEntity attacker, CBaseEntity inflictor, DamageTypes_t damageType) + { + pendingNativeKills[victimPawn.Index] = (attacker.EntityHandle.Raw, inflictor.EntityHandle.Raw, damageType, Server.TickCount + 64); + } + + public static void ApplyNativeKill(CEntityInstance victim, CTakeDamageInfo info) + { + if (pendingNativeKills.IsEmpty) return; + if (!pendingNativeKills.TryGetValue(victim.Index, out var kill)) return; + + if (kill.ExpiryTick < Server.TickCount) + { + pendingNativeKills.TryRemove(victim.Index, out _); + return; + } + + if (info.Attacker.Value?.Handle != victim.Handle) return; + + pendingNativeKills.TryRemove(victim.Index, out _); + info.Attacker.Raw = kill.AttackerHandle; + info.Inflictor.Raw = kill.InflictorHandle; + info.BitsDamageType = kill.DamageType; } private static readonly HashSet bulletWeapons = new(StringComparer.Ordinal) diff --git a/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json b/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json index bd817d6..0c2c147 100644 --- a/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json +++ b/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json @@ -3,20 +3,20 @@ "signatures": { "library": "server", "windows": "48 8B C4 48 89 58 ? 48 89 68 ? 48 89 70 ? 57 41 56 41 57 48 81 EC ? ? ? ? 48 8B B4 24 ? ? ? ? 4D 8B F8", - "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 45 89 CE 41 55 4D 89 C5 41 54 53 48 83 EC ? 48 89 55 ? 48 89 F2 48 89 FE" + "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 45 89 CE 41 55 4D 89 C5 41 54 53 48 81 EC ? ? ? ? 48 89 95 ? ? ? ? 48 89 F2 48 89 FE 48 8D 3D" } }, "HEGrenadeProjectile_CreateFunc": { "signatures": { "library": "server", - "windows": "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B 6C 24 ? 49 8B F8 4C 8B C2 0F 29 74 24 ? 48 8B D1 48 8B D9 48 8D 0D ? ? ? ? 4C 8B CD E8 ? ? ? ? F3 0F 10 0D ? ? ? ? 48 8B C8 48 8B F0 E8 ? ? ? ? 48 8B D7 48 8B CE", + "windows": "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B AC 24 ? ? ? ? 49 8B F8 4C 8B C2 0F 29 74 24 ? 48 8B D1 0F 29 7C 24 ? 48 8B D9 4C 8B CD 48 8D 0D ? ? ? ? E8", "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 49 89 D6 48 89 F2 48 89 FE 41 55 48 8D 3D ? ? ? ? 4D 89 C5 41 54 45 89 CC 53" } }, "CMolotovProjectile_CreateFunc": { "signatures": { "library": "server", - "windows": "48 8B C4 48 89 58 10 4C 89 40 18 48 89 48 08", + "windows": "48 8B C4 48 89 58 08 48 89 70 10 48 89 78 20 4C 89 40 18 55 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 45 33 FF", "linux": "55 48 8D 05 ? ? ? ? 48 89 E5 41 57 41 56 41 55 41 54 49 89 FC 53 48 81 EC ? ? ? ? 4C 8D 35" } }, @@ -30,7 +30,7 @@ "SnapViewAngles": { "signatures": { "library": "server", - "windows": "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B DA 48 8B F1 48 8D 55", + "windows": "48 89 7C 24 ? 55 48 8B EC 48 81 EC ? ? ? ? 48 8B F9 48 8D 4D ? E8 ? ? ? ? F2 0F 10 87 ? ? ? ? 48 8B CF", "linux": "55 48 89 E5 41 57 49 89 FF 48 89 F7 41 56 41 55 41 54 53 48 81 EC ? ? ? ? E8" } }, @@ -42,8 +42,8 @@ }, "INetworkGameServer_Slots": { "offsets": { - "windows": 584, - "linux": 584 + "windows": 616, + "linux": 616 } }, "INetworkServerService_GetIGameServer": { diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll b/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll index ff1b24f..42c757f 100644 Binary files a/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll and b/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll differ diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll b/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll index 4dc173f..771da85 100644 Binary files a/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll and b/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll differ