import { useMemo, useState, useEffect } from "react"; type Status = | "ready" | "saved successfully" | "injection started" | "validating key..." | "invalid key" | "injecting..." | "RL Running" | "RL Closed" | string; interface UserInfo { user_id: string | null; discord_id: string | null; epic_id: string | null; username: string | null; global_name: string | null; logins?: number; } interface KeyValidationResponse { status: string; user: UserInfo | null; } const THEMES = [ { id: "phantom", label: "Phantom", color: "#a855f7" }, { id: "glacier", label: "Glacier", color: "#38bdf8" }, { id: "inferno", label: "Inferno", color: "#f97316" }, { id: "matrix", label: "Matrix", color: "#00ff41" }, { id: "synthwave", label: "Synthwave", color: "#f72585" }, { id: "eclipse", label: "Eclipse", color: "#fbbf24" }, ] as const; type ThemeId = typeof THEMES[number]["id"]; const LS_KEYS = { spoofed: "rlidentity.spoofedUsername", apiKey: "rlidentity.apiKey", minimizeToTray: "rlidentity.minimizeToTray", platform: "rlidentity.platform", autoInject: "rlidentity.autoInject", theme: "rlidentity.theme", } as const; const GITHUB_URL = "https://git.rlidentity.me/bits/rlidentity"; const FAQ_URL = "https://rlidentity.me/#faq"; function isTauriRuntime() { return typeof window !== "undefined" && typeof (window as any).__TAURI_INTERNALS__ !== "undefined"; } async function tryWindowApi(action: (win: any) => Promise) { if (!isTauriRuntime()) return; const mod: any = await import("@tauri-apps/api/window"); const win = mod.getCurrentWindow(); await action(win); } async function tryInvoke(cmd: string, args?: Record) { if (!isTauriRuntime()) return null; const mod: any = await import("@tauri-apps/api/core"); return (await mod.invoke(cmd, args)) as T; } async function openUrl(url: string) { const fallback = () => window.open(url, "_blank", "noopener,noreferrer"); if (!isTauriRuntime()) return fallback(); try { const mod: any = await import("@tauri-apps/plugin-opener"); if (typeof mod.openUrl === "function") { await mod.openUrl(url); return; } fallback(); } catch { fallback(); } } export default function App() { const initialApiKey = useMemo(() => localStorage.getItem(LS_KEYS.apiKey) ?? "", []); const initialSpoofed = useMemo(() => localStorage.getItem(LS_KEYS.spoofed) ?? "", []); const initialMinToTray = useMemo(() => localStorage.getItem(LS_KEYS.minimizeToTray) === "true", []); const initialPlatform = useMemo(() => localStorage.getItem(LS_KEYS.platform) ?? "Epic", []); const initialAutoInject = useMemo(() => localStorage.getItem(LS_KEYS.autoInject) === "true", []); const initialTheme = useMemo(() => (localStorage.getItem(LS_KEYS.theme) ?? "phantom") as ThemeId, []); const [version, setVersion] = useState(''); const [apiKey, setApiKey] = useState(initialApiKey); const [spoofedUsername, setSpoofedUsername] = useState(initialSpoofed); const [isAuthorized, setIsAuthorized] = useState(false); const [isRevoked, setIsRevoked] = useState(false); const [userData, setUserData] = useState(null); const [status, setStatus] = useState("ready"); const [rlStatus, setRlStatus] = useState("Checking..."); const [settingsOpen, setSettingsOpen] = useState(false); const [logsOpen, setLogsOpen] = useState(false); const [lastLog, setLastLog] = useState(""); const [minimizeToTray, setMinimizeToTray] = useState(initialMinToTray); const [platform, setPlatform] = useState(initialPlatform); const [autoInject, setAutoInject] = useState(initialAutoInject); const [platformPickerOpen, setPlatformPickerOpen] = useState(false); const [theme, setTheme] = useState(initialTheme); // Update modal const [pendingUpdate, setPendingUpdate] = useState<{ version: string; install: () => Promise } | null>(null); // Easter egg const [debugOpen, setDebugOpen] = useState(false); const [logoClicks, setLogoClicks] = useState(0); const handleLogoClick = (e: React.MouseEvent) => { e.stopPropagation(); setLogoClicks(prev => prev + 1); }; useEffect(() => { if (logoClicks >= 5) { setDebugOpen(true); setLogoClicks(0); } const timer = setTimeout(() => { if (logoClicks > 0) setLogoClicks(0); }, 1000); return () => clearTimeout(timer); }, [logoClicks]); // Apply theme useEffect(() => { document.documentElement.setAttribute("data-theme", theme); localStorage.setItem(LS_KEYS.theme, theme); }, [theme]); // Startup useEffect(() => { if (initialApiKey) authorize(initialApiKey); syncAssetsAndCheckUpdates(); tryInvoke("get_app_version").then(v => setVersion(v as string)); }, []); async function syncAssetsAndCheckUpdates() { if (!isTauriRuntime()) return; try { setStatus("syncing assets..."); await tryInvoke("download_assets"); setStatus("ready"); } catch (e) { console.error("Failed to sync assets:", e); setStatus("Sync Error: " + String(e)); } checkForUpdates(); } async function checkForUpdates() { if (!isTauriRuntime()) return; try { const { check } = await import("@tauri-apps/plugin-updater"); const update = await check(); if (update) { setPendingUpdate({ version: update.version, install: async () => { setStatus("Updating..."); await update.downloadAndInstall(); const { relaunch } = await import("@tauri-apps/plugin-process"); await relaunch(); }, }); } } catch (e) { console.error("Failed to check for updates:", e); } } // Revoked bg useEffect(() => { document.body.classList.toggle("revoked-bg", isRevoked); }, [isRevoked]); // Poll RL status + auto-inject useEffect(() => { if (!isAuthorized || isRevoked) return; const interval = setInterval(async () => { try { const res = await tryInvoke<{ is_running: boolean }>("check_status"); if (res) { const wasRunning = rlStatus === "RL Running"; const isRunning = res.is_running; setRlStatus(isRunning ? "RL Running" : "RL Closed"); if (!wasRunning && isRunning && autoInject) inject(); } } catch (e) { console.error(e); } }, 2000); return () => clearInterval(interval); }, [isAuthorized, isRevoked, rlStatus, autoInject]); async function authorize(keyToTry: string) { if (!keyToTry.trim()) { setStatus("Please enter a key"); return; } setStatus("validating key..."); setIsRevoked(false); try { const hwid = await tryInvoke("get_hwid") || "UNKNOWN-HWID"; const res = await tryInvoke("validate_key", { key: keyToTry.trim(), hwid }); if (res?.status === "valid") { localStorage.setItem(LS_KEYS.apiKey, keyToTry.trim()); setUserData(res.user); setIsAuthorized(true); setIsRevoked(false); setStatus("ready"); } else if (res?.status === "revoked") { setIsRevoked(true); setIsAuthorized(false); setStatus("Error: Key Revoked"); } else if (res?.status === "invalid_hwid") { setStatus("Error: Key locked to another PC"); setIsAuthorized(false); } else { setStatus("Error: Invalid key"); setIsAuthorized(false); } } catch { setStatus("Network Error: Check connection"); } } async function saveConfig() { localStorage.setItem(LS_KEYS.spoofed, spoofedUsername.trim()); localStorage.setItem(LS_KEYS.platform, platform); try { await tryInvoke("save_config", { name: spoofedUsername.trim(), platform }); setStatus("saved successfully"); window.setTimeout(() => setStatus("ready"), 1400); } catch (e) { setStatus("Save error: " + String(e)); } } async function inject() { setStatus("injecting..."); try { const res = await tryInvoke("inject_dll", { discordId: userData?.discord_id }); setLastLog(res || "Successfully Injected!"); setStatus("Successfully Injected!"); window.setTimeout(() => setStatus("ready"), 1400); } catch (e) { setStatus("Injection Failed!"); setLastLog(String(e)); setLogsOpen(true); } } function toggleMinimizeToTray(next: boolean) { setMinimizeToTray(next); localStorage.setItem(LS_KEYS.minimizeToTray, String(next)); } function toggleAutoInject(next: boolean) { setAutoInject(next); localStorage.setItem(LS_KEYS.autoInject, String(next)); } async function handleMinimizeClick() { if (!isTauriRuntime()) return; if (minimizeToTray) { await tryInvoke("minimize_to_tray"); } else { await tryWindowApi(w => w.minimize()); } } const logout = () => { localStorage.removeItem(LS_KEYS.apiKey); window.location.reload(); }; const closeAllModals = () => { setSettingsOpen(false); setLogsOpen(false); setDebugOpen(false); }; const isModalOpen = settingsOpen || logsOpen || debugOpen; // ── Auth screen ─────────────────────────────────────────────────────────── if (!isAuthorized) { return (
); } // ── Main app ────────────────────────────────────────────────────────────── return (
); }