mirror of
https://github.com/daffyyyy/CS2-SimpleAdmin.git
synced 2026-09-27 20:17:04 +02:00
fix: Fix potential vector & qangle leaks
This commit is contained in:
parent
7ac2f873a7
commit
a758b9a7a7
7 changed files with 299 additions and 16 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -88,7 +88,7 @@ jobs:
|
|||
with:
|
||||
artifacts: "${{ env.PROJECT_NAME_CS2_SIMPLEADMIN }}-${{ env.BUILD_NUMBER }}.zip"
|
||||
name: "CS2-SimpleAdmin - Build ${{ env.BUILD_NUMBER }}"
|
||||
tag: "build-${{ env.BUILD_NUMBER }}"
|
||||
tag: "fork-build-${{ env.BUILD_NUMBER }}-${{ github.run_id }}"
|
||||
body: |
|
||||
Place files in addons/counterstrikesharp
|
||||
After first launch, configure the plugins in the respective configs:
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using CounterStrikeSharp.API.Modules.Commands;
|
|||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using FixVectorLeak;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using CounterStrikeSharp.API.Core.Translations;
|
|||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.ValveConstants.Protobuf;
|
||||
using FixVectorLeak;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
||||
|
|
@ -523,16 +524,16 @@ public partial class CS2_SimpleAdmin
|
|||
if (!PlayersInfo.ContainsKey(player.UserId.Value) || @event.Attacker == null)
|
||||
return HookResult.Continue;
|
||||
|
||||
var playerPosition = player.PlayerPawn.Value?.AbsOrigin;
|
||||
var playerRotation = player.PlayerPawn.Value?.AbsRotation;
|
||||
|
||||
var playerPosition = player.PlayerPawn.Value?.AbsOrigin?.ToVector_t();
|
||||
var playerRotation = player.PlayerPawn.Value?.AbsRotation?.ToQAngle_t();
|
||||
|
||||
PlayersInfo[player.UserId.Value].DiePosition = new DiePosition(
|
||||
new Vector(
|
||||
new Vector_t(
|
||||
playerPosition?.X ?? 0,
|
||||
playerPosition?.Y ?? 0,
|
||||
playerPosition?.Z ?? 0
|
||||
),
|
||||
new QAngle(
|
||||
new QAngle_t(
|
||||
playerRotation?.X ?? 0,
|
||||
playerRotation?.Y ?? 0,
|
||||
playerRotation?.Z ?? 0
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using CounterStrikeSharp.API.Modules.Memory;
|
|||
using Microsoft.Extensions.Localization;
|
||||
using System.Text;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
||||
using FixVectorLeak;
|
||||
|
||||
namespace CS2_SimpleAdmin;
|
||||
|
||||
|
|
@ -87,18 +87,18 @@ public static class PlayerExtensions
|
|||
|
||||
public static void Bury(this CBasePlayerPawn pawn, float depth = 10f)
|
||||
{
|
||||
var newPos = new Vector(pawn.AbsOrigin!.X, pawn.AbsOrigin.Y,
|
||||
var newPos = new Vector_t(pawn.AbsOrigin!.X, pawn.AbsOrigin.Y,
|
||||
pawn.AbsOrigin!.Z - depth);
|
||||
|
||||
pawn.Teleport(newPos, pawn.AbsRotation!, pawn.AbsVelocity);
|
||||
pawn.Teleport(newPos, pawn.AbsRotation!.ToQAngle_t(), pawn.AbsVelocity.ToVector_t());
|
||||
}
|
||||
|
||||
public static void Unbury(this CBasePlayerPawn pawn, float depth = 15f)
|
||||
{
|
||||
var newPos = new Vector(pawn.AbsOrigin!.X, pawn.AbsOrigin.Y,
|
||||
var newPos = new Vector_t(pawn.AbsOrigin!.X, pawn.AbsOrigin.Y,
|
||||
pawn.AbsOrigin!.Z + depth);
|
||||
|
||||
pawn.Teleport(newPos, pawn.AbsRotation!, pawn.AbsVelocity);
|
||||
pawn.Teleport(newPos, pawn.AbsRotation!.ToQAngle_t(), pawn.AbsVelocity.ToVector_t());
|
||||
}
|
||||
|
||||
public static void Freeze(this CBasePlayerPawn pawn)
|
||||
|
|
@ -186,7 +186,7 @@ public static class PlayerExtensions
|
|||
/* Teleport in a random direction - thank you, Mani!*/
|
||||
/* Thank you AM & al!*/
|
||||
var random = new Random();
|
||||
var vel = new Vector(pawn.AbsVelocity.X, pawn.AbsVelocity.Y, pawn.AbsVelocity.Z);
|
||||
var vel = new Vector_t(pawn.AbsVelocity.X, pawn.AbsVelocity.Y, pawn.AbsVelocity.Z);
|
||||
|
||||
vel.X += (random.Next(180) + 50) * (random.Next(2) == 1 ? -1 : 1);
|
||||
vel.Y += (random.Next(180) + 50) * (random.Next(2) == 1 ? -1 : 1);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<RootNamespace>CS2_SimpleAdminApi</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
280
CS2-SimpleAdminApi/Extensions/FixVectorLeak.cs
Normal file
280
CS2-SimpleAdminApi/Extensions/FixVectorLeak.cs
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Numerics;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace FixVectorLeak;
|
||||
|
||||
public struct Vector_t : IAdditionOperators<Vector_t, Vector_t, Vector_t>,
|
||||
ISubtractionOperators<Vector_t, Vector_t, Vector_t>,
|
||||
IMultiplyOperators<Vector_t, float, Vector_t>,
|
||||
IDivisionOperators<Vector_t, float, Vector_t>
|
||||
{
|
||||
public float X, Y, Z;
|
||||
|
||||
public const int SIZE = 3;
|
||||
|
||||
public unsafe float this[int i]
|
||||
{
|
||||
readonly get
|
||||
{
|
||||
if (i < 0 || i > SIZE)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
fixed (void* ptr = &this)
|
||||
{
|
||||
return Unsafe.Read<float>(Unsafe.Add<float>(ptr, i));
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (i < 0 || i > SIZE)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
fixed (void* ptr = &this)
|
||||
{
|
||||
Unsafe.Write(Unsafe.Add<float>(ptr, i), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector_t()
|
||||
{
|
||||
}
|
||||
|
||||
public unsafe Vector_t(nint ptr) : this(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef<float>((void*)ptr), SIZE))
|
||||
{
|
||||
}
|
||||
|
||||
public Vector_t(float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public Vector_t(ReadOnlySpan<float> values)
|
||||
{
|
||||
if (values.Length < SIZE)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(values));
|
||||
}
|
||||
|
||||
this = Unsafe.ReadUnaligned<Vector_t>(ref Unsafe.As<float, byte>(ref MemoryMarshal.GetReference(values)));
|
||||
}
|
||||
|
||||
public readonly float Length()
|
||||
{
|
||||
return (float)Math.Sqrt(X * X + Y * Y + Z * Z);
|
||||
}
|
||||
|
||||
public readonly float Length2D()
|
||||
{
|
||||
return (float)Math.Sqrt(X * X + Y * Y);
|
||||
}
|
||||
|
||||
public readonly bool IsZero(float tolerance = 0.0001f)
|
||||
{
|
||||
return Math.Abs(X) <= tolerance && Math.Abs(Y) <= tolerance && Math.Abs(Z) <= tolerance;
|
||||
}
|
||||
|
||||
public void Scale(float scale)
|
||||
{
|
||||
X *= scale;
|
||||
Y *= scale;
|
||||
Z *= scale;
|
||||
}
|
||||
|
||||
public readonly override string ToString()
|
||||
{
|
||||
return $"{X:n2} {Y:n2} {Z:n2}";
|
||||
}
|
||||
|
||||
public static Vector_t operator +(Vector_t a, Vector_t b)
|
||||
{
|
||||
return new Vector_t(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||
}
|
||||
|
||||
public static Vector_t operator -(Vector_t a, Vector_t b)
|
||||
{
|
||||
return new Vector_t(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||
}
|
||||
|
||||
public static Vector_t operator -(Vector_t a)
|
||||
{
|
||||
return new Vector_t(-a.X, -a.Y, -a.Z);
|
||||
}
|
||||
|
||||
public static Vector_t operator *(Vector_t a, float b)
|
||||
{
|
||||
return new Vector_t(a.X * b, a.Y * b, a.Z * b);
|
||||
}
|
||||
|
||||
public static Vector_t operator /(Vector_t a, float b)
|
||||
{
|
||||
return new Vector_t(a.X / b, a.Y / b, a.Z / b);
|
||||
}
|
||||
}
|
||||
|
||||
public struct QAngle_t : IAdditionOperators<QAngle_t, QAngle_t, QAngle_t>,
|
||||
ISubtractionOperators<QAngle_t, QAngle_t, QAngle_t>,
|
||||
IMultiplyOperators<QAngle_t, float, QAngle_t>,
|
||||
IDivisionOperators<QAngle_t, float, QAngle_t>
|
||||
{
|
||||
public float X, Y, Z;
|
||||
|
||||
public const int SIZE = 3;
|
||||
|
||||
public unsafe float this[int i]
|
||||
{
|
||||
readonly get
|
||||
{
|
||||
if (i < 0 || i > SIZE)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
fixed (void* ptr = &this)
|
||||
{
|
||||
return Unsafe.Read<float>(Unsafe.Add<float>(ptr, i));
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (i < 0 || i > SIZE)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
fixed (void* ptr = &this)
|
||||
{
|
||||
Unsafe.Write(Unsafe.Add<float>(ptr, i), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public QAngle_t()
|
||||
{
|
||||
}
|
||||
|
||||
public unsafe QAngle_t(nint ptr) : this(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef<float>((void*)ptr), SIZE))
|
||||
{
|
||||
}
|
||||
|
||||
public QAngle_t(float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public QAngle_t(ReadOnlySpan<float> values)
|
||||
{
|
||||
if (values.Length < SIZE)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(values));
|
||||
}
|
||||
|
||||
this = Unsafe.ReadUnaligned<QAngle_t>(ref Unsafe.As<float, byte>(ref MemoryMarshal.GetReference(values)));
|
||||
}
|
||||
|
||||
public unsafe (Vector_t fwd, Vector_t right, Vector_t up) AngleVectors()
|
||||
{
|
||||
Vector_t fwd = default, right = default, up = default;
|
||||
|
||||
nint pFwd = (nint)Unsafe.AsPointer(ref fwd);
|
||||
nint pRight = (nint)Unsafe.AsPointer(ref right);
|
||||
nint pUp = (nint)Unsafe.AsPointer(ref up);
|
||||
|
||||
fixed (void* ptr = &this)
|
||||
{
|
||||
NativeAPI.AngleVectors((nint)ptr, pFwd, pRight, pUp);
|
||||
}
|
||||
|
||||
return (fwd, right, up);
|
||||
}
|
||||
|
||||
public unsafe void AngleVectors(out Vector_t fwd, out Vector_t right, out Vector_t up)
|
||||
{
|
||||
fixed (void* ptr = &this, pFwd = &fwd, pRight = &right, pUp = &up)
|
||||
{
|
||||
NativeAPI.AngleVectors((nint)ptr, (nint)pFwd, (nint)pRight, (nint)pUp);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly override string ToString()
|
||||
{
|
||||
return $"{X:n2} {Y:n2} {Z:n2}";
|
||||
}
|
||||
|
||||
public static QAngle_t operator +(QAngle_t a, QAngle_t b)
|
||||
{
|
||||
return new QAngle_t(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||
}
|
||||
|
||||
public static QAngle_t operator -(QAngle_t a, QAngle_t b)
|
||||
{
|
||||
return new QAngle_t(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||
}
|
||||
|
||||
public static QAngle_t operator -(QAngle_t a)
|
||||
{
|
||||
return new QAngle_t(-a.X, -a.Y, -a.Z);
|
||||
}
|
||||
|
||||
public static QAngle_t operator *(QAngle_t a, float b)
|
||||
{
|
||||
return new QAngle_t(a.X * b, a.Y * b, a.Z * b);
|
||||
}
|
||||
|
||||
public static QAngle_t operator /(QAngle_t a, float b)
|
||||
{
|
||||
return new QAngle_t(a.X / b, a.Y / b, a.Z / b);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe static class Extensions
|
||||
{
|
||||
public static void Teleport(this CBaseEntity entity, Vector_t? position = null, QAngle_t? angles = null, Vector_t? velocity = null)
|
||||
{
|
||||
Guard.IsValidEntity(entity);
|
||||
|
||||
void* pPos = null, pAng = null, pVel = null;
|
||||
|
||||
// Structs are stored on the stack, GC should not break pointers.
|
||||
|
||||
if (position.HasValue)
|
||||
{
|
||||
var pos = position.Value; // Remove nullable wrapper
|
||||
pPos = &pos;
|
||||
}
|
||||
|
||||
if (angles.HasValue)
|
||||
{
|
||||
var ang = angles.Value;
|
||||
pAng = ∠
|
||||
}
|
||||
|
||||
if (velocity.HasValue)
|
||||
{
|
||||
var vel = velocity.Value;
|
||||
pVel = &vel;
|
||||
}
|
||||
|
||||
VirtualFunction.CreateVoid<IntPtr, IntPtr, IntPtr, IntPtr>(entity.Handle, GameData.GetOffset("CBaseEntity_Teleport"))(entity.Handle, (nint)pPos,
|
||||
(nint)pAng, (nint)pVel);
|
||||
}
|
||||
|
||||
public static (Vector_t fwd, Vector_t right, Vector_t up) AngleVectors(this QAngle vec) => vec.ToQAngle_t().AngleVectors();
|
||||
public static void AngleVectors(this QAngle vec, out Vector_t fwd, out Vector_t right, out Vector_t up) => vec.ToQAngle_t().AngleVectors(out fwd, out right, out up);
|
||||
|
||||
public static Vector_t ToVector_t(this CounterStrikeSharp.API.Modules.Utils.Vector vec) => new(vec.Handle);
|
||||
public static QAngle_t ToQAngle_t(this QAngle vec) => new(vec.Handle);
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using FixVectorLeak;
|
||||
|
||||
namespace CS2_SimpleAdminApi;
|
||||
|
||||
|
|
@ -30,8 +30,8 @@ public class PlayerInfo(
|
|||
public DiePosition? DiePosition { get; set; }
|
||||
}
|
||||
|
||||
public struct DiePosition(Vector position, QAngle angle)
|
||||
public struct DiePosition(Vector_t position, QAngle_t angle)
|
||||
{
|
||||
public Vector Position { get; set; } = position;
|
||||
public QAngle Angle { get; set; } = angle;
|
||||
public Vector_t Position { get; set; } = position;
|
||||
public QAngle_t Angle { get; set; } = angle;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue