Autosave: 20260218-141308

This commit is contained in:
Flatlogic Bot 2026-02-18 14:13:08 +00:00
parent 09fa2a7096
commit 05c351eb39
10 changed files with 320 additions and 37 deletions

View File

@ -6,13 +6,33 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? 'create';
$user_id = $_SESSION['user_id'];
if ($action === 'refresh_invite_code') {
header('Content-Type: application/json');
$server_id = $_POST['server_id'] ?? 0;
require_once 'includes/permissions.php';
if (Permissions::hasPermission($user_id, $server_id, Permissions::MANAGE_SERVER)) {
$new_code = generateSecureInviteCode();
$expiry_ts = time() + 1800; // 30 minutes
$expires_at = date('Y-m-d H:i:s', $expiry_ts);
$stmt = db()->prepare("UPDATE servers SET invite_code = ?, invite_code_expires_at = ? WHERE id = ?");
$stmt->execute([$new_code, $expires_at, $server_id]);
echo json_encode(['success' => true, 'invite_code' => $new_code, 'expires_at' => $expires_at, 'expiry_timestamp' => $expiry_ts]);
} else {
echo json_encode(['success' => false, 'error' => 'Permission denied']);
}
exit;
}
if ($action === 'join') {
$invite_code = $_POST['invite_code'] ?? '';
$stmt = db()->prepare("SELECT id FROM servers WHERE invite_code = ?");
$stmt = db()->prepare("SELECT id, invite_code_expires_at FROM servers WHERE invite_code = ?");
$stmt->execute([$invite_code]);
$server = $stmt->fetch();
if ($server) {
if (!empty($server['invite_code_expires_at']) && strtotime($server['invite_code_expires_at']) < time()) {
die("Invite code has expired.");
}
$stmt = db()->prepare("INSERT IGNORE INTO server_members (server_id, user_id) VALUES (?, ?)");
$stmt->execute([$server['id'], $user_id]);
header('Location: index.php?server_id=' . $server['id']);
@ -56,9 +76,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$db->beginTransaction();
// Create server
$invite_code = substr(strtoupper(md5(uniqid())), 0, 8);
$stmt = $db->prepare("INSERT INTO servers (name, owner_id, invite_code, icon_url) VALUES (?, ?, ?, ?)");
$stmt->execute([$name, $user_id, $invite_code, $icon_url]);
$invite_code = generateSecureInviteCode();
$expires_at = date('Y-m-d H:i:s', time() + 1800);
$stmt = $db->prepare("INSERT INTO servers (name, owner_id, invite_code, invite_code_expires_at, icon_url) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$name, $user_id, $invite_code, $expires_at, $icon_url]);
$server_id = $db->lastInsertId();
// Add owner as member

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -6,23 +6,49 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? '';
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$invite_code = $_POST['invite_code'] ?? '';
if ($username && $email && $password) {
$hash = password_hash($password, PASSWORD_DEFAULT);
try {
$stmt = db()->prepare("INSERT INTO users (username, display_name, email, password_hash) VALUES (?, ?, ?, ?)");
$stmt->execute([$username, $username, $email, $hash]);
$userId = db()->lastInsertId();
// Add to default server
$stmt = db()->prepare("INSERT IGNORE INTO server_members (server_id, user_id) VALUES (1, ?)");
$stmt->execute([$userId]);
$target_server_id = 1;
$can_register = true;
$_SESSION['user_id'] = $userId;
header('Location: ../index.php');
exit;
} catch (Exception $e) {
$error = "Registration failed: " . $e->getMessage();
if (defined('PRIVATE_REGISTRATION') && PRIVATE_REGISTRATION && empty($invite_code)) {
$can_register = false;
$error = "Invite code is required for private registration.";
}
if ($can_register && !empty($invite_code)) {
$stmt = db()->prepare("SELECT id, invite_code_expires_at FROM servers WHERE invite_code = ?");
$stmt->execute([$invite_code]);
$server = $stmt->fetch();
if (!$server) {
$can_register = false;
$error = "Invalid invite code.";
} elseif (!empty($server['invite_code_expires_at']) && strtotime($server['invite_code_expires_at']) < time()) {
$can_register = false;
$error = "Invite code has expired.";
} else {
$target_server_id = $server['id'];
}
}
if ($can_register) {
$hash = password_hash($password, PASSWORD_DEFAULT);
try {
$stmt = db()->prepare("INSERT INTO users (username, display_name, email, password_hash) VALUES (?, ?, ?, ?)");
$stmt->execute([$username, $username, $email, $hash]);
$userId = db()->lastInsertId();
// Add to target server
$stmt = db()->prepare("INSERT IGNORE INTO server_members (server_id, user_id) VALUES (?, ?)");
$stmt->execute([$target_server_id, $userId]);
$_SESSION['user_id'] = $userId;
header('Location: ../index.php');
exit;
} catch (Exception $e) {
$error = "Registration failed: " . $e->getMessage();
}
}
} else {
$error = "Please fill all fields.";
@ -67,6 +93,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<label class="form-label">Password</label>
<input type="password" name="password" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Invite Code <?php echo (defined('PRIVATE_REGISTRATION') && PRIVATE_REGISTRATION) ? '' : '(Optional)'; ?></label>
<input type="text" name="invite_code" class="form-control" placeholder="Enter your invitation code" <?php echo (defined('PRIVATE_REGISTRATION') && PRIVATE_REGISTRATION) ? 'required' : ''; ?>>
</div>
<button type="submit" class="btn btn-blurple">Continue</button>
<div class="auth-footer">
Already have an account? <a href="login.php">Login</a>

View File

@ -1 +1 @@
{"de65a0b0b1a29c9a":{"id":"de65a0b0b1a29c9a","user_id":2,"name":"swefpifh ᵇʰᶠʳ","avatar_url":"","last_seen":1771343410040}}
[]

View File

@ -0,0 +1,4 @@
{"from":"d52b05b241a00981","to":"dab810918717cee5","data":{"type":"voice_speaking","channel_id":"3","user_id":2,"speaking":true},"time":1771423958367}
{"from":"d52b05b241a00981","to":"dab810918717cee5","data":{"type":"voice_speaking","channel_id":"3","user_id":2,"speaking":false},"time":1771423959219}
{"from":"d52b05b241a00981","to":"dab810918717cee5","data":{"type":"voice_speaking","channel_id":"3","user_id":2,"speaking":true},"time":1771423959434}
{"from":"d52b05b241a00981","to":"dab810918717cee5","data":{"type":"voice_speaking","channel_id":"3","user_id":2,"speaking":false},"time":1771423967708}

View File

@ -1 +1 @@
{"920464469dc771ed":{"id":"920464469dc771ed","user_id":3,"name":"swefheim","avatar_url":"","last_seen":1771343410598}}
{"d52b05b241a00981":{"id":"d52b05b241a00981","user_id":2,"name":"swefpifh ᵇʰᶠʳ","avatar_url":"","last_seen":1771423987533},"c96c42356d6a3ee4":{"id":"c96c42356d6a3ee4","user_id":3,"name":"swefheim","avatar_url":"","last_seen":1771423988087}}

View File

@ -16,6 +16,18 @@ function db() {
return $pdo;
}
define('PRIVATE_REGISTRATION', true);
function generateSecureInviteCode() {
$length = random_int(8, 12);
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()';
$code = '';
for ($i = 0; $i < $length; $i++) {
$code .= $chars[random_int(0, strlen($chars) - 1)];
}
return $code;
}
function enforceChannelLimit($channel_id) {
$stmt = db()->prepare("SELECT message_limit FROM channels WHERE id = ?");
$stmt->execute([$channel_id]);

118
index.php
View File

@ -147,6 +147,19 @@ $stmt = db()->prepare("
");
$stmt->execute([$current_user_id]);
$servers = $stmt->fetchAll();
// Automatic rotation of expired invite codes for owned servers
foreach ($servers as &$s) {
if ($s['owner_id'] == $current_user_id && (empty($s['invite_code_expires_at']) || strtotime($s['invite_code_expires_at']) < time())) {
$new_code = generateSecureInviteCode();
$new_expiry = date('Y-m-d H:i:s', time() + 1800);
$stmt = db()->prepare("UPDATE servers SET invite_code = ?, invite_code_expires_at = ? WHERE id = ?");
$stmt->execute([$new_code, $new_expiry, $s['id']]);
$s['invite_code'] = $new_code;
$s['invite_code_expires_at'] = $new_expiry;
}
}
unset($s);
$is_dm_view = (isset($_GET['server_id']) && $_GET['server_id'] == 'dms') || !isset($_GET['server_id']) && empty($servers);
if ($is_dm_view) {
@ -1518,12 +1531,87 @@ async function handleSaveUserSettings(btn) {
<label class="form-label text-uppercase fw-bold" style="font-size: 0.7em; color: var(--text-muted);">Invite Code</label>
<?php
$invite = '';
foreach($servers as $s) if($s['id'] == $active_server_id) $invite = $s['invite_code'];
$expiry = '';
foreach($servers as $s) {
if($s['id'] == $active_server_id) {
$invite = $s['invite_code'];
$expiry = $s['invite_code_expires_at'];
}
}
?>
<div class="input-group">
<input type="text" class="form-control bg-dark text-white border-0" value="<?php echo $invite; ?>" readonly>
<button class="btn btn-secondary" type="button" onclick="navigator.clipboard.writeText('<?php echo $invite; ?>')">Copy</button>
<input type="text" id="server-invite-code-input" class="form-control bg-dark text-white border-0" value="<?php echo htmlspecialchars($invite); ?>" readonly>
<button class="btn btn-secondary" type="button" onclick="navigator.clipboard.writeText(document.getElementById('server-invite-code-input').value)">Copy</button>
<button class="btn btn-outline-info" type="button" id="refresh-invite-code-btn">
<i class="fa-solid fa-sync"></i> Refresh
</button>
</div>
<div id="invite-expiry-timer" class="small mt-1" style="font-size: 0.75em; color: var(--text-muted);">
Expire dans : <span id="invite-countdown">--:--</span>
</div>
<script>
(function() {
let expiryTime = <?php echo $expiry ? strtotime($expiry) * 1000 : 0; ?>;
let countdownInterval;
function updateCountdown() {
const now = new Date().getTime();
const distance = expiryTime - now;
if (distance < 0) {
document.getElementById('invite-countdown').innerHTML = "Expired (Refresh needed)";
document.getElementById('invite-countdown').classList.add('text-danger');
return;
}
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById('invite-countdown').innerHTML =
(minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
document.getElementById('invite-countdown').classList.remove('text-danger');
}
if (expiryTime > 0) {
updateCountdown();
countdownInterval = setInterval(updateCountdown, 1000);
}
document.getElementById('refresh-invite-code-btn').addEventListener('click', async function() {
const btn = this;
const originalInner = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i>';
const formData = new FormData();
formData.append('action', 'refresh_invite_code');
formData.append('server_id', '<?php echo $active_server_id; ?>');
try {
const resp = await fetch('api_v1_servers.php', {
method: 'POST',
body: formData
});
const result = await resp.json();
if (result.success) {
document.getElementById('server-invite-code-input').value = result.invite_code;
expiryTime = result.expiry_timestamp * 1000;
updateCountdown();
if (countdownInterval) clearInterval(countdownInterval);
countdownInterval = setInterval(updateCountdown, 1000);
} else {
alert('Error: ' + result.error);
}
} catch (e) {
console.error(e);
alert('Connection error');
} finally {
btn.disabled = false;
btn.innerHTML = originalInner;
}
});
})();
</script>
</div>
<hr class="border-secondary">
@ -1997,15 +2085,16 @@ async function handleSaveUserSettings(btn) {
<div class="row h-100 g-0 border rounded border-secondary overflow-hidden" style="background-color: #2b2d31;">
<!-- Sidebar: Roles & Members -->
<div class="col-4 border-end border-secondary d-flex flex-column" style="background-color: #2b2d31;">
<div class="p-3 border-bottom border-secondary d-flex justify-content-between align-items-center">
<span class="small fw-bold text-uppercase" style="font-size: 0.7em; color: #dbdee1;">Roles / Members</span>
<div class="dropdown">
<button class="btn btn-sm btn-link text-white p-0" type="button" data-bs-toggle="dropdown" title="Add Role or Member" style="text-decoration: none; opacity: 0.8;">
<i class="fa-solid fa-plus-circle" style="font-size: 1.1rem;"></i>
</button>
<ul class="dropdown-menu dropdown-menu-dark shadow border-secondary" id="add-permission-role-list" style="max-height: 300px; overflow-y: auto; min-width: 200px;">
<!-- Roles loaded here -->
</ul>
<div class="p-3 border-bottom border-secondary d-flex justify-content-between align-items-center">
<span class="small fw-bold text-uppercase" style="font-size: 0.7em; color: #dbdee1;">Roles / Members</span>
<div class="dropdown">
<button class="btn btn-sm btn-link text-white p-0" type="button" data-bs-toggle="dropdown" title="Add Role or Member" style="text-decoration: none; opacity: 0.8;">
<i class="fa-solid fa-plus-circle" style="font-size: 1.1rem;"></i>
</button>
<ul class="dropdown-menu dropdown-menu-dark shadow border-secondary" id="add-permission-role-list" style="max-height: 300px; overflow-y: auto; min-width: 200px;">
<!-- Roles loaded here -->
</ul>
</div>
</div>
<div id="channel-permissions-roles-list" class="list-group list-group-flush overflow-auto flex-grow-1" style="max-height: 350px; overflow-x: hidden;">
<!-- List of roles with overrides -->
@ -2075,11 +2164,6 @@ async function handleSaveUserSettings(btn) {
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Pinned Messages Modal -->
<div class="modal fade" id="pinnedMessagesModal" tabindex="-1">

View File

@ -632,3 +632,135 @@
{"date":"2026-02-17 15:47:36","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0.06","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
{"date":"2026-02-17 15:48:00","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
{"date":"2026-02-17 15:48:41","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.06","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
2026-02-17 15:52:14 - GET /index.php - POST: []
2026-02-17 15:52:18 - GET /?fl_project=38443 - POST: []
2026-02-17 17:00:36 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-17 17:00:43 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-17 17:09:01 - GET /?fl_project=38443 - POST: []
2026-02-17 17:47:44 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-17 17:52:41 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-17 17:52:44 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 17:54:04 - GET /index.php - POST: []
2026-02-17 17:54:25 - GET /index.php - POST: []
{"date":"2026-02-17 17:55:17","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
{"date":"2026-02-17 17:55:43","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.5","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
{"date":"2026-02-17 17:55:49","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0.5","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
{"date":"2026-02-17 17:56:46","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.16","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
{"date":"2026-02-17 17:56:59","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.11","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
{"date":"2026-02-17 17:57:07","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.06","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
2026-02-17 17:57:42 - GET /index.php - POST: []
2026-02-17 17:59:06 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 18:00:37 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 18:00:49 - GET /index.php - POST: []
2026-02-17 18:29:50 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 18:30:16 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 18:30:54 - GET /index.php - POST: []
2026-02-17 18:30:59 - GET /index.php?server_id=1&channel_id=1 - POST: []
{"date":"2026-02-17 18:31:34","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.3","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
2026-02-17 18:32:20 - GET /index.php?server_id=1&channel_id=1 - POST: []
{"date":"2026-02-17 18:32:53","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0.3","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
2026-02-17 18:33:29 - GET /index.php?server_id=1&channel_id=6 - POST: []
{"date":"2026-02-17 18:33:54","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0.06","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
2026-02-17 18:53:11 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-17 18:53:18 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-17 18:53:28 - GET /index.php?server_id=1&channel_id=6 - POST: []
{"date":"2026-02-17 18:53:57","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.2","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
2026-02-17 18:54:39 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 18:54:59 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 19:10:20 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-17 19:10:33 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-17 19:10:34 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-17 19:11:03 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-17 19:11:17 - GET /index.php?server_id=1&channel_id=1 - POST: []
{"date":"2026-02-17 19:11:38","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.3","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
{"date":"2026-02-17 19:11:53","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0.3","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
2026-02-17 19:12:20 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-17 19:12:26 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-17 19:35:39 - GET /index.php?server_id=1&channel_id=6 - POST: []
{"date":"2026-02-17 19:35:57","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.12","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
2026-02-17 19:36:43 - GET /index.php?server_id=1&channel_id=17 - POST: []
2026-02-17 19:36:45 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-17 23:03:09 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-17 23:03:27 - GET /index.php - POST: []
2026-02-17 23:03:34 - GET /index.php - POST: []
2026-02-17 23:04:21 - GET /index.php - POST: []
2026-02-17 23:38:37 - GET /index.php - POST: []
2026-02-17 23:43:09 - GET /index.php - POST: []
2026-02-17 23:59:28 - GET /index.php - POST: []
2026-02-18 00:23:11 - GET / - POST: []
2026-02-18 07:48:39 - GET / - POST: []
2026-02-18 07:49:09 - GET / - POST: []
2026-02-18 07:49:44 - GET /?fl_project=38443 - POST: []
2026-02-18 07:50:57 - GET /index.php - POST: []
2026-02-18 07:52:10 - GET /?fl_project=38443 - POST: []
2026-02-18 07:52:18 - GET /index.php - POST: []
2026-02-18 07:53:28 - GET / - POST: []
2026-02-18 07:53:36 - GET /index.php - POST: []
2026-02-18 07:58:29 - GET /?fl_project=38443 - POST: []
2026-02-18 08:18:05 - GET /index.php - POST: []
2026-02-18 08:18:31 - GET /?fl_project=38443 - POST: []
2026-02-18 08:19:40 - GET /?fl_project=38443 - POST: []
2026-02-18 08:24:12 - GET /index.php - POST: []
2026-02-18 08:24:26 - GET /index.php - POST: []
2026-02-18 08:24:29 - GET /?fl_project=38443 - POST: []
2026-02-18 08:25:32 - GET /?fl_project=38443 - POST: []
2026-02-18 08:25:40 - GET /?fl_project=38443 - POST: []
2026-02-18 08:39:54 - GET /index.php - POST: []
2026-02-18 08:45:21 - GET /?fl_project=38443 - POST: []
2026-02-18 08:49:08 - GET /?fl_project=38443 - POST: []
2026-02-18 08:49:18 - GET /index.php - POST: []
2026-02-18 08:49:36 - GET /index.php - POST: []
2026-02-18 08:49:55 - GET /index.php - POST: []
2026-02-18 08:52:31 - GET /?fl_project=38443 - POST: []
2026-02-18 08:53:44 - GET /index.php - POST: []
2026-02-18 08:54:25 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:54:27 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:54:30 - GET /index.php?server_id=1 - POST: []
2026-02-18 08:54:31 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:54:33 - GET /index.php?server_id=1 - POST: []
2026-02-18 08:54:36 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:54:44 - GET /index.php?server_id=1 - POST: []
2026-02-18 08:54:53 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:55:06 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:55:12 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:55:27 - GET /index.php?server_id=1 - POST: []
2026-02-18 08:55:44 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:55:49 - GET /index.php?server_id=1 - POST: []
2026-02-18 08:57:02 - GET /index.php?server_id=1&channel_id=17 - POST: []
2026-02-18 08:57:05 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-18 08:57:15 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-18 08:57:17 - GET /index.php - POST: []
2026-02-18 08:57:55 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:58:06 - GET /index.php?server_id=3 - POST: []
2026-02-18 08:59:26 - GET /index.php?server_id=1 - POST: []
2026-02-18 09:00:27 - GET /index.php - POST: []
2026-02-18 09:02:33 - GET /index.php - POST: []
{"date":"2026-02-18 09:03:05","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.16","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
{"date":"2026-02-18 09:03:34","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.06","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
{"date":"2026-02-18 09:04:11","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.12","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
2026-02-18 09:04:26 - GET /index.php?server_id=1 - POST: []
{"date":"2026-02-18 09:04:42","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0.12","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
{"date":"2026-02-18 09:04:51","method":"POST","post":{"avatar_url":"","display_name":"swefheim","theme":"light","voice_mode":"ptt","voice_ptt_key":"v","voice_vox_threshold":"0.06","dnd_mode":"0","sound_notifications":"0"},"session":{"user_id":3},"user_id":3,"db_success":true}
2026-02-18 09:06:29 - GET /index.php?server_id=3 - POST: []
2026-02-18 09:06:32 - GET /index.php?server_id=1 - POST: []
2026-02-18 09:06:58 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-18 09:07:01 - GET /index.php?server_id=1&channel_id=17 - POST: []
2026-02-18 09:07:04 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-18 09:07:07 - GET /index.php?server_id=1&channel_id=21 - POST: []
2026-02-18 09:08:05 - GET /index.php?server_id=3 - POST: []
2026-02-18 09:08:22 - GET /index.php?server_id=1 - POST: []
2026-02-18 09:16:08 - GET /?fl_project=38443 - POST: []
2026-02-18 09:16:53 - GET /index.php?server_id=1 - POST: []
2026-02-18 09:17:08 - GET /index.php?server_id=3 - POST: []
2026-02-18 09:17:12 - GET /index.php?server_id=3 - POST: []
2026-02-18 09:17:26 - GET /index.php?server_id=3 - POST: []
2026-02-18 13:33:59 - GET /index.php?server_id=1 - POST: []
2026-02-18 13:41:53 - GET /index.php?server_id=1 - POST: []
{"date":"2026-02-18 13:52:05","method":"POST","post":{"avatar_url":"","display_name":"swefpifh \u1d47\u02b0\u1da0\u02b3","theme":"dark","voice_mode":"vox","voice_ptt_key":"v","voice_vox_threshold":"0.12","dnd_mode":"1","sound_notifications":"1"},"session":{"user_id":2},"user_id":2,"db_success":true}
2026-02-18 13:52:08 - GET /index.php?server_id=1 - POST: []
2026-02-18 13:52:20 - GET /index.php?server_id=1 - POST: []
2026-02-18 13:53:16 - GET /index.php - POST: []
2026-02-18 13:53:21 - GET /index.php - POST: []
2026-02-18 13:54:26 - GET /index.php?server_id=1 - POST: []
2026-02-18 13:54:43 - GET /index.php?server_id=1 - POST: []
2026-02-18 14:13:01 - GET /?fl_project=38443 - POST: []