Skip to content

Commit 9e553a7

Browse files
committed
Minimum CSSharp requirement bumped to v65, addition of new commands and modified others.
New configuration values: If you are upgrading from previous version, please add the following : ```json "admin_list_min_flag": "@css/kick", "admin_list_req_flag": "", "freeze_duration": 5, ``` New commands: * `css_admins` * `css_admin_help` * `css_noclip`, * `css_freeze(unfreeze)`, * `css_slap` Modified: * `css_wsmap` now takes an id or a name. * `css_bury` takes a second argument, duration. * `css_spec` renamed to `css_forcespec` to avoid conflicts. Added logging for the following actions: * Game restart * Cvar changing * Map changing Other minor changes.
1 parent 8c79f0d commit 9e553a7

File tree

5 files changed

+275
-61
lines changed

5 files changed

+275
-61
lines changed

BasicAdmin/BasicAdmin.cs

Lines changed: 155 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
using CounterStrikeSharp.API;
1+
using System.Reflection;
2+
using CounterStrikeSharp.API;
23
using CounterStrikeSharp.API.Core;
4+
using CounterStrikeSharp.API.Core.Attributes;
35
using CounterStrikeSharp.API.Core.Attributes.Registration;
46
using CounterStrikeSharp.API.Modules.Utils;
57
using CounterStrikeSharp.API.Modules.Admin;
68
using CounterStrikeSharp.API.Modules.Commands;
79
using CounterStrikeSharp.API.Modules.Cvars;
810
using CounterStrikeSharp.API.Modules.Memory;
11+
using Microsoft.Extensions.Logging;
912

1013
namespace BasicAdmin;
1114

12-
// [MinimumApiVersion(66)]
15+
[MinimumApiVersion(65)]
1316
public sealed class BasicAdmin : BasePlugin, IPluginConfig<BasicAdminConfig>
1417
{
1518
public override string ModuleName => "BasicAdmin";
1619
public override string ModuleAuthor => "livevilog";
17-
public override string ModuleVersion => "1.2.0";
20+
public override string ModuleVersion => "1.4.0";
1821

1922
public BasicAdminConfig Config {get; set;} = new ();
2023

@@ -44,7 +47,7 @@ public HookResult OnSayCommand(CCSPlayerController? caller, CommandInfo info)
4447
if (!(info.GetArg(1).StartsWith('@') && AdminManager.PlayerHasPermissions(caller, "@css/chat")))
4548
return HookResult.Continue;
4649

47-
var isTeam = info.GetArg(0).Equals("say_team");
50+
var isTeam = info.GetArg(0).Length > 4;
4851
var start = isTeam ? 11 : 6;
4952
string message;
5053

@@ -87,17 +90,22 @@ public void OnMapCommand(CCSPlayerController? caller, CommandInfo info)
8790
Server.ExecuteCommand($"changelevel {map}");
8891
// caller.Discon
8992
});
93+
94+
Logger.LogInformation($"{caller!.PlayerName} changed map to {map}.");
9095
}
9196

9297
[ConsoleCommand("css_wsmap", "Change map.")]
9398
[ConsoleCommand("css_workshop", "Change map.")]
94-
[CommandHelper(1, "<mapid>")]
99+
[CommandHelper(1, "<name or id>")]
95100
[RequiresPermissions("@css/changemap")]
96101
public void OnWorkshopMapCommand(CCSPlayerController? caller, CommandInfo info)
97102
{
103+
string? command = null;
98104
var map = info.GetArg(1);
105+
106+
command = ulong.TryParse(map, out var mapId) ? $"host_workshop_map {mapId}" : $"ds_workshop_changelevel {map}";
99107

100-
if (!Server.IsMapValid(map))
108+
if (mapId == 0 && !Server.IsMapValid(map))
101109
{
102110
info.ReplyToCommand(FormatMessage($"Map {map} not found."));
103111
return;
@@ -107,8 +115,10 @@ public void OnWorkshopMapCommand(CCSPlayerController? caller, CommandInfo info)
107115

108116
AddTimer(3f, () =>
109117
{
110-
Server.ExecuteCommand($"ds_workshop_changelevel {map}");
118+
Server.ExecuteCommand(command);
111119
});
120+
121+
Logger.LogInformation($"{caller!.PlayerName} changed map to {map}.");
112122
}
113123

114124
[ConsoleCommand("css_kick", "Kick a player from the server.")]
@@ -180,10 +190,10 @@ public void OnSwapCommand(CCSPlayerController? caller, CommandInfo info)
180190
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} swapped {player.PlayerName}."));
181191
}
182192

183-
[ConsoleCommand("css_spec", "Change a player to spec.")]
193+
[ConsoleCommand("css_forcespec", "Change a player to spec.")]
184194
[CommandHelper(1, "<#userid or name>")]
185195
[RequiresPermissions("@css/kick")]
186-
public void OnSpecCommand(CCSPlayerController? caller, CommandInfo info)
196+
public void OnForceSpecCommand(CCSPlayerController? caller, CommandInfo info)
187197
{
188198
if (!GetTarget(info, out var player))
189199
return;
@@ -280,20 +290,30 @@ public void OnRestartGameCommand(CCSPlayerController? caller, CommandInfo info)
280290

281291
if (!Config.HideActivity)
282292
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} restarted the game."));
293+
294+
Logger.LogInformation($"{caller!.PlayerName} restarted the game.");
283295
}
284296

285297
[ConsoleCommand("css_bury", "Bury a player.")]
286-
[CommandHelper(1, "<#userid or name>")]
298+
[CommandHelper(1, "<#userid or name> [duration]")]
287299
[RequiresPermissions("@css/ban")]
288300
public void OnBuryCommand(CCSPlayerController? caller, CommandInfo info)
289301
{
290302
if (!GetTarget(info, out var player))
291303
return;
292304

293-
var newPos = new Vector(player!.Pawn.Value.AbsOrigin!.X, player.Pawn.Value.AbsOrigin.Y,
294-
player.Pawn.Value.AbsOrigin.Z - 10f);
305+
var duration = 0;
295306

296-
player.Pawn.Value.Teleport(newPos, player.AbsRotation!, player.AbsVelocity);
307+
if (!string.IsNullOrEmpty(info.GetArg(2)) && !int.TryParse(info.GetArg(2), out duration))
308+
{
309+
info.ReplyToCommand(FormatMessage($"Invalid duration value."));
310+
return;
311+
}
312+
313+
player!.Pawn.Value.Bury();
314+
315+
if (duration > 0)
316+
AddTimer(duration, () => player!.Pawn.Value.Unbury());
297317

298318
if (!Config.HideActivity)
299319
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} buried {player.PlayerName}."));
@@ -307,10 +327,7 @@ public void OnUnburyCommand(CCSPlayerController? caller, CommandInfo info)
307327
if (!GetTarget(info, out var player))
308328
return;
309329

310-
var newPos = new Vector(player!.Pawn.Value.AbsOrigin!.X, player.Pawn.Value.AbsOrigin.Y,
311-
player.Pawn.Value.AbsOrigin!.Z + 15f);
312-
313-
player.Pawn.Value.Teleport(newPos, player.AbsRotation!, player.AbsVelocity);
330+
player!.Pawn.Value.Unbury();
314331

