Skip to content
This repository has been archived by the owner on Aug 10, 2024. It is now read-only.

Commit

Permalink
Finish refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
ntm5 authored Jul 9, 2024
1 parent f992807 commit 5663db4
Show file tree
Hide file tree
Showing 92 changed files with 3,707 additions and 0 deletions.
7 changes: 7 additions & 0 deletions mod/TTT.Detective/DetectiveConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TTT.Detective;

public class DetectiveConfig
{
public bool DNAScannerEnabled { get; } = true;

}
147 changes: 147 additions & 0 deletions mod/TTT.Detective/DetectiveManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using TTT.Player;
using TTT.Public.Behaviors;
using TTT.Public.Extensions;
using TTT.Public.Formatting;
using TTT.Public.Mod.Detective;
using TTT.Public.Mod.Role;
using TTT.Public.Player;

namespace TTT.Detective;

public class DetectiveManager(IPlayerService roleService) : IDetectiveService, IPluginBehavior
{
private const int TaserAmmoType = 18;

public void Start(BasePlugin parent)
{
parent.RegisterListener<Listeners.OnTick>(() =>
{
foreach (var player in Utilities.GetPlayers().Where(player => player.IsValid && player.IsReal())
.Where(player => (player.Buttons & PlayerButtons.Use) != 0)) OnPlayerUse(player);
});


VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnZeus, HookMode.Pre);

}

public HookResult OnZeus(DynamicHook hook)
{
var ent = hook.GetParam<CBaseEntity>(0);

var playerWhoWasDamaged = player(ent);

if (playerWhoWasDamaged == null) return HookResult.Continue;

var info = hook.GetParam<CTakeDamageInfo>(1);

CCSPlayerController? attacker = null;

if (info.Attacker.Value != null)
{
var playerWhoAttacked = info.Attacker.Value.As<CCSPlayerPawn>();

attacker = playerWhoAttacked.Controller.Value.As<CCSPlayerController>();

}

if (info.BitsDamageType is not 256) return HookResult.Continue;
if (attacker == null) return HookResult.Continue;

info.Damage = 0;

var targetRole = roleService.GetPlayer(playerWhoWasDamaged);

Server.NextFrame(() =>
{
attacker.PrintToChat(
StringUtils.FormatTTT(
$"You tased player {playerWhoWasDamaged.PlayerName} they are a {targetRole.PlayerRole().FormatRoleFull()}"));
});

return HookResult.Stop;
}


private void OnPlayerUse(CCSPlayerController player)
{
IdentifyBody(player);
}

private void IdentifyBody(CCSPlayerController caller)
{
//add states

if (roleService.GetPlayer(caller).PlayerRole() != Role.Detective) return;

var entity = caller.GetClientRagdollAimTarget();

if (entity == null) return;

if (entity.PawnIsAlive) return;

var player = roleService.GetPlayer(entity);

if (player.IsFound()) return;

var killerEntity= player.Killer();

string message;

var plr = player.Player();
if (plr == null) return;

if (killerEntity == null || !killerEntity.IsReal())
message = StringUtils.FormatTTT(player.PlayerRole()
.FormatStringFullAfter($"{plr.PlayerName} was killed by world"));
else
message = StringUtils.FormatTTT(
player.PlayerRole().FormatStringFullAfter($"{plr.PlayerName} was killed by ") +
roleService.GetPlayer(killerEntity).PlayerRole().FormatStringFullAfter(killerEntity.PlayerName));


player.SetFound(true);

Server.NextFrame(() => { Server.PrintToChatAll(message); });
}

//to be moved to a utility class
public static CCSPlayerController? player(CEntityInstance? instance)
{
if (instance == null)
{
return null;
}

if (instance.DesignerName != "player")
{
return null;
}

// grab the pawn index
int player_index = (int)instance.Index;

// grab player controller from pawn
CCSPlayerPawn player_pawn = Utilities.GetEntityFromIndex<CCSPlayerPawn>(player_index);

// pawn valid
if (player_pawn == null || !player_pawn.IsValid)
{
return null;
}

// controller valid
if (player_pawn.OriginalController == null || !player_pawn.OriginalController.IsValid)
{
return null;
}

// any further validity is up to the caller
return player_pawn.OriginalController.Value;
}
}
13 changes: 13 additions & 0 deletions mod/TTT.Detective/DetectiveServiceExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using TTT.Public.Extensions;
using TTT.Public.Mod.Detective;

namespace TTT.Detective;

