Compare commits

..

No commits in common. "0a5d394eab4f150e302e2bacb396c9c50625cf9d" and "f6379df7c889157eb841a71ac2046e8a5d29bd64" have entirely different histories.

9 changed files with 229 additions and 129 deletions

4
.gitignore vendored
View File

@ -2,6 +2,4 @@ bin/
obj/ obj/
/packages/ /packages/
riderModule.iml riderModule.iml
/_ReSharper.Caches/ /_ReSharper.Caches/
*.user
/.idea/

View File

@ -1,25 +1,139 @@
<Project Sdk="Microsoft.NET.Sdk"> <?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')"/>
<PropertyGroup> <PropertyGroup>
<TargetFramework>net48</TargetFramework> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{67776CDF-B249-4B71-B8B9-6537A9DCE309}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<LangVersion>12</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AppDesignerFolder>Properties</AppDesignerFolder> <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> <PlatformTarget>x64</PlatformTarget>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<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> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Assembly-CSharp" Private="false"/> <Reference Include="Assembly-CSharp">
<Reference Include="Assembly-CSharp-firstpass" Private="false"/> <HintPath>$(NW-ASSEMBLIES)\Assembly-CSharp.dll</HintPath>
<Reference Include="Axwabo.Helpers" Private="false"/> </Reference>
<Reference Include="CommandSystem.Core" Private="false"/> <Reference Include="Assembly-CSharp-firstpass">
<Reference Include="Mirror" Private="false"/> <HintPath>$(NW-ASSEMBLIES)\Assembly-CSharp-firstpass.dll</HintPath>
<Reference Include="Mirror.Components" Private="false"/> </Reference>
<Reference Include="mscorlib" Private="false"/> <Reference Include="Axwabo.Helpers.NWAPI">
<Reference Include="LabApi" Private="false"/> <HintPath>$(NW-ASSEMBLIES)\Axwabo.Helpers.dll</HintPath>
<Reference Include="Pooling" Private="false"/> </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"/>
<Reference Include="UnityEngine.CoreModule" Private="false"/> <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>
<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>
-->
</Project> </Project>

View File

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

View File

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

View File

