{"id":28416012,"url":"https://github.com/adnanmula/keyforge-game-log-parser","last_synced_at":"2026-03-10T11:31:45.299Z","repository":{"id":288328110,"uuid":"967669257","full_name":"adnanmula/keyforge-game-log-parser","owner":"adnanmula","description":"Parse The Crucible game logs into a structured model.","archived":false,"fork":false,"pushed_at":"2025-11-01T00:38:49.000Z","size":174,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-01T02:26:30.370Z","etag":null,"topics":["keyforge"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adnanmula.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-16T20:13:27.000Z","updated_at":"2025-11-01T00:38:53.000Z","dependencies_parsed_at":"2025-10-22T14:37:26.889Z","dependency_job_id":"07b25616-07ff-4456-b7a7-3ed05213b22e","html_url":"https://github.com/adnanmula/keyforge-game-log-parser","commit_stats":null,"previous_names":["adnanmula/keyforge-game-log-parser"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/adnanmula/keyforge-game-log-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adnanmula%2Fkeyforge-game-log-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adnanmula%2Fkeyforge-game-log-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adnanmula%2Fkeyforge-game-log-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adnanmula%2Fkeyforge-game-log-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adnanmula","download_url":"https://codeload.github.com/adnanmula/keyforge-game-log-parser/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adnanmula%2Fkeyforge-game-log-parser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30332281,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T05:25:20.737Z","status":"ssl_error","status_checked_at":"2026-03-10T05:25:17.430Z","response_time":106,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["keyforge"],"created_at":"2025-06-03T20:07:20.311Z","updated_at":"2026-03-10T11:31:45.291Z","avatar_url":"https://github.com/adnanmula.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# KeyForge Game Log Parser\n\nParse The Crucible game logs into a structured model.\n\n## Requirements\n- PHP \u003e= 8.4\n\n## Installation\nInstall via Composer:\n\n```bash\ncomposer require adnanmula/keyforge-game-log-parser\n```\n\n## Quick start\n\n```php\n\u003c?php\n\nuse AdnanMula\\KeyforgeGameLogParser\\Event\\EventType;\nuse AdnanMula\\KeyforgeGameLogParser\\Parser\\GameLogParser;\nuse AdnanMula\\KeyforgeGameLogParser\\Parser\\ParseType;\n\n$log = file_get_contents('path/to/log.txt');\n\n$parser = new GameLogParser();\n$game = $parser-\u003eexecute($log, ParseType::PLAIN);\n\n$winner = $game-\u003ewinner()?-\u003ename;\n$keysForged = $game-\u003etimeline()-\u003efilter(EventType::KEY_FORGED)-\u003ecount();\n$reapsByPlayer1 = $game-\u003eplayer1-\u003etimeline-\u003efilter(EventType::REAP)-\u003ecount();\n$firstCreatureUsedToReapByPlayer1 = $game-\u003eplayer1-\u003etimeline-\u003efilter(EventType::REAP)-\u003eat(0)-\u003evalue;\n```\n\n### Input formats\nYou can parse logs provided in 3 different formats via `ParseType`:\n- `ParseType::PLAIN` (default): a single string containing the full log, what you get when use tco's copy to clipboard button.\n- `ParseType::ARRAY`: an array of strings containing the log messages, one per line.\n- `ParseType::HTML`: the HTML markup of the log view.\n\n```php\n\u003c?php\n\nuse AdnanMula\\KeyforgeGameLogParser\\Parser\\GameLogParser;\nuse AdnanMula\\KeyforgeGameLogParser\\Parser\\ParseType;\n\n$parser = new GameLogParser();\n\n$plainString = '\n    Alice brings Deck A to The Crucible\n    Bob brings Deck B to The Crucible\n    ...\n';\n\n// PLAIN\n$game1 = $parser-\u003eexecute($plainString, ParseType::PLAIN);\n\n// ARRAY\n$messages = [\n    'Alice brings Deck A to The Crucible',\n    'Bob brings Deck B to The Crucible',\n    // ...\n];\n$game2 = $parser-\u003eexecute($messages, ParseType::ARRAY);\n\n// HTML\n$html = '\u003cdiv class=\"message\"\u003eAlice brings Deck A to The Crucible\u003c/div\u003e...';\n$game3 = $parser-\u003eexecute($html, ParseType::HTML);\n```\n\n## Exploring results\n`execute()` returns a `Game` object with the following useful members:\n\n- `player1`, `player2` (AdnanMula\\KeyforgeGameLogParser\\Game\\Player)\n  - `name`, `deck`, `isFirst`, `isWinner`, `hasConceded`\n  - `timeline` (AdnanMula\\KeyforgeGameLogParser\\Game\\Timeline)\n- `winner(): ?Player`\n- `loser(): ?Player`\n- `first(): ?Player` (the player who took the first turn)\n- `timeline(): Timeline` (combined, time-ordered events from both players)\n\nTimelines are collections with helper methods:\n- `filter(EventType ...$events): Collection`\n- `count()`, `first()`, `last()`, `at(int $i)`, `items(): array`\n\nExample queries:\n\n```php\n\u003c?php\n\nuse AdnanMula\\KeyforgeGameLogParser\\Event\\EventType;\n\n// Checks declared across the whole game\n$checks = $game-\u003etimeline()-\u003efilter(EventType::CHECK_DECLARED)-\u003eitems();\n\n// Player-specific timeline queries\n$p1Checks = $game-\u003eplayer1-\u003etimeline-\u003efilter(EventType::CHECK_DECLARED)-\u003eitems();\n$p2Keys   = $game-\u003eplayer2-\u003etimeline-\u003efilter(EventType::KEY_FORGED)-\u003eitems();\n$reapsAndFights   = $game-\u003eplayer2-\u003etimeline-\u003efilter(EventType::REAP, EventType::FIGHT)-\u003eitems();\n\netc...\n```\n\n## Events\nThe library categorizes log messages into typed events via `EventType` enum:\n\n- AMBER_OBTAINED\n- AMBER_STOLEN\n- CARDS_DISCARDED\n- CARDS_DRAWN\n- CARDS_PLAYED\n- CARD_USED\n- HOUSE_CHOSEN\n- KEY_FORGED\n- FIGHT\n- REAP\n- EXTRA_TURN\n- TOKEN_CREATED\n- PROPHECY_ACTIVATED\n- PROPHECY_FULFILLED\n- FATE_RESOLVED\n- TIDE_RAISED\n- CHAINS_ADDED\n- CHAINS_REDUCED\n- PLAYER_CONCEDED\n- CHECK_DECLARED\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadnanmula%2Fkeyforge-game-log-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadnanmula%2Fkeyforge-game-log-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadnanmula%2Fkeyforge-game-log-parser/lists"}