public static class DetectiveServiceExtension
{
public static void AddDetectiveBehavior(this IServiceCollection collection)
{
collection.AddPluginBehavior<IDetectiveService, DetectiveManager>();
}
}
11 changes: 11 additions & 0 deletions mod/TTT.Detective/TTT.Detective.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>TTT.Detective</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\public\TTT.Public\TTT.Public.csproj" />
</ItemGroup>
</Project>
83 changes: 83 additions & 0 deletions mod/TTT.Logs/LogBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System.Collections.Generic;
using System.Linq;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using TTT.Public.Action;
using TTT.Public.Behaviors;
using TTT.Public.Extensions;
using TTT.Public.Mod.Logs;
using Action = TTT.Public.Action.Action;

namespace TTT.Logs;

public class LogBehavior : ILogService, IPluginBehavior
{
private int _round = 1;

public void Start(BasePlugin plugin)
{
}

[GameEventHandler]
public HookResult OnRoundStart(EventRoundStart _, GameEventInfo __)
{
CreateRound(_round++);
return HookResult.Continue;
}

[GameEventHandler]
public HookResult OnRoundEnd(EventRoundEnd _, GameEventInfo __)
{
PrintLogs(_round);
return HookResult.Continue;
}

private readonly Dictionary<int, IRoundLogs> _logs = new();

public int GetCurrentRound()
{
return _round;
}

public void AddLog(Action action)
{
_logs[_round].AddLog(action);
}

public bool PrintLogs(int round)
{
if (_logs.ContainsKey(round)) return false;
foreach (var player in Utilities.GetPlayers().Where(plr => plr.IsReal()))
{
PrintToPlayer(player, round);
}

PrintToConsole(round);
return true;
}

public bool PrintToPlayer(CCSPlayerController player, int round)
{
if (!_logs.ContainsKey(round)) return false;
player.PrintToConsole(GetLogs(round).FormattedLogs());
return true;
}

public bool PrintToConsole(int round)
{
if (!_logs.ContainsKey(round)) return false;
Server.PrintToConsole(GetLogs(round).FormattedLogs());
return true;
}

public IRoundLogs GetLogs(int round)
{
return _logs[round];
}

public void CreateRound(int round)
{
_logs.Add(round, new RoundLog(round));
}
}
16 changes: 16 additions & 0 deletions mod/TTT.Logs/LogServiceExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.Extensions.DependencyInjection;
using TTT.Public.Extensions;
using TTT.Public.Mod.Logs;
using TTT.Public.Mod.Role;

namespace TTT.Logs;

public static class LogServiceExtension
{
public static void AddLogsService(this IServiceCollection collection)
{
collection.AddPluginBehavior<ILogService, LogBehavior>();
collection.AddPluginBehavior<LogsCommand>();
collection.AddPluginBehavior<LogsListener>();
}
}
62 changes: 62 additions & 0 deletions mod/TTT.Logs/LogsCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands;
using TTT.Public.Behaviors;
using TTT.Public.Formatting;
using TTT.Public.Mod.Logs;

namespace TTT.Logs;

public class LogsCommand(ILogService service) : IPluginBehavior
{
private readonly ILogService _service = service;

Check warning on line 13 in mod/TTT.Logs/LogsCommand.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'ILogService service' is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.

public void Start(BasePlugin plugin)
{

}

[ConsoleCommand("css_logs", "Prints logs to console")]
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
public void Command_Logs(CCSPlayerController? executor, CommandInfo info)
{

if (!AdminManager.PlayerHasPermissions(executor, "@css/kick"))
{
info.ReplyToCommand(StringUtils.FormatTTT("You do not have permission to execute this command"));
return;
}

var roundIdString = info.GetArg(1);

var roundId = service.GetCurrentRound();

if (!string.IsNullOrEmpty(roundIdString) || !int.TryParse(roundIdString, out roundId))
{
info.ReplyToCommand(StringUtils.FormatTTT("Invalid round id"));
return;
}

if (roundId <= 0)
{
info.ReplyToCommand( StringUtils.FormatTTT("Invalid round id"));
}

if (executor == null)
{
if (!service.PrintToConsole(roundId)) info.ReplyToCommand(StringUtils.FormatTTT("No logs found for round " + roundId));
return;
}

if (!AdminManager.PlayerHasPermissions(executor, "@css/kick"))
{
info.ReplyToCommand("You do not have permission to execute this command");
return;
}

info.ReplyToCommand(!service.PrintToPlayer(executor, roundId)
? StringUtils.FormatTTT("No logs found for round " + roundId)
: StringUtils.FormatTTT("Logs printed to console"));
}
}
Loading

0 comments on commit 5663db4

Please sign in to comment.