88using CounterStrikeSharp . API . Modules . Commands ;
99using CounterStrikeSharp . API . Modules . Cvars ;
1010using CounterStrikeSharp . API . Modules . Memory ;
11+ using CounterStrikeSharp . API . Modules . Memory . DynamicFunctions ;
1112using Microsoft . Extensions . Logging ;
1213
1314namespace BasicAdmin ;
@@ -21,6 +22,8 @@ public sealed class BasicAdmin : BasePlugin, IPluginConfig<BasicAdminConfig>
2122
2223 public BasicAdminConfig Config { get ; set ; } = new ( ) ;
2324
25+ private static readonly Dictionary < IntPtr , bool > ActiveGodMode = new ( ) ;
26+
2427 public void OnConfigParsed ( BasicAdminConfig config )
2528 {
2629 this . Config = config ;
@@ -32,17 +35,38 @@ public override void Load(bool hotReload)
3235
3336 AddCommandListener ( "say" , OnSayCommand ) ;
3437 AddCommandListener ( "say_team" , OnSayCommand ) ;
38+ VirtualFunctions . CBaseEntity_TakeDamageOldFunc . Hook ( OnTakeDamage , HookMode . Pre ) ;
3539 }
3640
37- // public override void Unload(bool hotReload)
38- // {
39- // base.Unload(hotReload);
40- //
41- // RemoveCommandListener("say", OnSayCommand, HookMode.Pre);
42- // RemoveCommandListener("say_team", OnSayCommand, HookMode.Pre);
43- // }
41+ public override void Unload ( bool hotReload )
42+ {
43+ base . Unload ( hotReload ) ;
44+
45+ VirtualFunctions . CBaseEntity_TakeDamageOldFunc . Unhook ( OnTakeDamage , HookMode . Pre ) ;
46+ }
4447
45- public HookResult OnSayCommand ( CCSPlayerController ? caller , CommandInfo info )
48+
49+ private static HookResult OnTakeDamage ( DynamicHook hook )
50+ {
51+ var entindex = hook . GetParam < CEntityInstance > ( 0 ) . EntityIndex ? . Value ;
52+
53+ if ( entindex is null or 0 )
54+ return HookResult . Continue ;
55+
56+ var pawn = Utilities . GetEntityFromIndex < CCSPlayerPawn > ( ( int ) entindex . Value ) ;
57+
58+ if ( pawn . OriginalController ? . Value is not { } player )
59+ return HookResult . Continue ;
60+
61+ if ( ActiveGodMode . ContainsKey ( player . Handle ) )
62+ {
63+ hook . GetParam < CTakeDamageInfo > ( 1 ) . Damage = 0 ;
64+ }
65+
66+ return HookResult . Continue ;
67+ }
68+
69+ private HookResult OnSayCommand ( CCSPlayerController ? caller , CommandInfo info )
4670 {
4771 if ( ! ( info . GetArg ( 1 ) . StartsWith ( '@' ) && AdminManager . PlayerHasPermissions ( caller , "@css/chat" ) ) )
4872 return HookResult . Continue ;
@@ -69,6 +93,14 @@ public HookResult OnSayCommand(CCSPlayerController? caller, CommandInfo info)
6993
7094 return HookResult . Stop ;
7195 }
96+
97+ [ GameEventHandler ( HookMode . Post ) ]
98+ public HookResult OnRoundStart ( EventRoundStart @event , GameEventInfo info )
99+ {
100+ ActiveGodMode . Clear ( ) ;
101+
102+ return HookResult . Continue ;
103+ }
72104
73105 [ ConsoleCommand ( "css_map" , "Change map." ) ]
74106 [ CommandHelper ( 1 , "<mapname>" ) ]
@@ -105,11 +137,11 @@ public void OnWorkshopMapCommand(CCSPlayerController? caller, CommandInfo info)
105137
106138 command = ulong . TryParse ( map , out var mapId ) ? $ "host_workshop_map { mapId } " : $ "ds_workshop_changelevel { map } ";
107139
108- if ( mapId == 0 && ! Server . IsMapValid ( map ) )
109- {
110- info . ReplyToCommand ( FormatMessage ( $ "Map { map } not found.") ) ;
111- return ;
112- }
140+ // if (mapId == 0 && !Server.IsMapValid(map))
141+ // {
142+ // info.ReplyToCommand(FormatMessage($"Map {map} not found."));
143+ // return;
144+ // }
113145
114146 Server . PrintToChatAll ( FormatAdminMessage ( $ "Changing map to { map } ...") ) ;
115147
@@ -204,22 +236,22 @@ public void OnForceSpecCommand(CCSPlayerController? caller, CommandInfo info)
204236 Server . PrintToChatAll ( FormatAdminMessage ( $ "{ caller ! . PlayerName } moved { player . PlayerName } to spec.") ) ;
205237 }
206238
207- // [ConsoleCommand("css_respawn", "Respawn a dead player.")]
208- // [CommandHelper(1, "<#userid or name>")]
209- // [RequiresPermissions("@css/kick")]
210- // public void OnRespawnCommand(CCSPlayerController? caller, CommandInfo info)
211- // {
212- // if (!ServerUtils. GetTarget(info.GetArg(1) , out var player))
213- // {
214- // info.ReplyToCommand(FormatMessage($"Target {info.GetArg(1)} not found."));
215- // return;
216- // }
217- //
218- // player!.DispatchSpawn ();
219- //
220- // if (Config.HideActivity)
221- // Server.PrintToChatAll(FormatAdminMessage($"{caller!.PlayerName} respawned {player! .PlayerName}."));
222- // }
239+ [ ConsoleCommand ( "css_respawn" , "Respawn a dead player." ) ]
240+ [ CommandHelper ( 1 , "<#userid or name>" ) ]
241+ [ RequiresPermissions ( "@css/kick" ) ]
242+ public void OnRespawnCommand ( CCSPlayerController ? caller , CommandInfo info )
243+ {
244+ if ( ! GetTarget ( info , out var player ) )
245+ {
246+ info . ReplyToCommand ( FormatMessage ( $ "Target { info . GetArg ( 1 ) } not found.") ) ;
247+ return ;
248+ }
249+
250+ player ! . Respawn ( ) ;
251+
252+ if ( Config . HideActivity )
253+ Server . PrintToChatAll ( FormatAdminMessage ( $ "{ caller ! . PlayerName } respawned { player . PlayerName } .") ) ;
254+ }
223255
224256 [ ConsoleCommand ( "css_say" , "Say to all players." ) ]
225257 [ CommandHelper ( 1 , "<message>" ) ]
@@ -392,7 +424,7 @@ public void OnCvarCommand(CCSPlayerController? caller, CommandInfo info)
392424
393425 info . ReplyToCommand ( $ "{ caller ! . PlayerName } changed cvar { cvar . Name } to { value } .") ;
394426
395- Logger . LogInformation ( $ "{ caller ! . PlayerName } changed cvar { cvar . Name } to { value } .") ;
427+ Logger . LogInformation ( $ "{ caller . PlayerName } changed cvar { cvar . Name } to { value } .") ;
396428 }
397429
398430 [ ConsoleCommand ( "css_admins" , "Show connected admins." ) ]
@@ -414,7 +446,7 @@ public void OnAdminsCommand(CCSPlayerController? caller, CommandInfo info)
414446 }
415447
416448
417- [ ConsoleCommand ( "css_admin_help" , "Show connected admins ." ) ]
449+ [ ConsoleCommand ( "css_admin_help" , "Show available admin commands ." ) ]
418450 [ RequiresPermissions ( "@css/generic" ) ]
419451 public void OnAdminHelpCommand ( CCSPlayerController ? caller , CommandInfo info )
420452 {
@@ -424,7 +456,7 @@ public void OnAdminHelpCommand(CCSPlayerController? caller, CommandInfo info)
424456 return ;
425457 }
426458
427- var currentCommandIndex = 1 ; // Initialize counter variable
459+ var currentCommandIndex = 1 ;
428460
429461 info . ReplyToCommand ( FormatMessage ( "Help printed to your console." ) ) ;
430462
@@ -443,7 +475,9 @@ public void OnSlapCommand(CCSPlayerController? caller, CommandInfo info)
443475 if ( ! GetTarget ( info , out var player ) )
444476 return ;
445477
446- if ( ! int . TryParse ( info . GetArg ( 2 ) , out var damage ) )
478+ var damage = 0 ;
479+
480+ if ( ! string . IsNullOrEmpty ( info . GetArg ( 2 ) ) && ! int . TryParse ( info . GetArg ( 2 ) , out damage ) )
447481 {
448482 info . ReplyToCommand ( FormatMessage ( $ "Invalid damage value.") ) ;
449483 return ;
@@ -507,18 +541,45 @@ public void OnNoclipCommand(CCSPlayerController? caller, CommandInfo info)
507541 Server . PrintToChatAll ( FormatAdminMessage ( $ "{ caller ! . PlayerName } toggled noclip on { player . PlayerName } .") ) ;
508542 }
509543
544+ [ ConsoleCommand ( "css_godmode" , "Godmode a player." ) ]
545+ [ CommandHelper ( 1 , "<#userid or name>" ) ]
546+ [ RequiresPermissions ( "@css/cheats" ) ]
547+ public void OnGodmodeCommand ( CCSPlayerController ? caller , CommandInfo info )
548+ {
549+ if ( ! GetTarget ( info , out var player ) )
550+ return ;
551+
552+ if ( ActiveGodMode . ContainsKey ( player ! . Handle ) )
553+ {
554+ ActiveGodMode . Remove ( player . Handle ) ;
555+ }
556+ else
557+ {
558+ ActiveGodMode [ player . Handle ] = true ;
559+ }
560+
561+ if ( ! Config . HideActivity )
562+ Server . PrintToChatAll ( FormatAdminMessage ( $ "{ caller ! . PlayerName } toggled godmode on { player . PlayerName } (h: { player . Entity ! . EntityInstance . Handle : X} .") ) ;
563+ }
564+
565+ [ ConsoleCommand ( "css_rcon" , "Run a server console command." ) ]
566+ [ CommandHelper ( 1 , "<command>" ) ]
567+ [ RequiresPermissions ( "@css/rcon" ) ]
568+ public void OnRcomCommand ( CCSPlayerController ? caller , CommandInfo info )
569+ {
570+ info . ReplyToCommand ( $ "Command executed ({ info . ArgString } ).") ;
571+
572+ Server . ExecuteCommand ( info . ArgString ) ;
573+
574+ Logger . LogInformation ( $ "{ caller ! . PlayerName } executed command ({ info . ArgString } ).") ;
575+ }
576+
510577 // [ConsoleCommand("css_vote", "Respawn a dead player.")]
511578 // [CommandHelper(1, "<#userid or name>")]
512579 // // [RequiresPermissions("@css/vote")]
513580 // public void OnVoteCommand(CCSPlayerController? caller, CommandInfo info)
514581 // {
515- // if (!ServerUtils.GetTarget(info.GetArg(1), out var player))
516- // {
517- // info.ReplyToCommand(FormatMessage($"Target {info.GetArg(1)} not found."));
518- // return;
519- // }
520- //
521- // player!.PlayerPawn.Value.LifeState = (int) LifeState_t.LIFE_ALIVE;;
582+
522583 // }
523584
524585 private static bool GetTarget ( CommandInfo info , out CCSPlayerController ? player )
0 commit comments