PDO::ERRMODE_EXCEPTION ]); } catch (PDOException $e) { header('Content-Type: application/json'); exit(json_encode([ 'error' => true, 'message' => 'Database Error', 'debug' => $e->getMessage() ])); } use TrashBlx\Core\SoapUtils; $soapUtils = new SoapUtils(); $id = isset($_GET['assetId']) ? intval($_GET['assetId']) : null; $targetW = isset($_GET['width']) ? intval($_GET['width']) : null; $targetH = isset($_GET['height']) ? intval($_GET['height']) : null; $basePath = $_SERVER['DOCUMENT_ROOT'] . '/Thumbs/RenderedAssets/'; $imagePath = "{$basePath}{$id}.png"; $stmt = $pdo->prepare("SELECT AssetID, AssetType FROM assets WHERE AssetID = :id"); $stmt->execute(['id' => $id]); $asset = $stmt->fetch(PDO::FETCH_ASSOC); if (!$asset) { http_response_code(400); exit("Asset doesn't exist"); } //var_dump($asset); exit; if ($asset["AssetType"] === 1) { header("Location: /asset/?id=$id"); exit; } elseif($asset["AssetType"] === 2) { // Example TeeShirt XML content path and image path extraction $xmlContent = @file_get_contents("http://www.aftwld.com/asset?id=$id"); if ($xmlContent !== false) { //echo $xmlContent; $dom = new DOMDocument(); $dom->loadXML($xmlContent); // Use loadXML since you're loading a string, not a file $nodes = $dom->getElementsByTagName("Content"); $imgFile = null; foreach ($nodes as $node) { $imgFile = $node->nodeValue; break; } if(empty($imgFile)){ exit("fatal issue"); } if (str_contains($imgFile, "rbxassetid://")) { $assetId = str_replace("rbxassetid://", "", $imgFile); if (!is_numeric($assetId)) { exit("Invalid asset ID extracted: '$assetId'"); } $imgFile = "https://www.aftwld.com/asset?id=" . trim($assetId); }elseif (str_contains($imgFile, "roblox.com")) { $imgFile = str_replace("roblox.com", "aftwld.com", $imgFile); } $background = imagecreatefrompng($_SERVER['DOCUMENT_ROOT'] . "/Thumbs/tshirt.png"); function fetchImageFromUrl($url) { $url = trim($url); $url = filter_var($url, FILTER_SANITIZE_URL); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_CAINFO => $_SERVER['DOCUMENT_ROOT'] . '/asset/cacert.pem', CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_TIMEOUT => 10, CURLOPT_VERBOSE => true, // <--- show SSL and connection logs CURLOPT_STDERR => fopen('php://stderr', 'w'), // or a log file ]); $data = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $mimeType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); $err = curl_error($ch); curl_close($ch); if ($data === false) { exit("cURL error: $err $url"); } if ($httpCode === 200) { return $data; } exit("Failed to fetch image from $url — HTTP: $httpCode, MIME: $mimeType"); } if ($background && $imgFile) { $overlay = @imagecreatefromstring(fetchImageFromUrl($imgFile)); if ($overlay === false) { exit("Failed to load overlay image from $imgFile"); } if ($overlay !== false) { function cropTransparentPixels($img) { $width = imagesx($img); $height = imagesy($img); $minX = $width; $minY = $height; $maxX = 0; $maxY = 0; for ($y = 0; $y < $height; $y++) { for ($x = 0; $x < $width; $x++) { $rgba = imagecolorat($img, $x, $y); $alpha = ($rgba & 0x7F000000) >> 24; if ($alpha < 127) { // visible pixel if ($x < $minX) $minX = $x; if ($x > $maxX) $maxX = $x; if ($y < $minY) $minY = $y; if ($y > $maxY) $maxY = $y; } } } // Check if no visible pixels found if ($maxX < $minX || $maxY < $minY) { return null; } $cropWidth = $maxX - $minX + 1; $cropHeight = $maxY - $minY + 1; $cropped = imagecreatetruecolor($cropWidth, $cropHeight); imagealphablending($cropped, false); imagesavealpha($cropped, true); $transparent = imagecolorallocatealpha($cropped, 0, 0, 0, 127); imagefill($cropped, 0, 0, $transparent); imagecopy($cropped, $img, 0, 0, $minX, $minY, $cropWidth, $cropHeight); return $cropped; } // Preserve transparent areas from overlay image imagealphablending($overlay, false); imagesavealpha($overlay, true); $canvas = imagecreatetruecolor(420, 420); imagealphablending($canvas, false); imagesavealpha($canvas, true); $transparent = imagecolorallocatealpha($canvas, 0, 0, 0, 127); imagefill($canvas, 0, 0, $transparent); // Draw background imagecopyresampled($canvas, $background, 0, 0, 0, 0, 420, 420, imagesx($background), imagesy($background)); // Draw overlay with preserved alpha $boxX = $boxY = 84; $boxW = $boxH = 420 - 2 * $boxX; imagecopyresampled($canvas, $overlay, $boxX, $boxY, 0, 0, $boxW, $boxH, imagesx($overlay), imagesy($overlay)); header('Content-Type: image/png'); if($targetW === null || $targetH === null){ imagepng($canvas); imagedestroy($canvas); imagedestroy($overlay); imagedestroy($background); exit; } $dst = imagecreatetruecolor($targetW, $targetH); imagealphablending($dst, false); imagesavealpha($dst, true); imagecopyresampled($dst, $canvas, 0, 0, 0, 0, $targetW, $targetH, imagesx($canvas), imagesy($canvas)); imagepng($dst); exit; } } } } // If still no image, use fallback if (!file_exists($imagePath) || !is_readable($imagePath)) { // Call your rendering function $render = $soapUtils->renderAsset($id, $asset['AssetType']); if ($render) { $decrypted = base64_decode($render[0]); file_put_contents($imagePath, $decrypted); } } // If no width/height, serve as-is if ($targetW === null || $targetH === null) { if (!file_exists($imagePath) || !is_readable($imagePath)) { $imagePath = $_SERVER['DOCUMENT_ROOT'] . '/Thumbs/img.png'; // fallback } header('Content-Type: image/png'); header('Content-Length: ' . filesize($imagePath)); readfile($imagePath); exit; } // Rescale $src = imagecreatefrompng($imagePath); if (!$src) { header("HTTP/1.1 500 Internal Server Error"); exit; } $dst = imagecreatetruecolor($targetW, $targetH); imagealphablending($dst, false); imagesavealpha($dst, true); imagecopyresampled($dst, $src, 0, 0, 0, 0, $targetW, $targetH, imagesx($src), imagesy($src)); header('Content-Type: image/png'); imagepng($dst); imagedestroy($src); imagedestroy($dst); exit;