' . h($displayName) . '
'; echo ''; echo 'Basisdaten
'; echo '' . format_single($profile['profilePartner'] ?? '') . 'Keine Angabe'; } return nl2br(h($clean)); } function format_single(?string $value): string { $clean = trim((string) $value); return $clean === '' ? 'Keine Angabe' : h($clean); } function bool_to_label(?string $value): string { return ord((string) $value) ? 'Ja' : 'Nein'; } function fetch_asset_blob(mysqli $conn, string $assetId): ?string { $assetId = trim($assetId); if ($assetId === '') { return null; } $compact = strtolower(str_replace('-', '', $assetId)); $variants = [$assetId]; // OpenSim grids may store IDs with different UUID formatting. if ($compact !== '') { $variants[] = strtolower($assetId); $variants[] = strtoupper($assetId); $variants[] = $compact; } $variants = array_values(array_unique($variants)); $tables = ['assets', 'assets_0']; foreach ($tables as $tableName) { foreach ($variants as $candidate) { $stmt = $conn->prepare("SELECT data FROM {$tableName} WHERE id=? LIMIT 1"); if ($stmt === false) { continue; } $stmt->bind_param('s', $candidate); $stmt->execute(); $stmt->bind_result($blob); $found = $stmt->fetch(); $stmt->close(); if ($found && $blob !== null) { return $blob; } } } // Fallback for installations where `id` is stored as BINARY(16). if (preg_match('/^[0-9a-f]{32}$/', $compact) === 1) { foreach ($tables as $tableName) { $stmt = $conn->prepare("SELECT data FROM {$tableName} WHERE id=UNHEX(?) LIMIT 1"); if ($stmt !== false) { $stmt->bind_param('s', $compact); $stmt->execute(); $stmt->bind_result($blob); $found = $stmt->fetch(); $stmt->close(); if ($found && $blob !== null) { return $blob; } } } } return null; } function render_jp2_preview(?string $imgData, string $assetUuid): string { if ($assetUuid === '') { return '
Kein Bild im Profil eingetragen.
'; } if ($imgData === null || $imgData === '') { return 'Asset konnte nicht geladen werden (UUID vorhanden, aber kein Treffer in `assets`).
'; } if (!class_exists('Imagick')) { return 'Keine Vorschau verfuegbar (Imagick fehlt), Download ist moeglich.
'; } try { $imagickClass = 'Imagick'; $im = new $imagickClass(); $im->readImageBlob($imgData); $im->setImageFormat('jpeg'); $jpegData = $im->getImageBlob(); $im->clear(); $im->destroy(); return "Vorschau konnte nicht erzeugt werden.
'; } } $userInput = trim($_GET['user'] ?? ''); $isSearch = isset($_GET['user']); $error = ''; $profile = null; $avatarName = ''; $uuid = ''; $imgData = null; $firstImgData = null; $db = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME); if ($db->connect_errno) { $error = 'Datenbankverbindung fehlgeschlagen.'; } $assetDb = null; if ($error === '') { $assetDbName = defined('DB_ASSET_NAME') ? DB_ASSET_NAME : DB_NAME; if (!empty($assetDbName) && $assetDbName !== DB_NAME) { $assetDb = @new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, $assetDbName); if ($assetDb->connect_errno) { $assetDb = null; } } } if ($error === '' && $isSearch) { if ($userInput === '') { $error = 'Bitte gib einen Benutzernamen oder eine UUID ein.'; } else { $isUuid = preg_match('/^[0-9a-fA-F-]{36}$/', $userInput) === 1; if ($isUuid) { $uuid = $userInput; } else { $parts = preg_split('/\s+/', $userInput); if ($parts === false || count($parts) < 2) { $error = 'Bitte gib Vor- und Nachnamen an (z.B. Max Mustermann).'; } else { $first = $parts[0]; $last = $parts[1]; $stmt = $db->prepare('SELECT PrincipalID, FirstName, LastName FROM UserAccounts WHERE FirstName=? AND LastName=? LIMIT 1'); if ($stmt === false) { $error = 'Fehler beim Lesen der Benutzerdaten.'; } else { $stmt->bind_param('ss', $first, $last); $stmt->execute(); $stmt->bind_result($uuid, $firstNameResult, $lastNameResult); $found = $stmt->fetch(); $stmt->close(); if (!$found || $uuid === '') { $error = 'Benutzer nicht gefunden.'; } else { $avatarName = trim((string) $firstNameResult . ' ' . (string) $lastNameResult); } } } } } } if ($error === '' && $uuid !== '') { $stmt = $db->prepare('SELECT * FROM userprofile WHERE useruuid=? LIMIT 1'); if ($stmt === false) { $error = 'Fehler beim Lesen des Profils.'; } else { $stmt->bind_param('s', $uuid); $stmt->execute(); $result = $stmt->get_result(); $profile = $result ? $result->fetch_assoc() : null; $stmt->close(); } if ($profile === null) { $error = 'Kein Profil fuer diesen Benutzer gefunden.'; } } if ($error === '' && $uuid !== '' && $avatarName === '') { $stmt = $db->prepare('SELECT FirstName, LastName FROM UserAccounts WHERE PrincipalID=? LIMIT 1'); if ($stmt !== false) { $stmt->bind_param('s', $uuid); $stmt->execute(); $stmt->bind_result($firstNameResult, $lastNameResult); if ($stmt->fetch()) { $avatarName = trim((string) $firstNameResult . ' ' . (string) $lastNameResult); } $stmt->close(); } } if ($error === '' && $profile !== null) { if (!empty($profile['profileImage'])) { $imgData = fetch_asset_blob($db, trim((string) $profile['profileImage'])); if ($imgData === null && $assetDb instanceof mysqli) { $imgData = fetch_asset_blob($assetDb, trim((string) $profile['profileImage'])); } } if (!empty($profile['profileFirstImage'])) { $firstImgData = fetch_asset_blob($db, trim((string) $profile['profileFirstImage'])); if ($firstImgData === null && $assetDb instanceof mysqli) { $firstImgData = fetch_asset_blob($assetDb, trim((string) $profile['profileFirstImage'])); } } } $title = $avatarName !== '' ? $avatarName : ($uuid !== '' ? $uuid : 'OpenSim Nutzerprofil'); echo <<Suche nach einem Avatar via Vorname Nachname oder direkt per UUID. Die Ansicht zeigt Profildaten, Freitexte und vorhandene Bild-Assets in einer besser lesbaren Struktur.
HTML; if ($error !== '') { echo '' . format_single($profile['profilePartner'] ?? '') . '