v1.2.2.b6

Performance & stability pass (issue #34 + audit)

General:
- DisableAll resets only skills active in the previous round instead of all loaded skills (~89ms -> ~5ms)
- Removed per-tick LINQ/allocations, O(1) HUD skill lookups, translation substitutions moved to load time
- ForceFullUpdate creates the network service once per broadcast; view-angle guard only skips a genuine (0,0,0) placeholder
- Debug hooks/logging only active when DebugMode is enabled (single reused writer)
- Player skill state unified to a single collection (fixes a rare disconnect race)
- Gamedata signatures resolved lazily/isolated; hardened tick/transmit paths against invalid handles
- Description HUD honours always-show / -1 duration consistently across all assignment paths

Skills:
- Jester: fixed the no-damage effect leaking after a mid-round skill change (Thief/Deactivator)
- Jackal: fixed trail entities accumulating over a round
- Falcon Eye / Third Eye / Spectator: camera state cleared on disable

Also: added missing translation keys as untranslated markers across language files.

Fixes #34
This commit is contained in:
ByDexter 2026-07-05 21:48:29 +03:00
parent a0f37ba1a1
commit 25cd8eb989
31 changed files with 202 additions and 79 deletions

View file

@ -61,7 +61,7 @@ namespace src.player
{
if (player == null || !player.IsValid || player.IsBot) return;
var skillPlayer = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
var skillPlayer = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index);
if (skillPlayer == null || !skillPlayer.DisplayHUD) return;
var now = DateTime.Now;
@ -72,7 +72,7 @@ namespace src.player
string skillLine = string.Empty;
string remainingLine = string.Empty;
bool showDescriptionHUD = skillPlayer.SkillDescriptionHudExpired >= now;
bool showDescriptionHUD = skillPlayer.SkillDescriptionHudExpired >= now || Config.LoadedConfig.DisplayAlwaysDescription;
bool isDescription = true;
var skills = SkillData.Skills;
@ -99,7 +99,7 @@ namespace src.player
{
if (player.PawnIsAlive)
{
var skillInfo = skills.FirstOrDefault(s => s.Skill == skillPlayer.Skill);
var skillInfo = SkillData.GetInfo(skillPlayer.Skill);
if (skillInfo != null)
{
@ -139,9 +139,9 @@ namespace src.player
var observedSkill = PlayerManager.GetPlayerByIndex(observedEvent.Index);
if (observedSkill == null) return;
var observedSkillInfo = skills.FirstOrDefault(s => s.Skill == observedSkill.Skill);
var observedSkillInfo = SkillData.GetInfo(observedSkill.Skill);
var observedSpecialInfo = observedSkill.SpecialSkill != Skills.None
? skills.FirstOrDefault(s => s.Skill == observedSkill.SpecialSkill)
? SkillData.GetInfo(observedSkill.SpecialSkill)
: null;
string primaryName = player.GetSkillName(observedSkill.Skill, observedSkill.SkillChance);