feat: Add dynamic favicons

This commit is contained in:
overflowerror 2024-08-08 22:31:52 +02:00
parent ad83911775
commit 5c3046d855
8 changed files with 106 additions and 5 deletions

View file

@ -38,7 +38,7 @@ $mobs = array_reduce($mobs, function ($mobs, $mob) {
echo "Downloading images...\n"; echo "Downloading images...\n";
foreach ($mobs as &$mob) { foreach ($mobs as &$mob) {
echo " ... " . $mob["name"] . "\n"; echo " ... " . $mob["name"] . "\n";
$filename = downloadImage($mob["image"], $mob["name"]); $filename = downloadImage($mob["image"], $mob["name"], "mobs");
$mob["filename"] = $filename; $mob["filename"] = $filename;
} }
@ -48,4 +48,22 @@ foreach ($mobs as &$mob) {
addOrUpdateMob($mob["name"], $mob["filename"]); addOrUpdateMob($mob["name"], $mob["filename"]);
} }
echo "Done."; echo "Fetching spawn egg image URLs...\n";
$spawnEggs = getSpawnEggsImages();
echo "Downloading images...\n";
foreach ($spawnEggs as &$spawnEgg) {
echo " ... " . $spawnEgg["name"] . "\n";
$filename = downloadImage($spawnEgg["image"], $spawnEgg["name"], "eggs");
$spawnEgg["filename"] = $filename;
}
echo "Making chimeras...\n";
foreach ($spawnEggs as $leftEgg) {
foreach ($spawnEggs as $rightEgg) {
echo " ... " . $leftEgg["name"] . " " . $rightEgg["name"] . "\n";
echo " -> " . makeChimera($leftEgg, $rightEgg, "eggs") . "\n";
}
}
echo "Done.\n";

1
html/images/eggs/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*

1
html/images/eggs/chimera/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*

View file

@ -3,6 +3,7 @@
require_once __DIR__ . "/../core.php"; require_once __DIR__ . "/../core.php";
require_once __DIR__ . "/../lib/pairing.php"; require_once __DIR__ . "/../lib/pairing.php";
require_once __DIR__ . "/../lib/rating.php"; require_once __DIR__ . "/../lib/rating.php";
require_once __DIR__ . "/../lib/favicon.php";
ensureSession(); ensureSession();
@ -13,12 +14,15 @@ function renderChoice(): void {
$ajax = isset($_GET["ajax"]); $ajax = isset($_GET["ajax"]);
$favicon = getFaviconUrl($left, $right);
if ($ajax) { if ($ajax) {
include __DIR__ . "/../view/fragments/mobSelection.php"; include __DIR__ . "/../view/fragments/mobSelection.php";
} else { } else {
$title = "MobMash - Vote"; $title = "MobMash - Vote";
$description = "Which Minecraft mob is the best? Vote for your favorite mob. MobMash uses a chess rating algorithm to calculate a definitive ranking."; $description = "Which Minecraft mob is the best? Vote for your favorite mob. MobMash uses a chess rating algorithm to calculate a definitive ranking.";
$content = function() use ($left, $right, $csrfToken) {
$content = function() use ($left, $right, $csrfToken, $favicon) {
include __DIR__ . "/../view/pages/mobSelection.php"; include __DIR__ . "/../view/pages/mobSelection.php";
}; };

11
lib/favicon.php Normal file
View file

@ -0,0 +1,11 @@
<?php
function getFaviconUrl($left, $right) {
$name = "/images/eggs/chimera/" .
strtolower(str_replace(" ", "_", $left["name"] . " " . $right["name"] . ".png"));
if (file_exists(__DIR__ . "/../html/" . $name)) {
return $name;
} else {
return "/images/eggs/spawn_egg.png";
}
}

View file

@ -78,14 +78,16 @@ function getImage(string $name): string {
} }
} }
function downloadImage(string $url, string $mobname): string { const IMAGE_BASE_PATH = __DIR__ . "/../html/images/";
function downloadImage(string $url, string $mobname, string $path): string {
$name = preg_replace( $name = preg_replace(
"/[^.]*(\.[a-zA-Z0-9]+).*/", "/[^.]*(\.[a-zA-Z0-9]+).*/",
strtolower(str_replace(" ", "_", $mobname)) . "$1", strtolower(str_replace(" ", "_", $mobname)) . "$1",
basename($url) basename($url)
); );
$file = fopen(__DIR__ . "/../html/images/mobs/" . $name, "w"); $file = fopen(IMAGE_BASE_PATH . $path . "/" . $name, "w");
$response = get($url); $response = get($url);
@ -109,4 +111,57 @@ function addOrUpdateMob(string $name, string $filename) {
$query->execute([$filename, $name]) or die("unable to update mob"); $query->execute([$filename, $name]) or die("unable to update mob");
echo " updated\n"; echo " updated\n";
} }
}
function getSpawnEggsImages(): array {
$wikiPage = handleWikiRequest("titles=Spawn_Egg&prop=revisions&rvprop=content");
$wikiText = getWikiTextFromResponse($wikiPage);
[, $iconSection] = explode("=== Icons ===", $wikiText);
[$iconSection, ] = explode("===", $iconSection);
$matches = [];
preg_match_all("/([a-zA-Z0-9_ -]+.png)/", $iconSection, $matches);
return array_filter(
array_map(
fn ($image) => [
"name" => trim(
str_replace("Spawn Egg.png", "", $image)
) ?: "Spawn Egg",
"image" => getImageUrlFromName($image)
],
array_filter(
array_unique($matches[1]),
fn($image) => !str_contains($image, "BE")
)
),
fn ($image) => !!$image["image"]
);
}
function makeChimera(array $left, array $right, string $path): string
{
$imageLeft = new Imagick(IMAGE_BASE_PATH . $path . "/" . $left["filename"]);
$imageRight = new Imagick(IMAGE_BASE_PATH . $path . "/" . $right["filename"]);
$height = min($imageLeft->getImageHeight(), $imageRight->getImageHeight());
$imageLeft->resizeImage(0, $height, Imagick::FILTER_LANCZOS, 1);
$imageLeft->cropImage($height / 2, $height, 0, 0);
$imageRight->resizeImage(0, $height, Imagick::FILTER_LANCZOS, 1);
$imageRight->cropImage($height / 2, $height, $height / 2, 0);
$chimera = new Imagick();
$chimera->newImage($height, $height, new ImagickPixel("transparent"));
$chimera->compositeImage($imageLeft, Imagick::COMPOSITE_DEFAULT, 0, 0);
$chimera->compositeImage($imageRight, Imagick::COMPOSITE_DEFAULT, $height / 2, 0);
$name = strtolower(str_replace(" ", "_", $left["name"] . " " . $right["name"] . ".png"));
$chimera->setImageFormat('png');
$chimera->writeImage(IMAGE_BASE_PATH . $path . "/chimera/" . $name);
$chimera->destroy();
return $name;
} }