315332
if (!Config.HideActivity)
316333
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} unburied {player.PlayerName}."));
@@ -335,9 +352,12 @@ public void OnDisarmCommand(CCSPlayerController? caller, CommandInfo info)
335352
[RequiresPermissions("@css/slay")]
336353
public void OnHealthCommand(CCSPlayerController? caller, CommandInfo info)
337354
{
338-
if (!GetTarget(info, out var player) || !int.TryParse(info.GetArg(2), out var health))
355+
if (!GetTarget(info, out var player))
356+
return;
357+
358+
if (!int.TryParse(info.GetArg(2), out var health))
339359
{
340-
info.ReplyToCommand(FormatMessage($"Target {info.GetArg(1)} not found or is not buried."));
360+
info.ReplyToCommand(FormatMessage($"Invalid health value."));
341361
return;
342362
}
343363

@@ -369,6 +389,122 @@ public void OnCvarCommand(CCSPlayerController? caller, CommandInfo info)
369389
var value = info.GetArg(2);
370390

371391
Server.ExecuteCommand($"{cvar.Name} {value}");
392+
393+
info.ReplyToCommand($"{caller!.PlayerName} changed cvar {cvar.Name} to {value}.");
394+
395+
Logger.LogInformation($"{caller!.PlayerName} changed cvar {cvar.Name} to {value}.");
396+
}
397+
398+
[ConsoleCommand("css_admins", "Show connected admins.")]
399+
public void OnAdminsCommand(CCSPlayerController? caller, CommandInfo info)
400+
{
401+
if (!string.IsNullOrEmpty(Config.AdminListReqFlag) && !AdminManager.PlayerHasPermissions(caller, Config.AdminListReqFlag))
402+
{
403+
info.ReplyToCommand("[CSS] You don't have permissions to use this command.");
404+
return;
405+
}
406+
407+
var admins = Utilities.GetPlayers().FindAll(x => AdminManager.PlayerHasPermissions(x, Config.AdminListMinFlag));
408+
409+
var message = admins.Aggregate($" {ChatColors.Lime}Connected admins: {ChatColors.Green}\u2029",
410+
(current, admin) =>
411+
current + $"{admin.PlayerName}\u2029");
412+
413+
info.ReplyToCommand(message);
414+
}
415+
416+
417+
[ConsoleCommand("css_admin_help", "Show connected admins.")]
418+
[RequiresPermissions("@css/generic")]
419+
public void OnAdminHelpCommand(CCSPlayerController? caller, CommandInfo info)
420+
{
421+
if (!string.IsNullOrEmpty(Config.AdminListReqFlag) && !AdminManager.PlayerHasPermissions(caller, Config.AdminListReqFlag))
422+
{
423+
info.ReplyToCommand("[CSS] You don't have permissions to use this command.");
424+
return;
425+
}
426+
427+
var currentCommandIndex = 1; // Initialize counter variable
428+
429+
info.ReplyToCommand(FormatMessage("Help printed to your console."));
430+
431+
caller!.PrintToConsole(FormatMessage(
432+
CommandHandlers.Aggregate($"Available commands: \u2029",
433+
(s, pair) => s + ChatColors.Lime + pair.Key.GetMethodInfo().GetCustomAttributes<ConsoleCommandAttribute>().First().Command +
434+
ChatColors.Default + (currentCommandIndex++ % 3 == 0 ? ",\u2029" : ", "))[..^2]
435+
));
436+
}
437+
438+
[ConsoleCommand("css_slap", "Slap a player.")]
439+
[CommandHelper(1, "<#userid or name> [damage]")]
440+
[RequiresPermissions("@css/slay")]
441+
public void OnSlapCommand(CCSPlayerController? caller, CommandInfo info)
442+
{
443+
if (!GetTarget(info, out var player))
444+
return;
445+
446+
if (!int.TryParse(info.GetArg(2), out var damage))
447+
{
448+
info.ReplyToCommand(FormatMessage($"Invalid damage value."));
449+
return;
450+
}
451+
452+
player!.Pawn.Value.Slap(damage);
453+
454+
if (!Config.HideActivity)
455+
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} slapped {player.PlayerName}."));
456+
}
457+
458+
[ConsoleCommand("css_freeze", "Freeze a player.")]
459+
[CommandHelper(1, "<#userid or name> [duration]")]
460+
[RequiresPermissions("@css/slay")]
461+
public void OnFreezeCommand(CCSPlayerController? caller, CommandInfo info)
462+
{
463+
if (!GetTarget(info, out var player))
464+
return;
465+
466+
var duration = Config.FreezeDuration;
467+
468+
if (!string.IsNullOrEmpty(info.GetArg(2)) && !int.TryParse(info.GetArg(2), out duration))
469+
{
470+
info.ReplyToCommand(FormatMessage($"Invalid duration value."));
471+
return;
472+
}
473+
474+
player!.Pawn.Value.Freeze();
475+
476+
AddTimer(duration, () => player.Pawn.Value.Unfreeze());
477+
478+
if (!Config.HideActivity)
479+
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} froze {player.PlayerName}."));
480+
}
481+
482+
[ConsoleCommand("css_unfreeze", "Unfreeze a player.")]
483+
[CommandHelper(1, "<#userid or name>")]
484+
[RequiresPermissions("@css/slay")]
485+
public void OnUnfreezeCommand(CCSPlayerController? caller, CommandInfo info)
486+
{
487+
if (!GetTarget(info, out var player))
488+
return;
489+
490+
player!.Pawn.Value.Unfreeze();
491+
492+
if (!Config.HideActivity)
493+
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} unfroze {player.PlayerName}."));
494+
}
495+
496+
[ConsoleCommand("css_noclip", "Noclip a player.")]
497+
[CommandHelper(1, "<#userid or name>")]
498+
[RequiresPermissions("@css/cheats")]
499+
public void OnNoclipCommand(CCSPlayerController? caller, CommandInfo info)
500+
{
501+
if (!GetTarget(info, out var player))
502+
return;
503+
504+
player!.Pawn.Value.ToggleNoclip();
505+
506+
if (!Config.HideActivity)
507+
Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} toggled noclip on {player.PlayerName}."));
372508
}
373509