@ -2,12 +2,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Axwabo.Helpers; using Axwabo.Helpers;
using LabApi.Features.Wrappers;
using PlayerRoles; using PlayerRoles;
using PlayerRoles.PlayableScps; using PlayerRoles.PlayableScps;
using PlayerRoles.PlayableScps.Scp3114;
using PlayerRoles.PlayableScps.Scp939; using PlayerRoles.PlayableScps.Scp939;
using PlayerStatsSystem; using PlayerStatsSystem;
using PluginAPI.Core;
using UnityEngine; using UnityEngine;
namespace DeathLog; namespace DeathLog;
@ -20,7 +19,7 @@ public static class LogHandler
private static readonly Color DntColor = new(0.59f, 0.59f, 0.59f); private static readonly Color DntColor = new(0.59f, 0.59f, 0.59f);
public static readonly HashSet<uint> KosIgnoredVictimNetIdList = []; public static readonly HashSet<uint> KosIgnoredVictimNetIdList = new();
private static bool IsWeapon(ItemType type) => type is ItemType.GunCOM15 private static bool IsWeapon(ItemType type) => type is ItemType.GunCOM15
or ItemType.GunCOM18 or ItemType.GunCOM18
@ -54,8 +53,9 @@ public static class LogHandler
public static void LogAttackerDeathMessage(Player victim, Player attacker, AttackerDamageHandler handler, PlayerPermissions permissions, bool kosPermitted, float defaultScalar) public static void LogAttackerDeathMessage(Player victim, Player attacker, AttackerDamageHandler handler, PlayerPermissions permissions, bool kosPermitted, float defaultScalar)
{ {
var isCuffed = victim.IsDisarmed; var isCuffed = victim.IsDisarmed;
var hasWeaponEquipped = IsWeapon(victim.Inventory.CurItem.TypeId); var inv = victim.ReferenceHub.inventory;
var carriesWeapon = victim.Items.Any(item => IsWeapon(item!.Type)); var hasWeaponEquipped = IsWeapon(inv.CurItem.TypeId);
var carriesWeapon = inv.UserInventory.Items.Any(item => IsWeapon(item.Value.ItemTypeId));
var victimRole = victim.Role; var victimRole = victim.Role;
var footprint = handler.Attacker; var footprint = handler.Attacker;
var attackerRole = footprint.Role; 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) private static void Log(Func<float, string> msg, bool success, PlayerPermissions playerPermissions, float defaultScalar)
{ {
foreach (var p in Player.ReadyList) foreach (var p in Player.GetPlayers())
{ {
var sender = p.ReferenceHub.queryProcessor._sender; var sender = p.ReferenceHub.queryProcessor._sender;
if (!p.RemoteAdminAccess || !PermissionsHandler.IsPermitted(sender.Permissions, playerPermissions) || ToggleLogsCommand.HiddenIdList.Contains(p.UserId)) 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) private static object GetKillerStatus(Player attacker, float sizeScalar)
{ {
var role = attacker.RoleBase; var role = attacker.Rm().CurrentRole;
return GetIdWithDnt(attacker, sizeScalar) return GetIdWithDnt(attacker, sizeScalar)
+ " " + " "
+ role.RoleName.Color(role.RoleColor.ToHex(true, false)).Size(35.Scale(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) private static object GetVictimStatus(Player victim, float sizeScalar)
{ {
var role = victim.RoleBase; var role = victim.Rm().CurrentRole;
return GetIdWithDnt(victim, sizeScalar).Size(25.Scale(sizeScalar)) return GetIdWithDnt(victim, sizeScalar).Size(25.Scale(sizeScalar))
+ " " + " "
+ role.RoleName.Color(role.RoleColor.ToHex(true, false)).Size(35.Scale(sizeScalar)) + role.RoleName.Color(role.RoleColor.ToHex(true, false)).Size(35.Scale(sizeScalar))
@ -125,7 +125,6 @@ public static class LogHandler
Scp018DamageHandler => $"{{0}} killed {{1}} with {"SCP-018".Bold().Color(Lime).Size(35.Scale(sizeScalar))}", 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))}", 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))}", 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)}" _ => $"{{0}} killed {{1}}. {"Reason is unknown".Italic().Color(Lime)}"
} }
+ WeaponStatusMessage(!scpAttacker, hasWeaponEquipped, carriesWeapon, sizeScalar); + WeaponStatusMessage(!scpAttacker, hasWeaponEquipped, carriesWeapon, sizeScalar);
@ -133,8 +132,8 @@ public static class LogHandler
private static string WeaponStatusMessage(bool show, bool hasWeaponEquipped, bool carriesWeapon, float sizeScalar) => private static string WeaponStatusMessage(bool show, bool hasWeaponEquipped, bool carriesWeapon, float sizeScalar) =>
show && (carriesWeapon || hasWeaponEquipped) show && (carriesWeapon || hasWeaponEquipped)
? (hasWeaponEquipped ? (hasWeaponEquipped
? " Victim was " + "holding".Underline() + " a weapon" ? " Victim was " + "holding".Underline() + " a weapon."
: " Victim had a weapon " + "in their inventory".Underline() : " Victim had a weapon " + "in their inventory.".Underline()
).Color(Cyan).Size(30.Scale(sizeScalar)) ).Color(Cyan).Size(30.Scale(sizeScalar))
: ""; : "";
@ -158,7 +157,7 @@ public static class LogHandler
_ => "[an unknown attack type]" _ => "[an unknown attack type]"
}; };
private static string GetScp939AttackType(Scp939DamageHandler scp939) => scp939.Scp939DamageType switch private static string GetScp939AttackType(Scp939DamageHandler scp939) => scp939._damageType switch
{ {
Scp939DamageType.Claw => nameof(Scp939DamageType.Claw), Scp939DamageType.Claw => nameof(Scp939DamageType.Claw),
Scp939DamageType.LungeSecondary => "Lunge Secondary", Scp939DamageType.LungeSecondary => "Lunge Secondary",
@ -166,18 +165,10 @@ public static class LogHandler
_ => "[an unknown attack type]" _ => "[an unknown attack type]"
}; };
public static void LogLeavingScp(string role, float health, float hs, PlayerPermissions permissions, float 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" + 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")} " + ($"HP: {((int) health).ToString().Color("red")} " +
$"HS: {((int) hs).ToString().Color("purple")}").Size(35.Scale(sizeScalar)), false, permissions, defaultScalar); $"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); 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: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DeathLog")] [assembly: AssemblyProduct("DeathLog")]
[assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [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 // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.0.0")] [assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyFileVersion("1.1.0.0")]

View File

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

17
DeathLog/packages.config Normal file
View File

@ -0,0 +1,17 @@
<?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>

View File

@ -1,19 +0,0 @@
<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>