View file

@ -1,5 +1,7 @@
<div class="selection"> <div class="selection">
<?php <?php
$favicon ??= "";
$mob = $left ?? []; $mob = $left ?? [];
$side = "left"; $side = "left";
include __DIR__ . "/mob.php"; include __DIR__ . "/mob.php";
@ -21,4 +23,10 @@
$side = "right"; $side = "right";
include __DIR__ . "/mob.php"; include __DIR__ . "/mob.php";
?> ?>
<script>
(function() {
let favicon = document.querySelector("link[rel~='icon']");
favicon.href = "<?= $favicon ?>";
})();
</script>
</div> </div>

View file

@ -1,5 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<?php <?php
$favicon ??= "/images/eggs/spawn_egg.png";
function makeNavigationLink(string $name, string $url, bool $newTab = false): void { function makeNavigationLink(string $name, string $url, bool $newTab = false): void {
$currentPath = rtrim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), "/"); $currentPath = rtrim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), "/");
$targetPath = rtrim(parse_url($url, PHP_URL_PATH), "/"); $targetPath = rtrim(parse_url($url, PHP_URL_PATH), "/");
@ -17,6 +19,7 @@
<meta name="description" content="<?= $description ?? "" ?>"> <meta name="description" content="<?= $description ?? "" ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" type="image/png" href="<?= $favicon ?>">
<link rel="stylesheet" type="text/css" href="/styles/main.css" /> <link rel="stylesheet" type="text/css" href="/styles/main.css" />
<link rel="stylesheet" type="text/css" href="/styles/fonts.css" /> <link rel="stylesheet" type="text/css" href="/styles/fonts.css" />
<link rel="stylesheet" type="text/css" href="/styles/emoji.css" /> <link rel="stylesheet" type="text/css" href="/styles/emoji.css" />