connect_errno) { http_response_code(500); echo '

Database connection failed.

'; exit; } $db->set_charset('utf8mb4'); return $db; } function is_uuid(string $value): bool { return preg_match('/^[0-9a-fA-F-]{36}$/', $value) === 1; } function normalize_lookup_input(string $value): string { $v = trim(urldecode($value)); // Some viewers/grids may pass values wrapped in brackets, e.g. [uuid]. if (strlen($v) >= 2 && $v[0] === '[' && $v[strlen($v) - 1] === ']') { $v = substr($v, 1, -1); $v = trim($v); } return $v; } function resolve_user_uuid(mysqli $db, string $nameOrUuid): ?array { $input = normalize_lookup_input($nameOrUuid); if ($input === '') { return null; } if (is_uuid($input)) { $stmt = $db->prepare('SELECT PrincipalID, FirstName, LastName FROM UserAccounts WHERE PrincipalID = ? LIMIT 1'); if ($stmt !== false) { $stmt->bind_param('s', $input); $stmt->execute(); $stmt->bind_result($uuid, $first, $last); $found = $stmt->fetch(); $stmt->close(); if ($found) { return [ 'uuid' => (string)$uuid, 'name' => trim((string)$first . ' ' . (string)$last), ]; } } // UUID was passed by viewer but account row could not be resolved. // Continue with UUID so profile/picks queries can still work. return [ 'uuid' => $input, 'name' => $input, ]; } $normalized = strtolower(str_replace(' ', '.', $input)); $sql = 'SELECT PrincipalID, FirstName, LastName FROM UserAccounts WHERE LOWER(CONCAT(FirstName, ".", LastName)) = ? OR LOWER(CONCAT(FirstName, " ", LastName)) = ? LIMIT 1'; $stmt = $db->prepare($sql); if ($stmt === false) { return null; } $stmt->bind_param('ss', $normalized, $normalized); $stmt->execute(); $stmt->bind_result($uuid, $first, $last); $found = $stmt->fetch(); $stmt->close(); if (!$found) { return null; } return [ 'uuid' => (string)$uuid, 'name' => trim((string)$first . ' ' . (string)$last), ]; } function pick_lookup_value(): string { // Prefer explicit UUID-style parameters when available. $uuidParam = normalize_lookup_input((string)($_GET['uuid'] ?? '')); $avatarIdParam = normalize_lookup_input((string)($_GET['avatar_id'] ?? '')); $idParam = normalize_lookup_input((string)($_GET['id'] ?? '')); $nameParam = normalize_lookup_input((string)($_GET['name'] ?? '')); $userParam = normalize_lookup_input((string)($_GET['user'] ?? '')); foreach ([$uuidParam, $avatarIdParam, $idParam] as $candidate) { if ($candidate !== '' && is_uuid($candidate)) { return $candidate; } } if ($nameParam !== '') { return $nameParam; } if ($userParam !== '') { return $userParam; } foreach ([$uuidParam, $avatarIdParam, $idParam] as $candidate) { if ($candidate !== '') { return $candidate; } } return ''; } function load_user_profile(mysqli $db, string $uuid): ?array { $stmt = $db->prepare('SELECT * FROM userprofile WHERE useruuid = ? LIMIT 1'); if ($stmt === false) { return null; } $stmt->bind_param('s', $uuid); $stmt->execute(); $result = $stmt->get_result(); $profile = $result ? $result->fetch_assoc() : null; $stmt->close(); return $profile ?: null; } function load_user_picks(mysqli $db, string $uuid): array { $sql = 'SELECT pickuuid, name, description, simname, posglobal, snapshotuuid, gatekeeper, enabled, sortorder FROM userpicks WHERE creatoruuid = ? ORDER BY sortorder ASC, name ASC'; $stmt = $db->prepare($sql); if ($stmt === false) { return []; } $stmt->bind_param('s', $uuid); $stmt->execute(); $result = $stmt->get_result(); $rows = []; if ($result) { while ($row = $result->fetch_assoc()) { $rows[] = $row; } } $stmt->close(); return $rows; } $feedOnly = parse_bool((string)($_GET['feed_only'] ?? '0')); $diag = parse_bool((string)($_GET['diag'] ?? '0')); $lookup = pick_lookup_value(); $db = connect_main_db(); $user = $lookup !== '' ? resolve_user_uuid($db, $lookup) : null; $profile = null; $picks = []; if ($user !== null) { $profile = load_user_profile($db, $user['uuid']); $picks = load_user_picks($db, $user['uuid']); } $db->close(); $pageTitle = $user !== null ? ($user['name'] . ' - Viewer Feed') : 'Viewer Feed Bridge'; ?> <?php echo h($pageTitle); ?>

OpenSim Viewer Feed Bridge

Use with Firestorm Web Profile URL, for example:
/oswebinterface/viewerfeed.php?name=[AGENT_NAME]

No avatar provided. Add ?name=first.last or ?uuid=....

Avatar not found for:

UUID:


Diagnostics

raw query:

remote addr:

user-agent:

Profile

About:

First Life:

Profile URL:

No userprofile row found for this user.

Picks ()

No picks available.

sim: enabled: sort:

pickuuid: