roflmuffin / CounterStrikeSharp

CounterStrikeSharp allows you to write server plugins in C# for Counter-Strike 2/Source2/CS2

Home Page:https://docs.cssharp.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Make player-grabbing functions safer

zonical opened this issue · comments

I wanted to do this myself before I left for university, but I'll offer this task to someone else.

A lot of issues when developing plugins that manipulate players come down to not validating player controller and player pawn entities properly. We should be building these validity checks into the Utilities functions instead of writing wrapper libraries, which I have done in this case.

The minimum validity checks should be:

  • The player controller entity is valid
  • UserId and Slot
  • The player is fully connected to the server
  • The player is not HLTV (perhaps add a new function to get the HLTV player)
  • The active pawn (spectator or player) is valid

I'm wondering if we can re-purpose the TargetType from the target module for this, where the user can supply their own simplistic filter; where most cases are covered by GroupHumans.

switch (targetType)
{
    case TargetType.TeamCt:
        return TeamNum == (byte)CsTeam.CounterTerrorist;
    case TargetType.TeamT:
        return TeamNum == (byte)CsTeam.Terrorist;
    case TargetType.TeamSpec:
        return TeamNum == (byte)CsTeam.Spectator;
    case TargetType.GroupAll:
        return !IsHLTV;
    case TargetType.GroupBots:
        return IsBot;
    case TargetType.GroupHumans:
        return !IsBot && !IsHLTV;
    case TargetType.GroupAlive:
        return PlayerPawn is { IsValid: true, Value.LifeState: (byte)LifeState_t.LIFE_ALIVE };
    case TargetType.GroupDead:
        return PlayerPawn is { IsValid: true, Value.LifeState: (byte)LifeState_t.LIFE_DEAD or (byte)LifeState_t.LIFE_DYING };
    default:
        return false;
}

one option would be interfaces. then you could make extensions for them :)

interface IEntityValid
{
  public bool IsValid { get; set; }
}

public static class EntityExtensions
{
  public static bool TryGetEntity<T>(this T? @this, [NotNullWhen(true)] out T? entity) where T : NativeEntity, IEntityValid
  {
    entity = null;

    if (@this is null || !@this.IsValid)
    {
      return false;
    }

    entity = @this;

    return true;
  }
}