|
|
|
|
@ -1,7 +1,7 @@ |
|
|
|
|
<?php |
|
|
|
|
session_start(); |
|
|
|
|
|
|
|
|
|
define('PASSWORD', 'cttue_avj2305_44'); |
|
|
|
|
define('PASSWORD', 'password'); |
|
|
|
|
define('FILES_DIR', __DIR__ . '/avj2305'); |
|
|
|
|
define('ACTIVE_FILE', __DIR__ . '/active.txt'); |
|
|
|
|
|
|
|
|
|
@ -39,6 +39,15 @@ function safe_filename(string $name): bool { |
|
|
|
|
&& !str_contains($name, "\0"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function has_png(string $bin_basename): bool { |
|
|
|
|
$png = substr($bin_basename, 0, -4) . '.png'; |
|
|
|
|
return file_exists(FILES_DIR . '/' . $png); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function png_path(string $bin_basename): string { |
|
|
|
|
return FILES_DIR . '/' . substr($bin_basename, 0, -4) . '.png'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ============================================================================= |
|
|
|
|
// ACTIONS (POST handlers - redirect, never render) |
|
|
|
|
// ============================================================================= |
|
|
|
|
@ -100,9 +109,12 @@ function render_edit(): never { |
|
|
|
|
h2{margin:0 0 16px} |
|
|
|
|
ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px} |
|
|
|
|
li form{margin:0} |
|
|
|
|
button{padding:6px 12px;background:#333;border:1px solid #555;color:#eee;cursor:pointer;width:100%;text-align:left} |
|
|
|
|
.row{display:flex;align-items:center;gap:10px} |
|
|
|
|
button{padding:6px 12px;background:#333;border:1px solid #555;color:#eee;cursor:pointer;flex:1;text-align:left} |
|
|
|
|
button:hover{background:#444} |
|
|
|
|
button.active{border-color:#6af;color:#6af} |
|
|
|
|
.thumb{width:480px;height:270px;object-fit:cover;border:1px solid #444;background:#222;flex-shrink:0} |
|
|
|
|
.nothumb{width:64px;height:64px;flex-shrink:0} |
|
|
|
|
.none{color:#888} |
|
|
|
|
</style> |
|
|
|
|
</head> |
|
|
|
|
@ -114,8 +126,15 @@ function render_edit(): never { |
|
|
|
|
<?php foreach ($files as $f): ?> |
|
|
|
|
<li> |
|
|
|
|
<form method="post" action="?edit"> |
|
|
|
|
<input type="hidden" name="file" value="<?= htmlspecialchars($f) ?>">
|
|
|
|
|
<button type="submit"<?= $f === $active ? ' class="active"' : '' ?>><?= htmlspecialchars($f) ?></button>
|
|
|
|
|
<div class="row"> |
|
|
|
|
<?php if (has_png($f)): ?> |
|
|
|
|
<img class="thumb" src="?img=<?= urlencode($f) ?>" alt="">
|
|
|
|
|
<?php else: ?> |
|
|
|
|
<div class="nothumb"></div> |
|
|
|
|
<?php endif; ?> |
|
|
|
|
<input type="hidden" name="file" value="<?= htmlspecialchars($f) ?>">
|
|
|
|
|
<button type="submit"<?= $f === $active ? ' class="active"' : '' ?>><?= htmlspecialchars($f) ?></button>
|
|
|
|
|
</div> |
|
|
|
|
</form> |
|
|
|
|
</li> |
|
|
|
|
<?php endforeach; ?> |
|
|
|
|
@ -130,6 +149,22 @@ function render_edit(): never { |
|
|
|
|
// FILE SERVER (default route) |
|
|
|
|
// ============================================================================= |
|
|
|
|
|
|
|
|
|
function serve_png(): never { |
|
|
|
|
require_auth(); |
|
|
|
|
$f = $_GET['img'] ?? ''; |
|
|
|
|
if (!safe_filename($f)) { |
|
|
|
|
http_response_code(400); exit('Invalid filename.'); |
|
|
|
|
} |
|
|
|
|
$path = png_path($f); |
|
|
|
|
if (!file_exists($path)) { |
|
|
|
|
http_response_code(404); exit('No preview.'); |
|
|
|
|
} |
|
|
|
|
header('Content-Type: image/png'); |
|
|
|
|
header('Content-Length: ' . filesize($path)); |
|
|
|
|
readfile($path); |
|
|
|
|
exit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function serve_active_file(): never { |
|
|
|
|
$active = get_active(); |
|
|
|
|
|
|
|
|
|
@ -158,11 +193,12 @@ function serve_active_file(): never { |
|
|
|
|
// ROUTES |
|
|
|
|
// ============================================================================= |
|
|
|
|
// |
|
|
|
|
// GET /live.php -> serve active .bin file |
|
|
|
|
// GET /live.php -> serve active .bin file |
|
|
|
|
// GET /live.php?login -> login page |
|
|
|
|
// POST /live.php?login -> process login |
|
|
|
|
// GET /live.php?edit -> file picker [auth required] |
|
|
|
|
// POST /live.php?edit -> set active file [auth required] |
|
|
|
|
// GET /live.php?edit -> file picker [auth required] |
|
|
|
|
// POST /live.php?edit -> set active file [auth required] |
|
|
|
|
// GET /live.php?img=x.bin -> serve x.png preview [auth required] |
|
|
|
|
// |
|
|
|
|
// ============================================================================= |
|
|
|
|
|
|
|
|
|
@ -174,5 +210,6 @@ match (true) { |
|
|
|
|
$method === 'POST' && $route === 'edit' => action_set_file(), |
|
|
|
|
$method === 'GET' && $route === 'login' => render_login(), |
|
|
|
|
$method === 'GET' && $route === 'edit' => render_edit(), |
|
|
|
|
$method === 'GET' && $route === 'img' => serve_png(), |
|
|
|
|
default => serve_active_file(), |
|
|
|
|
}; |
|
|
|
|
|