Compare commits

...

10 Commits

Author SHA1 Message Date
0a5d394eab use LabApi properties where possible 2025-05-01 19:24:32 +02:00
0a1192d5fc port plugin and events 2025-05-01 19:19:02 +02:00
6d39360955 begin LabApi version 2025-05-01 19:08:03 +02:00
755cfb0d88 fix spawn wave checks 2024-12-22 09:45:00 +01:00
bce7d936b3 detain events 2024-07-14 16:53:38 +02:00
cf8e68f159 Revert "Christmas"
This reverts commit 773f8c1fec87f6d903f88fd922bda964a871684f.
2024-01-13 10:28:51 +01:00
773f8c1fec Christmas 2023-12-23 22:32:45 +01:00
d668a1b28e 13.3.1 2023-11-14 21:47:34 +01:00
cda02035c6 3114 2023-10-28 12:04:59 +02:00
6bcb554c40 13.3 2023-10-27 18:46:42 +02:00
9 changed files with 134 additions and 234 deletions

2
.gitignore vendored
View File

@ -3,3 +3,5 @@ obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
*.user
/.idea/

View File

@ -1,139 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.8\build\Microsoft.CodeAnalysis.Analyzers.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.8\build\Microsoft.CodeAnalysis.Analyzers.props')"/>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{67776CDF-B249-4B71-B8B9-6537A9DCE309}</ProjectGuid>
<TargetFramework>net48</TargetFramework>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DeathLog</RootNamespace>
<AssemblyName>DeathLog</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<LangVersion>10</LangVersion>
<NoWarn>MSB3277</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>12</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp">
<HintPath>$(NW-ASSEMBLIES)\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp-firstpass">
<HintPath>$(NW-ASSEMBLIES)\Assembly-CSharp-firstpass.dll</HintPath>
</Reference>
<Reference Include="Axwabo.Helpers.NWAPI">
<HintPath>$(NW-ASSEMBLIES)\Axwabo.Helpers.dll</HintPath>
</Reference>
<Reference Include="CommandSystem.Core">
<HintPath>$(NW-ASSEMBLIES)\CommandSystem.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis, Version=3.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.3.3.1\lib\netstandard2.0\Microsoft.CodeAnalysis.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=3.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.3.3.1\lib\netstandard2.0\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
</Reference>
<Reference Include="Mirror">
<HintPath>$(NW-ASSEMBLIES)\Mirror.dll</HintPath>
</Reference>
<Reference Include="Mirror.Components">
<HintPath>$(NW-ASSEMBLIES)\Mirror.Components.dll</HintPath>
</Reference>
<Reference Include="mscorlib"/>
<Reference Include="PluginAPI, Version=13.1.0.0, Culture=neutral, processorArchitecture=Amd64">
<HintPath>..\packages\Northwood.PluginAPI.13.1.0\lib\net48\PluginAPI.dll</HintPath>
</Reference>
<Reference Include="Pooling">
<HintPath>$(NW-ASSEMBLIES)\Pooling.dll</HintPath>
</Reference>
<Reference Include="System"/>
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Core"/>
<Reference Include="System.Data"/>
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics"/>
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Reflection.Metadata, Version=1.4.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encoding.CodePages.4.5.1\lib\net461\System.Text.Encoding.CodePages.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml"/>
<Reference Include="UnityEngine">
<HintPath>$(NW-ASSEMBLIES)\UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>$(NW-ASSEMBLIES)\UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="YamlDotNet, Version=11.0.0.0, Culture=neutral, PublicKeyToken=ec19458f3c15af5e, processorArchitecture=MSIL">
<HintPath>..\packages\YamlDotNet.11.0.1\lib\net45\YamlDotNet.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="DeathLogConfig.cs"/>
<Compile Include="DeathLogPlugin.cs"/>
<Compile Include="LogHandler.cs"/>
<Compile Include="Properties\AssemblyInfo.cs"/>
<Compile Include="ToggleLogsCommand.cs"/>
</ItemGroup>
<ItemGroup>
<None Include="packages.config"/>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll"/>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.8\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll"/>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.8\build\Microsoft.CodeAnalysis.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.8\build\Microsoft.CodeAnalysis.Analyzers.props'))"/>
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<AppDesignerFolder>Properties</AppDesignerFolder>
<PlatformTarget>x64</PlatformTarget>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp" Private="false"/>
<Reference Include="Assembly-CSharp-firstpass" Private="false"/>
<Reference Include="Axwabo.Helpers" Private="false"/>
<Reference Include="CommandSystem.Core" Private="false"/>
<Reference Include="Mirror" Private="false"/>
<Reference Include="Mirror.Components" Private="false"/>
<Reference Include="mscorlib" Private="false"/>
<Reference Include="LabApi" Private="false"/>
<Reference Include="Pooling" Private="false"/>
<Reference Include="System"/>
<Reference Include="UnityEngine.CoreModule" Private="false"/>
</ItemGroup>
</Project>

