Add ProjectZomboidPerkLog (PerkLog.txt)
Per-line skill snapshot log; each Login event is paired with a perks row containing comma-separated Skill=N tokens. PERK_PAIR regex extracts each pair via preg_match_all for analyser use. Detectors: filename match plus content signature on the unique '[Cooking=N, Fitness=N, Strength=N,' prefix of the perks-row bracket.
This commit is contained in:
44
src/Log/ProjectZomboid/ProjectZomboidPerkLog.php
Normal file
44
src/Log/ProjectZomboid/ProjectZomboidPerkLog.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace IndifferentKetchup\Codex\Log\ProjectZomboid;
|
||||
|
||||
use IndifferentKetchup\Codex\Analyser\AnalyserInterface;
|
||||
use IndifferentKetchup\Codex\Analyser\PatternAnalyser;
|
||||
use IndifferentKetchup\Codex\Detective\FilenameDetector;
|
||||
use IndifferentKetchup\Codex\Detective\WeightedSinglePatternDetector;
|
||||
use IndifferentKetchup\Codex\Parser\ParserInterface;
|
||||
use IndifferentKetchup\Codex\Parser\PatternParser;
|
||||
use IndifferentKetchup\Codex\Pattern\ProjectZomboid\PerkPattern;
|
||||
|
||||
class ProjectZomboidPerkLog extends ProjectZomboidEventLog
|
||||
{
|
||||
public static function getDefaultParser(): ParserInterface
|
||||
{
|
||||
return static::makePatternParser(
|
||||
PerkPattern::LINE,
|
||||
[PatternParser::TIME]
|
||||
);
|
||||
}
|
||||
|
||||
public static function getDefaultAnalyser(): AnalyserInterface
|
||||
{
|
||||
return new PatternAnalyser();
|
||||
}
|
||||
|
||||
public static function getDetectors(): array
|
||||
{
|
||||
return [
|
||||
(new FilenameDetector())
|
||||
->setPattern('/_PerkLog\.txt$/')
|
||||
->setWeight(0.95),
|
||||
(new WeightedSinglePatternDetector())
|
||||
->setPattern('/\[Cooking=\d+, Fitness=\d+, Strength=\d+,/')
|
||||
->setWeight(0.95),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return "Project Zomboid Perk Log";
|
||||
}
|
||||
}
|
||||
21
src/Pattern/ProjectZomboid/PerkPattern.php
Normal file
21
src/Pattern/ProjectZomboid/PerkPattern.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace IndifferentKetchup\Codex\Pattern\ProjectZomboid;
|
||||
|
||||
/**
|
||||
* Regex constants for the Project Zomboid PerkLog.txt format.
|
||||
*
|
||||
* [time] [steamid][player][x,y,z][event-or-perks][Hours Survived: N].
|
||||
*
|
||||
* The fourth bracketed field is either a single token (Login, Logout,
|
||||
* LevelUp, etc.) or a comma-separated list of Skill=N pairs. Both fit
|
||||
* the same character class.
|
||||
*/
|
||||
class PerkPattern
|
||||
{
|
||||
public const string LINE = '/^\[(\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\] \[\d{17}\]\[[^\]]+\]\[\d+,\d+,\d+\]\[[^\]]+\]\[Hours Survived: \d+\]\.$/';
|
||||
|
||||
public const string FIELDS = '/^\[\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}\] \[(?<steamid>\d{17})\]\[(?<player>[^\]]+)\]\[(?<x>\d+),(?<y>\d+),(?<z>\d+)\]\[(?<event>[^\]]+)\]\[Hours Survived: (?<hours>\d+)\]\.$/';
|
||||
|
||||
public const string PERK_PAIR = '/(?<skill>[A-Za-z_]+)=(?<level>\d+)/';
|
||||
}
|
||||
6
test/src/Games/ProjectZomboid/fixtures/perk-minimal.txt
Normal file
6
test/src/Games/ProjectZomboid/fixtures/perk-minimal.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
[16-04-26 18:29:08.171] [76561198000000001][Player1][1000,2000,1][Login][Hours Survived: 100].
|
||||
[16-04-26 18:29:08.171] [76561198000000001][Player1][1000,2000,1][Cooking=5, Fitness=6, Strength=7, Blunt=7, Axe=0, Lightfoot=0, Nimble=3, Sprinting=5, Sneak=3, Woodwork=10, Aiming=1, Reloading=1, Farming=1, Fishing=1, Trapping=0, PlantScavenging=1, Doctor=1, Electricity=5, Blacksmith=6, MetalWelding=3, Mechanics=6, Spear=0, Maintenance=7, SmallBlade=0, LongBlade=0, SmallBlunt=3, Tailoring=10, Tracking=0, Husbandry=10, FlintKnapping=0, Masonry=6, Pottery=4, Carving=10, Butchering=6, Glassmaking=2, Side_L=0, Side_R=0, ProstFamiliarity=0][Hours Survived: 100].
|
||||
[16-04-26 18:29:15.822] [76561198000000002][Player2][1010,2010,0][Login][Hours Survived: 50].
|
||||
[16-04-26 18:29:15.823] [76561198000000002][Player2][1010,2010,0][Cooking=2, Fitness=10, Strength=10, Blunt=10, Axe=0, Lightfoot=4, Nimble=4, Sprinting=7, Sneak=2, Woodwork=6, Aiming=5, Reloading=4, Farming=0, Fishing=0, Trapping=0, PlantScavenging=0, Doctor=2, Electricity=5, Blacksmith=8, MetalWelding=10, Mechanics=10, Spear=0, Maintenance=7, SmallBlade=0, LongBlade=0, SmallBlunt=0, Tailoring=0, Tracking=0, Husbandry=0, FlintKnapping=0, Masonry=0, Pottery=0, Carving=0, Butchering=0, Glassmaking=0, Side_L=0, Side_R=0, ProstFamiliarity=0][Hours Survived: 50].
|
||||
[16-04-26 18:30:02.500] [76561198000000003][AdminUser][1020,2020,0][Logout][Hours Survived: 75].
|
||||
[16-04-26 19:15:00.000] [76561198000000001][Player1][1003,2003,1][LevelUp][Hours Survived: 101].
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace IndifferentKetchup\Codex\Test\Tests\Games\ProjectZomboid\Log;
|
||||
|
||||
use IndifferentKetchup\Codex\Detective\Detective;
|
||||
use IndifferentKetchup\Codex\Log\File\PathLogFile;
|
||||
use IndifferentKetchup\Codex\Log\ProjectZomboid\ProjectZomboidPerkLog;
|
||||
use IndifferentKetchup\Codex\Pattern\ProjectZomboid\PerkPattern;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ProjectZomboidPerkLogTest extends TestCase
|
||||
{
|
||||
private function fixturePath(): string
|
||||
{
|
||||
return __DIR__ . '/../../../../src/Games/ProjectZomboid/fixtures/perk-minimal.txt';
|
||||
}
|
||||
|
||||
public function testParsesEachLineAsAnEntry(): void
|
||||
{
|
||||
$log = (new ProjectZomboidPerkLog())->setLogFile(new PathLogFile($this->fixturePath()));
|
||||
$log->parse();
|
||||
|
||||
$this->assertCount(6, $log->getEntries());
|
||||
}
|
||||
|
||||
public function testFieldsRegexHandlesEventRow(): void
|
||||
{
|
||||
$line = '[16-04-26 18:29:08.171] [76561198000000001][Player1][1000,2000,1][Login][Hours Survived: 100].';
|
||||
$this->assertSame(1, preg_match(PerkPattern::FIELDS, $line, $m));
|
||||
$this->assertSame('Player1', $m['player']);
|
||||
$this->assertSame('Login', $m['event']);
|
||||
$this->assertSame('100', $m['hours']);
|
||||
}
|
||||
|
||||
public function testFieldsRegexHandlesPerksRow(): void
|
||||
{
|
||||
$line = '[16-04-26 18:30:02.500] [76561198000000003][AdminUser][1020,2020,0][Logout][Hours Survived: 75].';
|
||||
$this->assertSame(1, preg_match(PerkPattern::FIELDS, $line, $m));
|
||||
$this->assertSame('Logout', $m['event']);
|
||||
}
|
||||
|
||||
public function testPerkPairRegexExtractsSkillsFromBracketedList(): void
|
||||
{
|
||||
$bracket = 'Cooking=5, Fitness=6, Strength=7';
|
||||
$count = preg_match_all(PerkPattern::PERK_PAIR, $bracket, $matches, PREG_SET_ORDER);
|
||||
$this->assertSame(3, $count);
|
||||
$this->assertSame('Cooking', $matches[0]['skill']);
|
||||
$this->assertSame('5', $matches[0]['level']);
|
||||
}
|
||||
|
||||
public function testDetectiveDispatchesByContent(): void
|
||||
{
|
||||
$detective = (new Detective())
|
||||
->setLogFile(new PathLogFile($this->fixturePath()))
|
||||
->addPossibleLogClass(ProjectZomboidPerkLog::class);
|
||||
|
||||
$this->assertInstanceOf(ProjectZomboidPerkLog::class, $detective->detect());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user