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 "Bildvorschau"; } catch (Exception $e) { 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 << OpenSim Nutzerprofil

OpenSim Nutzerprofil

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 '
' . h($error) . '
'; } elseif (!$isSearch) { echo '
Noch keine Suche ausgefuehrt. Gib oben einen Namen oder eine UUID ein.
'; } echo '
'; if ($error === '' && $profile !== null) { $displayName = $avatarName !== '' ? $avatarName : 'Unbekannter Avatar'; $profileImageUuid = trim((string) ($profile['profileImage'] ?? '')); $firstImageUuid = trim((string) ($profile['profileFirstImage'] ?? '')); $profileImageFile = $profileImageUuid !== '' && $imgData !== null ? 'data:image/jp2;base64,' . base64_encode($imgData) : ''; $firstImageFile = $firstImageUuid !== '' && $firstImgData !== null ? 'data:image/jp2;base64,' . base64_encode($firstImgData) : ''; echo '
'; echo '
'; echo '

' . h($displayName) . '

'; echo '

UUID: ' . h($uuid) . '

'; echo '

Basisdaten

'; echo '
'; echo '
Partner UUID
' . format_single($profile['profilePartner'] ?? '') . '
'; echo '
Mature Publish
' . bool_to_label($profile['profileMaturePublish'] ?? '') . '
'; echo '
Profil URL
' . format_single($profile['profileURL'] ?? '') . '
'; echo '
Sprachen
' . format_multiline($profile['profileLanguages'] ?? '') . '
'; echo '
'; echo '

Interessen und Skills

'; echo '
'; echo '
Will (Text)
' . format_multiline($profile['profileWantToText'] ?? '') . '
'; echo '
Skills (Text)
' . format_multiline($profile['profileSkillsText'] ?? '') . '
'; echo '
'; echo '

Freitexte

'; echo '
Ueber mich
' . format_multiline($profile['profileAboutText'] ?? '') . '
'; echo '
Erster Text
' . format_multiline($profile['profileFirstText'] ?? '') . '
'; echo '
'; echo ''; echo '
'; } echo '
'; if ($assetDb instanceof mysqli) { $assetDb->close(); } if ($db instanceof mysqli) { $db->close(); } ?>