View File

@ -15,4 +15,6 @@ public sealed class DeathLogConfig
public float DefaultFontSizeScalar { get; set; } = 1;
public bool LogDetainEvents { get; set; } = true;
}

View File

@ -1,93 +1,82 @@
using Axwabo.Helpers;
using System;
using LabApi.Events.Arguments.PlayerEvents;
using LabApi.Events.Arguments.ServerEvents;
using LabApi.Events.Handlers;
using LabApi.Loader.Features.Plugins;
using PlayerRoles;
using PlayerRoles.PlayableScps;
using PlayerStatsSystem;
using PluginAPI.Core;
using PluginAPI.Core.Attributes;
using PluginAPI.Enums;
using PluginAPI.Events;
namespace DeathLog;
public sealed class DeathLogPlugin
public sealed class DeathLogPlugin : Plugin<DeathLogConfig>
{
[PluginEntryPoint("DeathLog", "1.1.0", "DeathLog", "Axwabo")]
public void OnEnabled()
public override string Name => "DeathLog";
public override string Description => "Logs deaths, cuffing and leaving SCPs";
public override string Author => "Axwabo";
public override Version Version => GetType().Assembly.GetName().Version;
public override Version RequiredApiVersion { get; } = new(1, 0, 0);
public override void Enable()
{
EventManager.RegisterEvents(this);
Log.Info("DeathLog loaded!");
ServerEvents.WaveRespawned += OnTeamRespawn;
ServerEvents.RoundStarted += OnRoundStarted;
PlayerEvents.Dying += OnPlayerDeath;
PlayerEvents.ChangingRole += OnPlayerLeave;
PlayerEvents.Cuffed += OnDetaining;
PlayerEvents.Uncuffed += OnUnDetaining;
}
[PluginUnload]
public void OnDisabled()
public override void Disable()
{
EventManager.UnregisterEvents(this);
Log.Info("DeathLog disabled!");
ServerEvents.WaveRespawned -= OnTeamRespawn;
ServerEvents.RoundStarted -= OnRoundStarted;
PlayerEvents.Dying -= OnPlayerDeath;
PlayerEvents.ChangingRole -= OnPlayerLeave;
PlayerEvents.Cuffed -= OnDetaining;
PlayerEvents.Uncuffed -= OnUnDetaining;
}
[PluginConfig]
public DeathLogConfig Config = new();
private bool _spawnWaveOccurred;
[PluginEvent(ServerEventType.RoundStart)]
private void OnRoundStarted()
{
_spawnWaveOccurred = false;
_lastId = "";
LogHandler.KosIgnoredVictimNetIdList.Clear();
}
[PluginEvent(ServerEventType.TeamRespawn)]
private void OnTeamRespawn(TeamRespawnEvent e) => _spawnWaveOccurred = Config.IgnoreLeavingAfterSpawnWave;
private void OnTeamRespawn(WaveRespawnedEventArgs ev)
=> _spawnWaveOccurred = Config!.IgnoreLeavingAfterSpawnWave;
private static bool IsUnknownCause(DamageHandlerBase handler) =>
handler is UniversalDamageHandler udh && (udh.TranslationId == 0 ? string.IsNullOrEmpty(udh._logsText) : udh._logsText == DeathTranslations.Unknown.LogLabel);
[PluginEvent(ServerEventType.PlayerDying)]
private void OnPlayerDeath(PlayerDyingEvent e)
private void OnPlayerDeath(PlayerDyingEventArgs e)
{
var player = e.Player;
var attacker = e.Attacker;
var handler = e.DamageHandler;
if (player.Role is RoleTypeId.None or RoleTypeId.Scp0492 || string.IsNullOrEmpty(player.ReferenceHub.nicknameSync._myNickSync))
if (!player.IsReady || player.Role is RoleTypeId.None or RoleTypeId.Scp0492 || string.IsNullOrEmpty(player.Nickname))
return;
if (attacker != null && handler is AttackerDamageHandler adh)
LogHandler.LogAttackerDeathMessage(player, attacker, adh, Config.VisibilityRequirement, Config.KillOnSightPermitted, Config.DefaultFontSizeScalar);
else if (Config.LogSimpleDeaths)
LogHandler.LogAttackerDeathMessage(player, attacker, adh, Config!.VisibilityRequirement, Config.KillOnSightPermitted, Config.DefaultFontSizeScalar);
else if (Config!.LogSimpleDeaths)
LogHandler.LogSimpleDeathMessage(player, handler, Config.VisibilityRequirement, Config.DefaultFontSizeScalar);
if (!IsUnknownCause(handler) || player.ReferenceHub.roleManager.CurrentRole is not FpcStandardScp scp)
return;
_lastRole = scp.RoleName.Color(scp.RoleColor.ToHex());
_lastId = player.UserId;
}
[PluginEvent(ServerEventType.PlayerDamage)]
private void OnDamage(PlayerDamageEvent e)
private void OnPlayerLeave(PlayerChangingRoleEventArgs ev)
{
var handler = e.DamageHandler;
var player = e.Player;
if (player == null
|| !player.IsConnected()
|| !IsUnknownCause(handler)
|| player.ReferenceHub.roleManager.CurrentRole is not FpcStandardScp {RoleTypeId: not RoleTypeId.Scp0492})
return;
var stats = player.ReferenceHub.playerStats;
_lastHealth = stats.GetModule<HealthStat>().CurValue;
_lastHumeShield = stats.GetModule<HumeShieldStat>().CurValue;
if (ev.NewRole == RoleTypeId.Destroyed && !_spawnWaveOccurred && Config!.LogLeavingScpPlayers)
LogHandler.LogLeavingScp(ev.OldRole.RoleName, ev.Player.Health, ev.Player.HumeShield, Config.VisibilityRequirement, Config.DefaultFontSizeScalar);
}
private string _lastRole = "";
private float _lastHealth;
private float _lastHumeShield;
private string _lastId;
[PluginEvent(ServerEventType.PlayerLeft)]
private void OnPlayerLeave(Player player)
private void OnDetaining(PlayerCuffedEventArgs e)
{
if (!_spawnWaveOccurred && Config.LogLeavingScpPlayers && player.UserId == _lastId)
LogHandler.LogLeavingScp(_lastRole, _lastHealth, _lastHumeShield, Config.VisibilityRequirement, Config.DefaultFontSizeScalar);
if (Config!.LogDetainEvents)
LogHandler.LogDetain(e.Target, e.Player, Config.VisibilityRequirement, Config.DefaultFontSizeScalar);
}
private void OnUnDetaining(PlayerUncuffedEventArgs e)
{
if (Config!.LogDetainEvents)
LogHandler.LogUnDetain(e.Target, e.Player, Config.VisibilityRequirement, Config.DefaultFontSizeScalar);
}
}

