Add ConnectionFailureAnalyser

First custom Analyser subclass in this game tree. PatternAnalyser
operates per-entry without cross-entry state, so pairing
'attempting to join' with 'allowed to join' per Steam ID requires a
bespoke pass over the log. The analyser counts attempts and allowed
events per Steam ID and emits a ConnectionFailureProblem for each
player whose attempt count exceeds their allowed count. Unmatched
'attempting to join used queue' rows are surfaced as failures in v1
because a long queue wait is indistinguishable from a real failure
without timing context.
This commit is contained in:
2026-04-30 22:39:13 +00:00
parent c444e8543b
commit 73e9ca6181
5 changed files with 176 additions and 2 deletions

View File

@@ -0,0 +1,67 @@
<?php
namespace IndifferentKetchup\Codex\Analysis\ProjectZomboid;
use IndifferentKetchup\Codex\Analysis\InsightInterface;
use IndifferentKetchup\Codex\Analysis\Problem;
/**
* Problem emitted by ConnectionFailureAnalyser when a player's
* "attempting to join" event count exceeds their "allowed to join" count
* within the same log file. Coalesced by Steam ID so each player produces
* at most one problem regardless of how many unmatched attempts they have.
*/
class ConnectionFailureProblem extends Problem
{
private string $steamId = '';
private string $player = '';
private int $unmatchedAttempts = 0;
public function setSteamId(string $steamId): static
{
$this->steamId = $steamId;
return $this;
}
public function setPlayer(string $player): static
{
$this->player = $player;
return $this;
}
public function setUnmatchedAttempts(int $count): static
{
$this->unmatchedAttempts = $count;
return $this;
}
public function getSteamId(): string
{
return $this->steamId;
}
public function getPlayer(): string
{
return $this->player;
}
public function getUnmatchedAttempts(): int
{
return $this->unmatchedAttempts;
}
public function getMessage(): string
{
return sprintf(
'Player %s (%s) had %d "attempting to join" event(s) without a matching "allowed to join".',
$this->player,
$this->steamId,
$this->unmatchedAttempts
);
}
public function isEqual(InsightInterface $insight): bool
{
return $insight instanceof self && $insight->getSteamId() === $this->steamId;
}
}