good work

This commit is contained in:
Marc Robin Richter
2026-03-16 11:56:40 +01:00
parent 205eb24819
commit fcfcf28eab
2 changed files with 374 additions and 100 deletions
+345 -83
View File
@@ -1,4 +1,4 @@
export type LineColor = 'green' | 'amber' | 'red' | 'dim'; export type LineColor = "green" | "amber" | "red" | "dim";
export interface BootLine { export interface BootLine {
text: string; text: string;
@@ -9,96 +9,358 @@ export interface BootLine {
export const BOOT_SEQUENCE: BootLine[] = [ export const BOOT_SEQUENCE: BootLine[] = [
// Phase 1 - BIOS POST // Phase 1 - BIOS POST
{ text: 'AWARD BIOS v6.9.420 (c) 2024 Stift15 Systems Ltd.', color: 'dim', delay: 300 }, {
{ text: 'Performing Power-On Self Test...', color: 'dim', delay: 200 }, text: "AWARD BIOS v6.9.420 (c) 2024 Stift15 Systems Ltd.",
{ text: '', color: 'dim', delay: 100 }, color: "dim",
{ text: 'CPU: AMD Ryzen 9 9950X "GamerFuel Edition" @ 5.7 GHz .......... OK', color: 'green', delay: 150 }, delay: 300,
{ text: 'RAM: 65536 MB DDR5-6000 ....................................... OK', color: 'green', delay: 120 }, },
{ text: 'GPU: NVIDIA RTX 5090 "Mortgage Edition" ........................ OK', color: 'green', delay: 120 }, { text: "Performing Power-On Self Test...", color: "dim", delay: 200 },
{ text: 'RGB Subsystem .................................................. SYNCED (mood: aggressive)', color: 'green', delay: 100 }, { text: "", color: "dim", delay: 100 },
{ text: 'Gamer Chair Lumbar Support ..................................... RECLINED', color: 'green', delay: 100 }, {
{ text: '', color: 'dim', delay: 80 }, text: 'CPU: AMD Ryzen 9 9950X "GamerFuel Edition" @ 5.7 GHz .......... OK',
{ text: 'Detecting boot devices...', color: 'dim', delay: 400 }, color: "green",
{ text: 'Boot device: /dev/sda1 (labeled "DO_NOT_DELETE_MOM")', color: 'dim', delay: 300 }, delay: 150,
{ text: '', color: 'dim', delay: 200 }, },
{
text: "RAM: 65536 MB DDR5-6000 ....................................... OK",
color: "green",
delay: 120,
},
{
text: 'GPU: NVIDIA RTX 5090 "Mortgage Edition" ........................ OK',
color: "green",
delay: 120,
},
{
text: "RGB Subsystem .................................................. SYNCED (mood: aggressive)",
color: "green",
delay: 100,
},
{
text: "Gamer Chair Lumbar Support ..................................... RECLINED",
color: "green",
delay: 100,
},
{ text: "", color: "dim", delay: 80 },
{ text: "Detecting boot devices...", color: "dim", delay: 400 },
{
text: 'Boot device: /dev/sda1 (labeled "DO_NOT_DELETE_MOM")',
color: "dim",
delay: 300,
},
{ text: "", color: "dim", delay: 200 },
// Phase 2 - Kernel Boot // Phase 2 - Kernel Boot
{ text: 'Loading GRUB 2.12 ...', color: 'green', delay: 300 }, { text: "Loading GRUB 2.12 ...", color: "green", delay: 300 },
{ text: 'kernel: Linux 6.9.0-gamer-generic loading...', color: 'green', delay: 200 }, {
{ text: '[ 0.000000] Command line: root=/dev/sda1 ro quiet splash=off fps_unlock=true', color: 'dim', delay: 80 }, text: "kernel: Linux 6.9.0-gamer-generic loading...",
{ text: '[ 0.004200] Initializing gaming subsystems...', color: 'dim', delay: 80 }, color: "green",
{ text: '[ 0.013370] RGB controller mapped to /dev/rgb0', color: 'dim', delay: 60 }, delay: 200,
{ text: '[ 0.024601] Registering thermal zone: "CPU Package" (target: yes)', color: 'dim', delay: 60 }, },
{ text: '[ 0.031337] Loading module: gamer_posture.ko', color: 'dim', delay: 60 }, {
{ text: '[ 0.042069] Mounting /dev/fridge (read-only, sadness mode)', color: 'dim', delay: 60 }, text: "[ 0.000000] Command line: root=/dev/sda1 ro quiet splash=off fps_unlock=true",
{ text: '', color: 'dim', delay: 200 }, color: "dim",
delay: 80,
},
{
text: "[ 0.004200] Initializing gaming subsystems...",
color: "dim",
delay: 80,
},
{
text: "[ 0.013370] RGB controller mapped to /dev/rgb0",
color: "dim",
delay: 60,
},
{
text: '[ 0.024601] Registering thermal zone: "CPU Package" (target: yes)',
color: "dim",
delay: 60,
},
{
text: "[ 0.031337] Loading module: gamer_posture.ko",
color: "dim",
delay: 60,
},
{
text: "[ 0.042069] Mounting /dev/fridge (read-only, sadness mode)",
color: "dim",
delay: 60,
},
{ text: "", color: "dim", delay: 200 },
// Phase 3 - Services Starting // Phase 3 - Services Starting
{ text: '[ OK ] Started Gamer Posture Reminder Service', color: 'green', delay: 150 }, {
{ text: '[ OK ] Started Mountain Dew Level Monitor', color: 'green', delay: 120 }, text: "[ OK ] Started Gamer Posture Reminder Service",
{ text: '[ OK ] Started Discord Rich Presence Daemon', color: 'green', delay: 120 }, color: "green",
{ text: '[ OK ] Started Mechanical Keyboard Click Amplifier', color: 'green', delay: 100 }, delay: 150,
{ text: '[ OK ] Started Rage Quit Prevention System (v0.1-beta)', color: 'green', delay: 100 }, },
{ text: '[WARN] Hot Pocket Proximity Sensor returned NaN', color: 'amber', delay: 300 }, {
{ text: '[ OK ] Started Frank\'s "Temporary" Minecraft Server (uptime: 847 days)', color: 'green', delay: 150 }, text: "[ OK ] Started Mountain Dew Level Monitor",
{ text: '[ OK ] Started nginx web server on port 80', color: 'green', delay: 100 }, color: "green",
{ text: '[ OK ] Started Node.js application server on port 3000', color: 'green', delay: 100 }, delay: 120,
{ text: '[WARN] server.js has mass of 2.1 GB (node_modules singularity detected)', color: 'amber', delay: 400 }, },
{ text: '[WARN] Gravitational pull from node_modules is affecting nearby files', color: 'amber', delay: 200 }, {
{ text: '', color: 'dim', delay: 300 }, text: "[ OK ] Started Teamspeak Rich Presence Daemon",
color: "green",
delay: 120,
},
{
text: "[ OK ] Started Mechanical Keyboard Click Amplifier",
color: "green",
delay: 100,
},
{
text: "[ OK ] Started Rage Quit Prevention System (v0.1-beta)",
color: "green",
delay: 100,
},
{
text: "[WARN] Hot Pocket Proximity Sensor returned NaN",
color: "amber",
delay: 300,
},
{
text: '[ OK ] Started Frank\'s "Temporary" Minecraft Server (uptime: 847 days)',
color: "green",
delay: 150,
},
{
text: "[ OK ] Started nginx web server on port 80",
color: "green",
delay: 100,
},
{
text: "[ OK ] Started Node.js application server on port 3000",
color: "green",
delay: 100,
},
{
text: "[WARN] server.js has mass of 2.1 GB (node_modules singularity detected)",
color: "amber",
delay: 400,
},
{
text: "[WARN] Gravitational pull from node_modules is affecting nearby files",
color: "amber",
delay: 200,
},
{ text: "", color: "dim", delay: 300 },
// Phase 4 - The Crash // Phase 4 - The Crash
{ text: '[FAIL] HTTP Health Check: GET /api/status returned... nothing', color: 'red', delay: 600 }, {
{ text: '[FAIL] The backend is not responding.', color: 'red', delay: 400 }, text: "[FAIL] HTTP Health Check: GET /api/status returned... nothing",
{ text: '[FAIL] The backend has never responded. To anything. Ever.', color: 'red', delay: 500 }, color: "red",
{ text: '', color: 'dim', delay: 200 }, delay: 600,
{ text: '[WARN] Attempting emergency restart...', color: 'amber', delay: 800 }, },
{ text: '[ 4.040404] Process \'server.js\' invoked OOM killer', color: 'red', delay: 300 }, { text: "[FAIL] The backend is not responding.", color: "red", delay: 400 },
{ text: '[ 4.040405] OOM killer selected process \'stift15-game-server\' (adj 1000)', color: 'red', delay: 150 }, {
{ text: '[ 4.040406] Out of memory: Killed process 1337 (stift15-game-server)', color: 'red', delay: 150 }, text: "[FAIL] The backend has never responded. To anything. Ever.",
{ text: '[ 4.040407] Reason: Frank downloaded the entire Steam Workshop into /tmp', color: 'red', delay: 300 }, color: "red",
{ text: '', color: 'dim', delay: 200 }, delay: 500,
{ text: '[FAIL] Emergency restart failed. Exit code: 418 (I\'m a teapot)', color: 'red', delay: 600 }, },
{ text: '', color: 'dim', delay: 800 }, { text: "", color: "dim", delay: 200 },
{
text: "[WARN] Attempting emergency restart...",
color: "amber",
delay: 800,
},
{
text: "[ 4.040404] Process 'server.js' invoked OOM killer",
color: "red",
delay: 300,
},
{
text: "[ 4.040405] OOM killer selected process 'stift15-game-server' (adj 1000)",
color: "red",
delay: 150,
},
{
text: "[ 4.040406] Out of memory: Killed process 1337 (stift15-game-server)",
color: "red",
delay: 150,
},
{
text: "[ 4.040407] Reason: Frank downloaded the entire Steam Workshop into /tmp",
color: "red",
delay: 300,
},
{ text: "", color: "dim", delay: 200 },
{
text: "[FAIL] Emergency restart failed. Exit code: 418 (I'm a teapot)",
color: "red",
delay: 600,
},
{ text: "", color: "dim", delay: 800 },
// Phase 5 - The 503 Error (typewriter lines) // Phase 5 - The 503 Error (typewriter lines)
{ text: '============================================================', color: 'red', delay: 400, typewriter: true }, {
{ text: ' ERROR 503 - SERVICE UNAVAILABLE', color: 'red', delay: 100, typewriter: true }, text: "============================================================",
{ text: '============================================================', color: 'red', delay: 100, typewriter: true }, color: "red",
{ text: '', color: 'dim', delay: 200 }, delay: 400,
{ text: ' The server hosting the Stift15 gaming group has encountered', color: 'green', delay: 60, typewriter: true }, typewriter: true,
{ text: ' a fatal error and is currently taking a rage-quit break.', color: 'green', delay: 60, typewriter: true }, },
{ text: '', color: 'dim', delay: 300 }, {
{ text: ' DIAGNOSTIC SUMMARY:', color: 'amber', delay: 200, typewriter: true }, text: " ERROR 503 - SERVICE UNAVAILABLE",
{ text: ' - Last stable connection: "lol"', color: 'green', delay: 80, typewriter: true }, color: "red",
{ text: ' - Uptime before crash: 4h 20m 69s', color: 'green', delay: 80, typewriter: true }, delay: 100,
{ text: ' - Packets lost: all of them', color: 'green', delay: 80, typewriter: true }, typewriter: true,
{ text: ' - Root cause: someone git pushed node_modules to prod', color: 'green', delay: 80, typewriter: true }, },
{ text: ' - Secondary cause: Frank', color: 'green', delay: 80, typewriter: true }, {
{ text: ' - Tertiary cause: also Frank', color: 'green', delay: 80, typewriter: true }, text: "============================================================",
{ text: ' - Frank\'s response: "works on my machine"', color: 'green', delay: 80, typewriter: true }, color: "red",
{ text: '', color: 'dim', delay: 300 }, delay: 100,
{ text: ' RECOMMENDED ACTIONS:', color: 'amber', delay: 200, typewriter: true }, typewriter: true,
{ text: ' 1. Touch grass (estimated ETA: never)', color: 'green', delay: 80, typewriter: true }, },
{ text: ' 2. Check if Frank pushed to main again', color: 'green', delay: 80, typewriter: true }, { text: "", color: "dim", delay: 200 },
{ text: ' 3. Blame the lag', color: 'green', delay: 80, typewriter: true }, {
{ text: ' 4. Alt+F4 your expectations', color: 'green', delay: 80, typewriter: true }, text: " The server hosting Stift15.de has encountered",
{ text: ' 5. Have you tried turning Frank off and on again?', color: 'green', delay: 80, typewriter: true }, color: "green",
{ text: '', color: 'dim', delay: 300 }, delay: 60,
{ text: ' If this error persists, please scream into the void or', color: 'green', delay: 60, typewriter: true }, typewriter: true,
{ text: ' message the server admin, who is also screaming into the void.', color: 'green', delay: 60, typewriter: true }, },
{ text: '', color: 'dim', delay: 400 }, {
{ text: '============================================================', color: 'red', delay: 100, typewriter: true }, text: " a fatal error and is currently taking a rage-quit break.",
{ text: ' SERVER ADMIN NOTE:', color: 'amber', delay: 200, typewriter: true }, color: "green",
{ text: ' No, I will not fix this at 3 AM. I have work tomorrow.', color: 'green', delay: 60, typewriter: true }, delay: 60,
{ text: ' The server can stay dead. It builds character.', color: 'green', delay: 60, typewriter: true }, typewriter: true,
{ text: ' Also Frank still owes me for last month\'s hosting.', color: 'green', delay: 60, typewriter: true }, },
{ text: '============================================================', color: 'red', delay: 100, typewriter: true }, { text: "", color: "dim", delay: 300 },
{ text: '', color: 'dim', delay: 1500 }, {
text: " DIAGNOSTIC SUMMARY:",
color: "amber",
delay: 200,
typewriter: true,
},
{
text: ' - Last stable connection: "lol"',
color: "green",
delay: 80,
typewriter: true,
},
{
text: " - Uptime before crash: 4h 20m 69s",
color: "green",
delay: 80,
typewriter: true,
},
{
text: " - Packets lost: all of them",
color: "green",
delay: 80,
typewriter: true,
},
{
text: " - Root cause: someone git pushed node_modules to prod",
color: "green",
delay: 80,
typewriter: true,
},
{
text: " - Secondary cause: Frank",
color: "green",
delay: 80,
typewriter: true,
},
{
text: " - Tertiary cause: also Frank",
color: "green",
delay: 80,
typewriter: true,
},
{
text: ' - Frank\'s response: "works on my machine"',
color: "green",
delay: 80,
typewriter: true,
},
{ text: "", color: "dim", delay: 300 },
{
text: " RECOMMENDED ACTIONS:",
color: "amber",
delay: 200,
typewriter: true,
},
{
text: " 1. Touch grass (estimated ETA: never)",
color: "green",
delay: 80,
typewriter: true,
},
{
text: " 2. Check if Frank pushed to main again",
color: "green",
delay: 80,
typewriter: true,
},
{ text: " 3. Blame the lag", color: "green", delay: 80, typewriter: true },
{
text: " 4. Alt+F4 your expectations",
color: "green",
delay: 80,
typewriter: true,
},
{
text: " 5. Have you tried turning Frank off and on again?",
color: "green",
delay: 80,
typewriter: true,
},
{ text: "", color: "dim", delay: 300 },
{
text: " If this error persists, please scream into the void or",
color: "green",
delay: 60,
typewriter: true,
},
{
text: " message the server admin, who is also screaming into the void.",
color: "green",
delay: 60,
typewriter: true,
},
{ text: "", color: "dim", delay: 400 },
{
text: "============================================================",
color: "red",
delay: 100,
typewriter: true,
},
{
text: " SERVER ADMIN NOTE:",
color: "amber",
delay: 200,
typewriter: true,
},
{
text: " No, I will not fix this at 3 AM. I have work tomorrow.",
color: "green",
delay: 60,
typewriter: true,
},
{
text: " The server can stay dead. It builds character.",
color: "green",
delay: 60,
typewriter: true,
},
{
text: " Also Frank still owes me for last month's hosting.",
color: "green",
delay: 60,
typewriter: true,
},
{
text: "============================================================",
color: "red",
delay: 100,
typewriter: true,
},
{ text: "", color: "dim", delay: 1500 },
// Phase 6 - Reconnect // Phase 6 - Reconnect
{ text: '> Reconnecting in 3 seconds...', color: 'dim', delay: 0 }, { text: "> Reconnecting in 3 seconds...", color: "dim", delay: 0 },
{ text: '> ...', color: 'dim', delay: 1000 }, { text: "> ...", color: "dim", delay: 1000 },
{ text: '> ...', color: 'dim', delay: 1000 }, { text: "> ...", color: "dim", delay: 1000 },
{ text: '> CONNECTION ESTABLISHED', color: 'green', delay: 1000 }, { text: "> CONNECTION ESTABLISHED", color: "green", delay: 1000 },
]; ];
+29 -17
View File
@@ -20,7 +20,7 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) {
const [input, setInput] = useState(''); const [input, setInput] = useState('');
const [history, setHistory] = useState<string[]>([]); const [history, setHistory] = useState<string[]>([]);
const [historyIndex, setHistoryIndex] = useState(-1); const [historyIndex, setHistoryIndex] = useState(-1);
const containerRef = useRef<HTMLDivElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const bottomRef = useRef<HTMLDivElement>(null); const bottomRef = useRef<HTMLDivElement>(null);
const scrollToBottom = useCallback(() => { const scrollToBottom = useCallback(() => {
@@ -29,9 +29,13 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) {
useEffect(scrollToBottom, [outputLines.length, scrollToBottom]); useEffect(scrollToBottom, [outputLines.length, scrollToBottom]);
// Focus container on mount // Keep input focused
useEffect(() => { useEffect(() => {
containerRef.current?.focus(); inputRef.current?.focus();
}, []);
const focusInput = useCallback(() => {
inputRef.current?.focus();
}, []); }, []);
const executeCommand = useCallback( const executeCommand = useCallback(
@@ -82,12 +86,11 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) {
); );
const handleKeyDown = useCallback( const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => { (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
executeCommand(input); executeCommand(input);
setInput(''); setInput('');
} else if (e.key === 'Backspace') { setHistoryIndex(-1);
setInput((prev) => prev.slice(0, -1));
} else if (e.key === 'ArrowUp') { } else if (e.key === 'ArrowUp') {
e.preventDefault(); e.preventDefault();
if (history.length === 0) return; if (history.length === 0) return;
@@ -105,8 +108,6 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) {
setHistoryIndex(newIndex); setHistoryIndex(newIndex);
setInput(history[newIndex]); setInput(history[newIndex]);
} }
} else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey) {
setInput((prev) => prev + e.key);
} }
}, },
[input, executeCommand, history, historyIndex] [input, executeCommand, history, historyIndex]
@@ -121,11 +122,8 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) {
return ( return (
<div <div
ref={containerRef} className="absolute inset-0 z-0 overflow-y-auto p-4 font-mono text-sm outline-none cursor-text"
className="absolute inset-0 z-0 overflow-y-auto p-4 font-mono text-sm outline-none" onClick={focusInput}
tabIndex={0}
onKeyDown={handleKeyDown}
onClick={() => containerRef.current?.focus()}
> >
{outputLines.map((line, i) => ( {outputLines.map((line, i) => (
<div <div
@@ -137,13 +135,27 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) {
))} ))}
{/* Input line */} {/* Input line */}
<div className="text-term-green whitespace-pre leading-[1.4]"> <div className="text-term-green whitespace-pre leading-[1.4] flex items-center">
{PROMPT} <span>{PROMPT}</span>
{input} <span>{input}</span>
<span <span
className="inline-block w-[0.6em] h-[1em] bg-term-green ml-0.5 align-middle" className="inline-block w-[0.6em] h-[1em] bg-term-green ml-0.5"
style={{ animation: 'blink 1s step-end infinite' }} style={{ animation: 'blink 1s step-end infinite' }}
/> />
{/* Hidden native input for reliable focus and mobile keyboard support */}
<input
ref={inputRef}
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={handleKeyDown}
onBlur={focusInput}
className="absolute opacity-0 w-0 h-0"
autoCapitalize="off"
autoCorrect="off"
autoComplete="off"
spellCheck={false}
/>
</div> </div>
<div ref={bottomRef} /> <div ref={bottomRef} />