View File

@ -2,11 +2,12 @@
using System.Collections.Generic;
using System.Linq;
using Axwabo.Helpers;
using LabApi.Features.Wrappers;
using PlayerRoles;
using PlayerRoles.PlayableScps;
using PlayerRoles.PlayableScps.Scp3114;
using PlayerRoles.PlayableScps.Scp939;
using PlayerStatsSystem;
using PluginAPI.Core;
using UnityEngine;
namespace DeathLog;
@ -19,7 +20,7 @@ public static class LogHandler
private static readonly Color DntColor = new(0.59f, 0.59f, 0.59f);
public static readonly HashSet<uint> KosIgnoredVictimNetIdList = new();
public static readonly HashSet<uint> KosIgnoredVictimNetIdList = [];
private static bool IsWeapon(ItemType type) => type is ItemType.GunCOM15
or ItemType.GunCOM18
@ -53,9 +54,8 @@ public static class LogHandler
public static void LogAttackerDeathMessage(Player victim, Player attacker, AttackerDamageHandler handler, PlayerPermissions permissions, bool kosPermitted, float defaultScalar)
{
var isCuffed = victim.IsDisarmed;
var inv = victim.ReferenceHub.inventory;
var hasWeaponEquipped = IsWeapon(inv.CurItem.TypeId);
var carriesWeapon = inv.UserInventory.Items.Any(item => IsWeapon(item.Value.ItemTypeId));
var hasWeaponEquipped = IsWeapon(victim.Inventory.CurItem.TypeId);
var carriesWeapon = victim.Items.Any(item => IsWeapon(item!.Type));
var victimRole = victim.Role;
var footprint = handler.Attacker;
var attackerRole = footprint.Role;
@ -75,7 +75,7 @@ public static class LogHandler
private static void Log(Func<float, string> msg, bool success, PlayerPermissions playerPermissions, float defaultScalar)
{
foreach (var p in Player.GetPlayers())
foreach (var p in Player.ReadyList)
{
var sender = p.ReferenceHub.queryProcessor._sender;
if (!p.RemoteAdminAccess || !PermissionsHandler.IsPermitted(sender.Permissions, playerPermissions) || ToggleLogsCommand.HiddenIdList.Contains(p.UserId))
@ -93,7 +93,7 @@ public static class LogHandler
private static object GetKillerStatus(Player attacker, float sizeScalar)
{
var role = attacker.Rm().CurrentRole;
var role = attacker.RoleBase;
return GetIdWithDnt(attacker, sizeScalar)
+ " "
+ role.RoleName.Color(role.RoleColor.ToHex(true, false)).Size(35.Scale(sizeScalar))
@ -102,7 +102,7 @@ public static class LogHandler
private static object GetVictimStatus(Player victim, float sizeScalar)
{
var role = victim.Rm().CurrentRole;
var role = victim.RoleBase;
return GetIdWithDnt(victim, sizeScalar).Size(25.Scale(sizeScalar))
+ " "
+ role.RoleName.Color(role.RoleColor.ToHex(true, false)).Size(35.Scale(sizeScalar))
@ -125,6 +125,7 @@ public static class LogHandler
Scp018DamageHandler => $"{{0}} killed {{1}} with {"SCP-018".Bold().Color(Lime).Size(35.Scale(sizeScalar))}",
DisruptorDamageHandler => $"{{0}} killed {{1}} with the {"3-X Particle Disruptor".Bold().Color(Lime).Size(35.Scale(sizeScalar))}",
JailbirdDamageHandler => $"{{0}} killed {{1}} with the {"Jailbird".Bold().Color(Lime).Size(35.Scale(sizeScalar))}",
Scp3114DamageHandler scp3114 => $"{{0}} killed {{1}} with {scp3114.Subtype.ToString().Bold().Color(Lime).Size(35.Scale(sizeScalar))}",
_ => $"{{0}} killed {{1}}. {"Reason is unknown".Italic().Color(Lime)}"
}
+ WeaponStatusMessage(!scpAttacker, hasWeaponEquipped, carriesWeapon, sizeScalar);
@ -132,8 +133,8 @@ public static class LogHandler
private static string WeaponStatusMessage(bool show, bool hasWeaponEquipped, bool carriesWeapon, float sizeScalar) =>
show && (carriesWeapon || hasWeaponEquipped)
? (hasWeaponEquipped
? " Victim was " + "holding".Underline() + " a weapon."
: " Victim had a weapon " + "in their inventory.".Underline()
? " Victim was " + "holding".Underline() + " a weapon"
: " Victim had a weapon " + "in their inventory".Underline()
).Color(Cyan).Size(30.Scale(sizeScalar))
: "";
@ -157,7 +158,7 @@ public static class LogHandler
_ => "[an unknown attack type]"
};
private static string GetScp939AttackType(Scp939DamageHandler scp939) => scp939._damageType switch
private static string GetScp939AttackType(Scp939DamageHandler scp939) => scp939.Scp939DamageType switch
{
Scp939DamageType.Claw => nameof(Scp939DamageType.Claw),
Scp939DamageType.LungeSecondary => "Lunge Secondary",
@ -165,10 +166,18 @@ public static class LogHandler
_ => "[an unknown attack type]"
};
public static void LogLeavingScp(string role, float health, float hs, PlayerPermissions permissions, float defaultScalar) =>
Log(sizeScalar => $"{"SCP Left".Color("red").Bold()}#Please replace {role.Size(40.Scale(sizeScalar))} as the player has left the game.\n" +
($"HP: {((int) health).ToString().Color("red")} " +
$"HS: {((int) hs).ToString().Color("purple")}").Size(35.Scale(sizeScalar)), false, permissions, defaultScalar);
public static void LogLeavingScp(string role, float health, float hs, PlayerPermissions permissions, float defaultScalar)
=> Log(sizeScalar => $"{"SCP Left".Color("red").Bold()}#Please replace {role.Size(40.Scale(sizeScalar))} as the player has left the game.\n" +
($"HP: {((int) health).ToString().Color("red")} " +
$"HS: {((int) hs).ToString().Color("purple")}").Size(35.Scale(sizeScalar)), false, permissions, defaultScalar);
public static void LogDetain(Player target, Player detainer, PlayerPermissions permissions, float defaultScalar)
=> Log(sizeScalar => $"{"CUFFING".Color("orange")}#{GetKillerStatus(detainer, sizeScalar)} {"detained".Color("orange").Size(30.Scale(sizeScalar))} {GetVictimStatus(target, sizeScalar)}",
true, permissions, defaultScalar);
public static void LogUnDetain(Player uncuffedPlayer, Player undetainer, PlayerPermissions permissions, float defaultScalar)
=> Log(sizeScalar => $"{"UNCUFFING".Color("red")}#{GetKillerStatus(undetainer, sizeScalar)} {"undetained".Color("red").Size(30.Scale(sizeScalar))} {GetVictimStatus(uncuffedPlayer, sizeScalar)}",
true, permissions, defaultScalar);
private static int Scale(this int number, float scalar) => (int) (number * scalar);

View File

@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DeathLog")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]

View File

@ -6,7 +6,8 @@ using RemoteAdmin;
namespace DeathLog;
[CommandHandler(typeof(RemoteAdminCommandHandler))]
public sealed class ToggleLogsCommand : ICommand {
public sealed class ToggleLogsCommand : ICommand
{
public static readonly HashSet<string> HiddenIdList = new();
public static readonly Dictionary<string, float> SizeScalar = new();
@ -14,17 +15,22 @@ public sealed class ToggleLogsCommand : ICommand {
public string Command => "toggleKillLogs";
public string[] Aliases { get; } = {"tkl"};
public string Description => "Toggles the visibility of kill logs or changes the font size scalar for the caller.";
public bool SanitizeResponse => false;
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response) {
if (sender is not PlayerCommandSender {ReferenceHub.characterClassManager.UserId: var id}) {
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
{
if (sender is not PlayerCommandSender {ReferenceHub.authManager.UserId: var id})
{
response = "You must be a player to use this command.";
return false;
}
if (arguments.Count < 1) {
if (arguments.Count < 1)
{
if (HiddenIdList.Add(id))
response = "You will no longer see kill logs.";
else {
else
{
HiddenIdList.Remove(id);
response = "You will now see kill logs.";
}
@ -32,7 +38,8 @@ public sealed class ToggleLogsCommand : ICommand {
return true;
}
switch (arguments.At(0).ToLower()) {
switch (arguments.At(0).ToLower())
{
case "on" or "enable" or "true" or "yes":
HiddenIdList.Remove(id);
response = "You will now see kill logs.";
@ -46,13 +53,16 @@ public sealed class ToggleLogsCommand : ICommand {
}
}
private static bool ParseScalar(ArraySegment<string> arguments, string id, out string response) {
if (!float.TryParse(arguments.At(0), out var scalar)) {
private static bool ParseScalar(ArraySegment<string> arguments, string id, out string response)
{
if (!float.TryParse(arguments.At(0), out var scalar))
{
response = "Invalid argument. Expected a float or a boolean.";
return false;
}
if (scalar is not (> 0 and <= 5)) {
if (scalar is not (> 0 and <= 5))
{
response = "Invalid argument. Expected a float in range 0-5.";
return false;
}

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.CodeAnalysis.Analyzers" version="2.9.8" targetFramework="net48"
developmentDependency="true"/>
<package id="Microsoft.CodeAnalysis.CSharp" version="3.3.1" targetFramework="net48"/>
<package id="Microsoft.CodeAnalysis.Common" version="3.3.1" targetFramework="net48"/>
<package id="Northwood.PluginAPI" version="13.1.0" targetFramework="net48"/>
<package id="System.Buffers" version="4.4.0" targetFramework="net48"/>
<package id="System.Collections.Immutable" version="1.5.0" targetFramework="net48"/>
<package id="System.Memory" version="4.5.3" targetFramework="net48"/>
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net48"/>
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net48"/>
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net48"/>
<package id="System.Text.Encoding.CodePages" version="4.5.1" targetFramework="net48"/>
<package id="System.Threading.Tasks.Extensions" version="4.5.3" targetFramework="net48"/>
<package id="YamlDotNet" version="11.0.1" targetFramework="net48"/>
</packages>

19
Directory.Build.targets Normal file
View File

@ -0,0 +1,19 @@
<Project>
<Import Project="ReferencePath.props.user" Condition="Exists('ReferencePath.props.user')"/>
<PropertyGroup>
<AssemblySearchPaths>$(AssemblySearchPaths);$(ReferencePath)</AssemblySearchPaths>
</PropertyGroup>
<Target Name="NotifyIncompleteSetup" BeforeTargets="PrepareForBuild" Condition="$(ReferencePath) == ''">
<PropertyGroup>
<Template>
&lt;Project&gt;
&lt;PropertyGroup&gt;
&lt;ReferencePath&gt;&lt;/ReferencePath&gt;
&lt;/PropertyGroup&gt;
&lt;/Project&gt;
</Template>
</PropertyGroup>
<WriteLinesToFile File="../ReferencePath.props.user" Lines="$(Template)" Overwrite="false" Condition="!Exists('../ReferencePath.props.user')"/>
<Error Text="The ReferencePath property is not specified! Make sure to set the property in the ReferencePath.props.user file."/>
</Target>
</Project>