1401a61e7Swikidesign<?php 21affe9b7Swikidesign/** 36e2b7c94Snerun * MonsterID Generator for DokuWiki Avatar Plugin 46e2b7c94Snerun * 56e2b7c94Snerun * Generates identicon-style monster avatars based on a seed. 66e2b7c94Snerun * Requires PHP GD extension. 76e2b7c94Snerun * 81affe9b7Swikidesign * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 91affe9b7Swikidesign * @author Andreas Gohr <andi@splitbrain.org> 106e2b7c94Snerun * @author Daniel Dias Rodrigues <danieldiasr@gmail.com> (modernization) 111affe9b7Swikidesign */ 12401a61e7Swikidesign 136e2b7c94Snerundeclare(strict_types=1); 146e2b7c94Snerun 156e2b7c94Snerunif (php_sapi_name() !== 'cli') { 166e2b7c94Snerun $seed = preg_replace('/[^a-f0-9]/i', '', $_GET['seed'] ?? ''); 176e2b7c94Snerun $size = (int) ($_GET['size'] ?? 120); 186e2b7c94Snerun $size = max(20, min(512, $size)); // limits between 20 and 512 pixels 196e2b7c94Snerun 206e2b7c94Snerun header('Content-Type: image/png'); 216e2b7c94Snerun header('Cache-Control: public, max-age=86400'); 226e2b7c94Snerun 236e2b7c94Snerun $image = generate_monster($seed, $size); 246e2b7c94Snerun if ($image) { 256e2b7c94Snerun imagepng($image); 266e2b7c94Snerun imagedestroy($image); 276e2b7c94Snerun } else { 286e2b7c94Snerun http_response_code(500); 296e2b7c94Snerun echo 'Erro ao gerar imagem.'; 306e2b7c94Snerun } 316e2b7c94Snerun exit; 326e2b7c94Snerun} 33401a61e7Swikidesign 341affe9b7Swikidesign/** 356e2b7c94Snerun * Generates monster image based on seed and size 361affe9b7Swikidesign */ 376e2b7c94Snerunfunction generate_monster(string $seed, int $size): ?GdImage 386e2b7c94Snerun{ 396e2b7c94Snerun if (!function_exists('imagecreatetruecolor')) { 406e2b7c94Snerun return null; 416e2b7c94Snerun } 426e2b7c94Snerun 432e0c1c6eSGina Haeussge $hash = md5($seed); 44401a61e7Swikidesign 456e2b7c94Snerun $parts = [ 466e2b7c94Snerun 'legs' => get_part(substr($hash, 0, 2), 1, 5), 476e2b7c94Snerun 'hair' => get_part(substr($hash, 2, 2), 1, 5), 486e2b7c94Snerun 'arms' => get_part(substr($hash, 4, 2), 1, 5), 496e2b7c94Snerun 'body' => get_part(substr($hash, 6, 2), 1, 15), 506e2b7c94Snerun 'eyes' => get_part(substr($hash, 8, 2), 1, 15), 516e2b7c94Snerun 'mouth' => get_part(substr($hash, 10, 2), 1, 10), 526e2b7c94Snerun ]; 53401a61e7Swikidesign 546e2b7c94Snerun $monster = imagecreatetruecolor(120, 120); 556e2b7c94Snerun if (!$monster) return null; 566e2b7c94Snerun 57*4bc5a549Snerun $white = @imagecolorallocate($monster, 255, 255, 255); 58401a61e7Swikidesign imagefill($monster, 0, 0, $white); 59401a61e7Swikidesign 606e2b7c94Snerun foreach ($parts as $part => $index) { 61*4bc5a549Snerun $filename = __DIR__ . '/parts/' . $part . '_' . $index . '.png'; 626e2b7c94Snerun if (!file_exists($filename)) continue; 636e2b7c94Snerun $part_img = imagecreatefrompng($filename); 64*4bc5a549Snerun imageSaveAlpha($part_img, true); 656e2b7c94Snerun if ($part_img) { 666e2b7c94Snerun imagecopy($monster, $part_img, 0, 0, 0, 0, 120, 120); 676e2b7c94Snerun imagedestroy($part_img); 68401a61e7Swikidesign } 69401a61e7Swikidesign } 70401a61e7Swikidesign 716e2b7c94Snerun if ($size !== 120) { 726e2b7c94Snerun $resized = imagecreatetruecolor($size, $size); 736e2b7c94Snerun imagefill($resized, 0, 0, $white); 746e2b7c94Snerun imagecopyresampled($resized, $monster, 0, 0, 0, 0, $size, $size, 120, 120); 75401a61e7Swikidesign imagedestroy($monster); 766e2b7c94Snerun return $resized; 77401a61e7Swikidesign } 782e0c1c6eSGina Haeussge 796e2b7c94Snerun return $monster; 802e0c1c6eSGina Haeussge} 812e0c1c6eSGina Haeussge 826e2b7c94Snerun/** 836e2b7c94Snerun * Converts part of the hash into an image index 846e2b7c94Snerun */ 856e2b7c94Snerunfunction get_part(string $hex, int $min, int $max): int 866e2b7c94Snerun{ 876e2b7c94Snerun $val = hexdec($hex); 886e2b7c94Snerun return ($val % ($max - $min + 1)) + $min; 89401a61e7Swikidesign} 9023415f0dSnerun 91