374510
// [ConsoleCommand("css_vote", "Respawn a dead player.")]

BasicAdmin/BasicAdmin.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.61" />
10+
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.65" />
1111
</ItemGroup>
1212
</Project>

BasicAdmin/BasicAdminConfig.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,13 @@ public class BasicAdminConfig : BasePluginConfig
1717

1818
[JsonPropertyName("admin_say_text_admins")]
1919
public string AdminSayTextTeam { get; set; } = $"(Admins only) \x03{{0}}\x01: {{1}}";
20+
21+
[JsonPropertyName("admin_list_min_flag")]
22+
public string AdminListMinFlag { get; set; } = "@css/kick";
23+
24+
[JsonPropertyName("admin_list_req_flag")]
25+
public string AdminListReqFlag { get; set; } = string.Empty;
26+
27+
[JsonPropertyName("freeze_duration")]
28+
public int FreezeDuration { get; set; } = 5;
2029
}

BasicAdmin/PlayerUtils.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using CounterStrikeSharp.API.Core;
2+
using CounterStrikeSharp.API.Modules.Utils;
3+
4+
namespace BasicAdmin;
5+
6+
public static class PlayerUtils
7+
{
8+
public static void Slap(this CBasePlayerPawn pawn, int damage = 0)
9+
{
10+
PerformSlap(pawn, damage);
11+
}
12+
13+
public static void Bury(this CBasePlayerPawn pawn, float depth = 10f)
14+
{
15+
var newPos = new Vector(pawn.AbsOrigin!.X, pawn.AbsOrigin.Y,
16+
pawn.AbsOrigin!.Z - depth);
17+
18+
pawn.Teleport(newPos, pawn.AbsRotation!, pawn.AbsVelocity);
19+
}
20+
21+
public static void Unbury(this CBasePlayerPawn pawn, float depth = 15f)
22+
{
23+
var newPos = new Vector(pawn.AbsOrigin!.X, pawn.AbsOrigin.Y,
24+
pawn.AbsOrigin!.Z + depth);
25+
26+
pawn.Teleport(newPos, pawn.AbsRotation!, pawn.AbsVelocity);
27+
}
28+
29+
public static void Freeze(this CBasePlayerPawn pawn)
30+
{
31+
pawn.MoveType = MoveType_t.MOVETYPE_NONE;
32+
}
33+
34+
public static void Unfreeze(this CBasePlayerPawn pawn)
35+
{
36+
pawn.MoveType = MoveType_t.MOVETYPE_WALK;
37+
}
38+
39+
public static void ToggleNoclip(this CBasePlayerPawn pawn)
40+
{
41+
if (pawn.MoveType == MoveType_t.MOVETYPE_NOCLIP)
42+
pawn.MoveType = MoveType_t.MOVETYPE_WALK;
43+
else
44+
pawn.MoveType = MoveType_t.MOVETYPE_NOCLIP;
45+
}
46+
47+
private static void PerformSlap(CBasePlayerPawn pawn, int damage = 0)
48+
{
49+
if (pawn.LifeState != (int)LifeState_t.LIFE_ALIVE)
50+
return;
51+
52+
/* Teleport in a random direction - thank you, Mani!*/
53+
/* Thank you AM & al!*/
54+
var random = new Random();
55+
var vel = new Vector(pawn.AbsVelocity.X, pawn.AbsVelocity.Y, pawn.AbsVelocity.Z);
56+
57+
vel.X += ((random.Next(180) + 50) * ((random.Next(2) == 1) ? -1 : 1));
58+
vel.Y += ((random.Next(180) + 50) * ((random.Next(2) == 1) ? -1 : 1));
59+
vel.Z += random.Next(200) + 100;
60+
61+
pawn.Teleport(pawn.AbsOrigin!, pawn.AbsRotation!, vel);
62+
63+
if (damage <= 0)
64+
return;
65+
66+
pawn.Health -= damage;
67+
68+
if (pawn.Health <= 0)
69+
pawn.CommitSuicide(true, true);
70+
}
71+
}

0 commit comments

Comments
 (0)