master piece

This commit is contained in:
Marc Robin Richter
2026-03-16 11:41:31 +01:00
parent 08e6523bef
commit 508ba07848
23 changed files with 2024 additions and 466 deletions
+222
View File
@@ -0,0 +1,222 @@
import type { LineColor } from '../components/BootSequence';
export interface OutputLine {
text: string;
color: LineColor;
}
type CommandHandler = (args: string[]) => OutputLine[];
function green(text: string): OutputLine {
return { text, color: 'green' };
}
function amber(text: string): OutputLine {
return { text, color: 'amber' };
}
function dim(text: string): OutputLine {
return { text, color: 'dim' };
}
function red(text: string): OutputLine {
return { text, color: 'red' };
}
const FS_LISTING = [
'drwxr-xr-x frank staff games/',
'drwxr-xr-x frank staff mods/',
'drwxr-xr-x frank staff frank_broke_this/',
'drwxr-xr-x frank staff backups_that_dont_work/',
'-rw-r--r-- root staff todo.txt',
'-rw-r--r-- root staff server_rules.txt',
'-rw-r--r-- frank staff definitely_not_a_virus.exe',
'-rwx------ root staff fix_franks_mess.sh',
'-rw-r--r-- frank staff iou_hosting_fees.txt',
'drwxrwxrwx frank staff node_modules/ (2.1 GB)',
];
const FILE_CONTENTS: Record<string, string[]> = {
'todo.txt': [
'1. Fix Frank\'s mess',
'2. Update the server (postponed since 2019)',
'3. Actually play games instead of fixing the server',
'4. Collect hosting fees from Frank',
'5. Give up',
],
'server_rules.txt': [
'STIFT15 SERVER RULES:',
'=====================',
'1. Do not let Frank push to main',
'2. Do NOT let Frank push to main',
'3. Seriously, Frank, stop pushing to main',
'4. No mining crypto on the game server',
'5. Frank, rule 4 applies to you specifically',
'6. Whoever keeps downloading texture packs: stop (Frank)',
'7. The server admin is always right',
'8. If the server is down, it\'s Frank\'s fault',
],
'iou_hosting_fees.txt': [
'Frank owes:',
' January .... $15.00',
' February ... $15.00',
' March ...... $15.00',
' April ...... $15.00 + $47.00 (emergency server recovery)',
' May ........ $15.00',
' Total ...... $122.00',
'',
'Status: "I\'ll get you next month" (since January)',
],
'definitely_not_a_virus.exe': [
'Nice try. This is a Linux server.',
],
};
const NEOFETCH = [
' _______ stift15@server',
' / _____| ---------------',
' | (___ OS: Linux 6.9.0-gamer-generic',
' \\___ \\ Host: Stift15 Gaming HQ',
' ____) | Kernel: 6.9.0-gamer',
' |_____/ Uptime: 4h 20m 69s',
' ____ _____ _____ Packages: 847 (node_modules)',
' |____|_____|_____| Shell: stift15-sh 1.0',
' CPU: AMD Ryzen 9 9950X @ 5.7GHz',
' S T I F T 1 5 GPU: NVIDIA RTX 5090 "Mortgage Ed."',
' Memory: 63420 MB / 65536 MB',
' Disk: 98% used (node_modules)',
' RGB: SYNCED (mood: aggressive)',
];
export const handlers: Record<string, CommandHandler> = {
help: () => [
amber('Available commands:'),
green(' help - Show this help message'),
green(' ls - List files'),
green(' cat <file> - Read a file'),
green(' cd <dir> - Change directory'),
green(' whoami - Who are you?'),
green(' nano - Text editor'),
green(' neofetch - System info'),
green(' clear - Clear terminal'),
green(' blame - Find who\'s responsible'),
green(' uptime - Server uptime'),
green(' ping <target> - Ping a target'),
green(' rm <file> - Remove a file'),
green(' sudo <cmd> - Run as root'),
green(' reboot - Reboot the server'),
],
ls: () => FS_LISTING.map((line) => dim(line)),
cat: (args) => {
const file = args[0];
if (!file) return [red('cat: missing file operand')];
const contents = FILE_CONTENTS[file];
if (!contents) return [red(`cat: ${file}: No such file or directory`)];
return contents.map((line) => green(line));
},
cd: (args) => {
const dir = args[0];
if (!dir) return [dim('~')];
if (dir === 'node_modules') return [red('cd: node_modules: event horizon detected, cannot enter')];
if (dir === 'frank_broke_this') return [red('cd: frank_broke_this: directory too corrupted to enter')];
if (dir === 'games') return [amber('cd: games: you should be fixing the server, not playing games')];
if (dir === 'backups_that_dont_work') return [red('cd: backups_that_dont_work: Permission denied (also they don\'t work)')];
return [red(`cd: ${dir}: No such file or directory`)];
},
whoami: () => [
green('guest'),
dim('(you thought you were root? lol)'),
],
nano: () => [
red('nano: command disabled.'),
dim('Frank deleted it to "save disk space."'),
dim('He then installed 47 texture packs.'),
],
neofetch: () => NEOFETCH.map((line) => green(line)),
blame: () => [
green('Analyzing git history...'),
green('Checking commit logs...'),
green('Cross-referencing with incident reports...'),
green(''),
amber('Result: It was Frank.'),
dim('(confidence: 99.7%)'),
dim('(remaining 0.3%: also Frank, using an alt account)'),
],
uptime: () => [
green(' 03:14:15 up 4:20, 69 users, load average: 4.04, 0.00, 0.00'),
dim('(new personal record!)'),
],
ping: (args) => {
const target = args[0];
if (!target) return [red('ping: missing target')];
const lower = target.toLowerCase();
if (lower === 'frank') {
return [
green(`PING frank (192.168.1.???) 56(84) bytes of data.`),
amber('Request timeout. Frank is AFK again.'),
amber('Request timeout. Frank is "getting food."'),
amber('Request timeout. Frank disconnected.'),
red('--- frank ping statistics ---'),
red('3 packets transmitted, 0 received, 100% packet loss'),
dim('(as usual)'),
];
}
if (lower === 'franks.mom' || lower === 'frank.mom' || lower === 'franksmom') {
return [
green(`PING franks.mom (192.168.1.1) 56(84) bytes of data.`),
dim('...'),
dim('...'),
dim('...'),
amber('Request timeout.'),
amber('Request timeout.'),
amber('Request timeout.'),
red('--- franks.mom ping statistics ---'),
red('3 packets transmitted, 0 received, 100% packet loss'),
dim(''),
dim('franks.mom is unreachable.'),
dim('She blocked this server after the 3 AM incident.'),
dim('Frank says "it wasn\'t that loud" but we have witnesses.'),
];
}
if (lower === 'google.com' || lower === 'google') {
return [
green(`PING google.com (142.250.80.46) 56(84) bytes of data.`),
green('64 bytes: icmp_seq=1 ttl=118 time=4.20ms'),
green('64 bytes: icmp_seq=2 ttl=118 time=6.90ms'),
dim('--- google.com ping statistics ---'),
dim('2 packets transmitted, 2 received, 0% packet loss'),
dim('(at least something works)'),
];
}
return [
green(`PING ${target} 56(84) bytes of data.`),
green(`64 bytes: icmp_seq=1 ttl=64 time=${(Math.random() * 100).toFixed(1)}ms`),
green(`64 bytes: icmp_seq=2 ttl=64 time=${(Math.random() * 100).toFixed(1)}ms`),
];
},
rm: (args) => {
const joined = args.join(' ');
if (joined.includes('-rf') && joined.includes('/')) {
// Special case handled in CommandPrompt
return [];
}
if (args.length === 0) return [red('rm: missing operand')];
return [red(`rm: cannot remove '${args[args.length - 1]}': Permission denied`)];
},
sudo: (args) => {
if (args.length === 0) return [red('sudo: missing command')];
return [
red('Nice try.'),
dim(`[sudo] incident reported to the server admin.`),
dim(`[sudo] also reported to Frank's mom.`),
];
},
};