1
0
Files
Bridges/HytaleNewsBridge.php
2025-11-24 19:16:06 +01:00

137 lines
4.1 KiB
PHP

<?php
declare(strict_types=1);
class HytaleNewsBridge extends BridgeAbstract
{
const MAINTAINER = 'Akamaru';
const NAME = 'Hytale News';
const URI = 'https://hytale.com/news';
const CACHE_TIMEOUT = 3600;
const DESCRIPTION = 'Get the latest news from Hytale!';
const PARAMETERS = [
[
'limit' => [
'name' => 'Max. Articles',
'type' => 'number',
'required' => false,
'defaultValue' => 20
]
]
];
public function getIcon()
{
return 'https://www.google.com/s2/favicons?domain=hytale.com&sz=32';
}
public function collectData()
{
$html = getContents(self::URI);
if (!$html) {
returnServerError('Could not load Hytale news page.');
}
// Find the JSON data in __INITIAL_COMPONENTS_STATE__
$marker = 'window.__INITIAL_COMPONENTS_STATE__ = ';
$startPos = strpos($html, $marker);
if ($startPos === false) {
returnServerError('Could not find initial state marker.');
}
$jsonStart = $startPos + strlen($marker);
// Find the matching closing bracket by counting brackets
$bracketCount = 0;
$jsonEnd = $jsonStart;
$len = strlen($html);
$inString = false;
$escapeNext = false;
for ($i = $jsonStart; $i < $len; $i++) {
$char = $html[$i];
if ($escapeNext) {
$escapeNext = false;
continue;
}
if ($char === '\\') {
$escapeNext = true;
continue;
}
if ($char === '"' && !$escapeNext) {
$inString = !$inString;
continue;
}
if ($inString) {
continue;
}
if ($char === '[') {
$bracketCount++;
} elseif ($char === ']') {
$bracketCount--;
if ($bracketCount === 0) {
$jsonEnd = $i + 1;
break;
}
}
}
$jsonStr = substr($html, $jsonStart, $jsonEnd - $jsonStart);
$jsonData = json_decode($jsonStr, true);
if (!$jsonData || !isset($jsonData[0]['posts'])) {
returnServerError('Could not extract posts data from page.');
}
$posts = $jsonData[0]['posts'];
$limit = $this->getInput('limit') ?? 20;
$count = 0;
foreach ($posts as $post) {
if ($count >= $limit) {
break;
}
$count++;
$item = [];
$item['title'] = $post['title'] ?? 'Untitled';
$item['author'] = $post['author'] ?? 'Hytale Team';
$item['uid'] = $post['_id'] ?? '';
// Build URI from publishedAt date and slug
$publishedAt = $post['publishedAt'] ?? null;
$slug = $post['slug'] ?? '';
if ($publishedAt && $slug) {
$date = new DateTime($publishedAt);
$year = $date->format('Y');
$month = $date->format('n'); // Month without leading zero
$item['uri'] = 'https://hytale.com/news/' . $year . '/' . $month . '/' . $slug;
$item['timestamp'] = $date->getTimestamp();
} else {
$item['uri'] = self::URI;
}
// Content with image
$content = '';
$imageUrl = null;
if (isset($post['coverImage']['s3Key'])) {
$s3Key = $post['coverImage']['s3Key'];
$imageUrl = 'https://cdn.hytale.com/variants/blog_cover_' . $s3Key;
$content .= '<p><img src="' . $imageUrl . '" alt="' . htmlspecialchars($item['title']) . '"></p>';
}
$content .= '<p>' . htmlspecialchars($post['bodyExcerpt'] ?? '') . '</p>';
$item['content'] = $content;
// Enclosure for image
if ($imageUrl) {
$item['enclosures'] = [$imageUrl];
}
$this->items[] = $item;
}
}
}