mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-08 08:56:34 -08:00
222 lines
9.0 KiB
C#
222 lines
9.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
using CounterStrikeSharp.API.Core;
|
|
using CounterStrikeSharp.API.Modules.Entities;
|
|
using CounterStrikeSharp.API.Modules.Utils;
|
|
|
|
namespace CounterStrikeSharp.API.Modules.Admin
|
|
{
|
|
public partial class AdminData
|
|
{
|
|
[JsonPropertyName("groups")] public HashSet<string> Groups { get; init; } = new();
|
|
}
|
|
public partial class AdminGroupData
|
|
{
|
|
[JsonPropertyName("flags")] public required HashSet<string> Flags { get; init; }
|
|
[JsonPropertyName("immunity")] public uint Immunity { get; set; } = 0;
|
|
[JsonPropertyName("command_overrides")] public Dictionary<string, bool> CommandOverrides { get; init; } = new();
|
|
}
|
|
|
|
public static partial class AdminManager
|
|
{
|
|
private static Dictionary<string, AdminGroupData> Groups = new();
|
|
|
|
public static void LoadAdminGroups(string adminGroupsPath)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(adminGroupsPath))
|
|
{
|
|
Console.WriteLine("Admin groups file not found. Skipping admin groups load.");
|
|
return;
|
|
}
|
|
|
|
var groupsFromFile = JsonSerializer.Deserialize<Dictionary<string, AdminGroupData>>(File.ReadAllText(adminGroupsPath), new JsonSerializerOptions() { ReadCommentHandling = JsonCommentHandling.Skip });
|
|
if (groupsFromFile == null) { throw new FileNotFoundException(); }
|
|
foreach (var (key, groupDef) in groupsFromFile)
|
|
{
|
|
if (Groups.ContainsKey(key))
|
|
{
|
|
Groups[key].Flags.UnionWith(groupDef.Flags);
|
|
if (groupDef.Immunity > Groups[key].Immunity)
|
|
{
|
|
Groups[key].Immunity = groupDef.Immunity;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Groups.Add(key, groupDef);
|
|
}
|
|
}
|
|
|
|
Console.WriteLine($"Loaded {Groups.Count} admin groups.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Failed to load admin groups: {ex}");
|
|
}
|
|
|
|
// Loop over each of the admins. If one of our admins is in a group,
|
|
// add the flags from the group to their admin definition and change
|
|
// the admin's immunity if it's higher.
|
|
foreach (var (admin, data) in Admins)
|
|
{
|
|
var groups = data.Groups;
|
|
foreach (var group in groups)
|
|
{
|
|
// roflmuffin is probably smart enough to condense this function down ;)
|
|
if (Groups.TryGetValue(group, out var groupData))
|
|
{
|
|
AddPlayerPermissions(admin, groupData.Flags.ToArray());
|
|
if (groupData.Immunity > data.Immunity)
|
|
{
|
|
data.Immunity = groupData.Immunity;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks to see if the player is part of an admin group.
|
|
/// </summary>
|
|
/// <param name="player">Player controller.</param>
|
|
/// <param name="groups">Groups to check for.</param>
|
|
/// <returns>True if a player is part of all of the groups provided, false if not.</returns>
|
|
public static bool PlayerInGroup(CCSPlayerController? player, params string[] groups)
|
|
{
|
|
// This is here for cases where the server console is attempting to call commands.
|
|
// The server console should have access to all commands, regardless of groups.
|
|
if (player == null) return true;
|
|
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return false; }
|
|
|
|
var playerData = GetPlayerAdminData(player.AuthorizedSteamID);
|
|
if (playerData == null) return false;
|
|
|
|
var playerGroups = groups.ToHashSet();
|
|
foreach (var domain in playerData.Flags)
|
|
{
|
|
if (playerData.DomainHasRootFlag(domain.Key))
|
|
{
|
|
playerGroups.ExceptWith(groups.Where(group => group.Contains(domain.Key + '/')));
|
|
}
|
|
}
|
|
|
|
return playerData.Groups.IsSupersetOf(playerGroups);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks to see if the player is part of an admin group.
|
|
/// </summary>
|
|
/// <param name="steamId">SteamID of the player.</param>
|
|
/// <param name="groups">Groups to check for.</param>
|
|
/// <returns>True if a player is part of all of the groups provided, false if not.</returns>
|
|
public static bool PlayerInGroup(SteamID? steamId, params string[] groups)
|
|
{
|
|
if (steamId == null) return false;
|
|
var playerData = GetPlayerAdminData(steamId);
|
|
if (playerData == null) return false;
|
|
|
|
var playerGroups = groups.ToHashSet<string>();
|
|
foreach (var domain in playerData.Flags)
|
|
{
|
|
if (playerData.DomainHasRootFlag(domain.Key))
|
|
{
|
|
playerGroups.ExceptWith(groups.Where(group => group.Contains(domain.Key + '/')));
|
|
}
|
|
}
|
|
|
|
return playerData.Groups.IsSupersetOf(playerGroups);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a player to a group. This does NOT modify the immunity of the player (see SetPlayerImmunity).
|
|
/// </summary>
|
|
/// <param name="player">Player controller.</param>
|
|
/// <param name="groups">Groups to add the player to.</param>
|
|
public static void AddPlayerToGroup(CCSPlayerController? player, params string[] groups)
|
|
{
|
|
if (player == null) return;
|
|
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return; }
|
|
AddPlayerToGroup(player.AuthorizedSteamID, groups);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a player to a group. This does NOT modify the immunity of the player (see SetPlayerImmunity).
|
|
/// </summary>
|
|
/// <param name="steamId">SteamID of the player.</param>
|
|
/// <param name="groups">Groups to add the player to.</param>
|
|
public static void AddPlayerToGroup(SteamID? steamId, params string[] groups)
|
|
{
|
|
if (steamId == null) return;
|
|
var data = GetPlayerAdminData(steamId);
|
|
if (data == null)
|
|
{
|
|
data = new AdminData()
|
|
{
|
|
Identity = steamId.SteamId64.ToString(),
|
|
Flags = new(),
|
|
Groups = new(groups)
|
|
};
|
|
}
|
|
|
|
foreach (var group in groups)
|
|
{
|
|
if (Groups.TryGetValue(group, out var groupDef))
|
|
{
|
|
AddPlayerPermissions(steamId, groupDef.Flags.ToArray());
|
|
groupDef.CommandOverrides.ToList().ForEach(x => data.CommandOverrides[x.Key] = x.Value);
|
|
}
|
|
}
|
|
Admins[steamId] = data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a player from a group.
|
|
/// </summary>
|
|
/// <param name="player">Player controller.</param>
|
|
/// <param name="removeInheritedFlags">If true, all of the flags that the player inherited from being in the group will be removed.</param>
|
|
/// <param name="groups"></param>
|
|
public static void RemovePlayerFromGroup(CCSPlayerController? player, bool removeInheritedFlags = true, params string[] groups)
|
|
{
|
|
if (player == null) return;
|
|
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot || player.IsHLTV) { return; }
|
|
RemovePlayerFromGroup(player.AuthorizedSteamID, true, groups);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a player from a group.
|
|
/// </summary>
|
|
/// <param name="steamId">SteamID of the player.</param>
|
|
/// <param name="removeInheritedFlags">If true, all of the flags that the player inherited from being in the group will be removed.</param>
|
|
/// <param name="groups"></param>
|
|
public static void RemovePlayerFromGroup(SteamID? steamId, bool removeInheritedFlags = true, params string[] groups)
|
|
{
|
|
if (steamId == null) return;
|
|
var data = GetPlayerAdminData(steamId);
|
|
if (data == null) return;
|
|
|
|
data.Groups.ExceptWith(groups);
|
|
|
|
if (removeInheritedFlags)
|
|
{
|
|
foreach (var group in groups)
|
|
{
|
|
if (Groups.TryGetValue(group, out var groupDef))
|
|
{
|
|
RemovePlayerPermissions(steamId, groupDef.Flags.ToArray());
|
|
}
|
|
}
|
|
}
|
|
Admins[steamId] = data;
|
|
}
|
|
}
|
|
}
|