Files
project_vollidioten_website/pages/DatapackGenerator.tsx
Lars Behrends d1b797a320 feat: Initialize project with Vite, React, and TypeScript
Sets up the foundational structure for the Obsidian | RP Plattform. This includes configuring Vite as the build tool, integrating React for the UI, and establishing TypeScript for type safety. Also includes initial styling and placeholder data to define the application's core interfaces.
2025-12-28 02:15:09 +01:00

273 lines
15 KiB
TypeScript

import React, { useState } from 'react';
import { Icons } from '../components/IconSet';
interface FileBlock {
name: string;
path: string;
language: string;
content: string;
}
const DatapackGenerator: React.FC = () => {
const [activeFile, setActiveFile] = useState<string>('menu.mcfunction');
const files: FileBlock[] = [
{
name: 'pack.mcmeta',
path: 'obsidian_core/pack.mcmeta',
language: 'json',
content: `{
"pack": {
"pack_format": 15,
"description": "Obsidian Core - Verwaltung (v2.4 DE)"
}
}`
},
{
name: 'load.json',
path: 'obsidian_core/data/minecraft/tags/functions/load.json',
language: 'json',
content: `{
"values": [
"obsidian:load"
]
}`
},
{
name: 'tick.json',
path: 'obsidian_core/data/minecraft/tags/functions/tick.json',
language: 'json',
content: `{
"values": [
"obsidian:system/tick"
]
}`
},
{
name: 'load.mcfunction',
path: 'obsidian_core/data/obsidian/functions/load.mcfunction',
language: 'mcfunction',
content: `# Initialize Scoreboards
scoreboard objectives add obs_action trigger
scoreboard objectives add obs_id dummy
# Initialize Storage
data modify storage obsidian:main selected set value {id:"Keine", type:"None"}
tellraw @a {"text":"[Obsidian] System geladen. Trigger registriert.","color":"green"}`
},
{
name: 'tick.mcfunction',
path: 'obsidian_core/data/obsidian/functions/system/tick.mcfunction',
language: 'mcfunction',
content: `# Enable trigger for all players
execute as @a run scoreboard players enable @s obs_action
# Detect triggers
execute as @a[scores={obs_action=1..}] run function obsidian:system/handle_trigger`
},
{
name: 'menu.mcfunction',
path: 'obsidian_core/data/obsidian/functions/ui/menu.mcfunction',
language: 'mcfunction',
content: `tellraw @s ["",{"text":"\\n=== OBSIDIAN MENÜ ===\\n","color":"dark_aqua","bold":true}]
tellraw @s ["",{"text":"Neu erstellen:","color":"gray"}]
tellraw @s [{"text":"[+ Stadt] ","color":"gold","clickEvent":{"action":"run_command","value":"/trigger obs_action set 10"},"hoverEvent":{"action":"show_text","value":"Eine neue Stadt gründen"}}]
tellraw @s [{"text":" [+ Unternehmung] ","color":"green","clickEvent":{"action":"run_command","value":"/trigger obs_action set 20"},"hoverEvent":{"action":"show_text","value":"Ein neues Unternehmen registrieren"}}]
tellraw @s ["",{"text":"\\n\\nZielauswahl:","color":"gray"}]
tellraw @s [{"text":"[Wähle per Name] ","color":"aqua","clickEvent":{"action":"run_command","value":"/trigger obs_action set 30"},"hoverEvent":{"action":"show_text","value":"Halte ein Item mit dem exakten Namen um den Eintrag zu wählen."}}]
tellraw @s ["",{"text":"\\nAktuell gewählt: ","color":"gray"},{"nbt":"selected.id","storage":"obsidian:main","color":"light_purple"}]
# Edit Controls
tellraw @s ["",{"text":"Bearbeiten: ","color":"gray"}]
tellraw @s [{"text":"[Umbenennen] ","color":"white","clickEvent":{"action":"run_command","value":"/trigger obs_action set 60"},"hoverEvent":{"action":"show_text","value":"Namen des Eintrags ändern"}}]
tellraw @s [{"text":"[Beschr. ändern] ","color":"white","clickEvent":{"action":"run_command","value":"/trigger obs_action set 40"},"hoverEvent":{"action":"show_text","value":"Beschreibungstext aktualisieren"}}]
tellraw @s [{"text":"[Status ändern] ","color":"white","clickEvent":{"action":"run_command","value":"/trigger obs_action set 50"},"hoverEvent":{"action":"show_text","value":"Wechseln zwischen Aktiv/Rekrutierend/Geschlossen"}}]
tellraw @s ["",{"text":"\\n\\n[?] Hilfe","color":"yellow","clickEvent":{"action":"run_command","value":"/trigger obs_action set 9"},"hoverEvent":{"action":"show_text","value":"Spieleranleitung lesen"}}]`
},
{
name: 'handle_trigger.mcfunction',
path: 'obsidian_core/data/obsidian/functions/system/handle_trigger.mcfunction',
language: 'mcfunction',
content: `# --- HANDLE TRIGGERS ---
# 1: Open Menu
execute if score @s obs_action matches 1 run function obsidian:ui/menu
# 9: Help
execute if score @s obs_action matches 9 run function obsidian:ui/help
# --- CREATION ---
# 10: Prompt City
execute if score @s obs_action matches 10 run tellraw @s ["",{"text":"[Neue Stadt] ","color":"gold"},{"text":"Item in Stadt-Name umbenennen. Halten & ","color":"gray"},{"text":"[KLICK]","color":"green","bold":true,"clickEvent":{"action":"run_command","value":"/trigger obs_action set 11"}}]
# 11: Create City
execute if score @s obs_action matches 11 run tellraw @a [{"text":"Neue Stadt gegründet: ","color":"gold"},{"nbt":"SelectedItem.tag.display.Name","entity":"@s"}]
execute if score @s obs_action matches 11 run data modify storage obsidian:db Cities append value {name:"New",status:"active"}
execute if score @s obs_action matches 11 run data modify storage obsidian:db Cities[-1].name set from entity @s SelectedItem.tag.display.Name
# 20: Prompt Venture
execute if score @s obs_action matches 20 run tellraw @s ["",{"text":"[Neues Unternehmen] ","color":"green"},{"text":"Item in Firmen-Name umbenennen. Halten & ","color":"gray"},{"text":"[KLICK]","color":"green","bold":true,"clickEvent":{"action":"run_command","value":"/trigger obs_action set 21"}}]
# 21: Create Venture
execute if score @s obs_action matches 21 run tellraw @a [{"text":"Neues Unternehmen registriert: ","color":"green"},{"nbt":"SelectedItem.tag.display.Name","entity":"@s"}]
execute if score @s obs_action matches 21 run data modify storage obsidian:db Ventures append value {name:"New",status:"active"}
execute if score @s obs_action matches 21 run data modify storage obsidian:db Ventures[-1].name set from entity @s SelectedItem.tag.display.Name
# --- SELECTION ---
# 30: Select Target
execute if score @s obs_action matches 30 run data modify storage obsidian:main selected.id set from entity @s SelectedItem.tag.display.Name
execute if score @s obs_action matches 30 run tellraw @s [{"text":"Ziel erfasst: ","color":"aqua"},{"nbt":"selected.id","storage":"obsidian:main"}]
# --- EDITING ---
# 40/41: Description
execute if score @s obs_action matches 40 run tellraw @s ["",{"text":"[Beschr. ändern] ","color":"light_purple"},{"text":"Item in neue Beschreibung umbenennen. Halten & ","color":"gray"},{"text":"[UPDATE]","color":"yellow","bold":true,"clickEvent":{"action":"run_command","value":"/trigger obs_action set 41"}}]
execute if score @s obs_action matches 41 run tellraw @a [{"text":"LOG|UPDATE_DESC|","color":"dark_gray"},{"nbt":"selected.id","storage":"obsidian:main"},{"text":"|"},{"nbt":"SelectedItem.tag.display.Name","entity":"@s"}]
# 50: Toggle Status (Active -> Recruiting -> Closed)
execute if score @s obs_action matches 50 run tellraw @a [{"text":"LOG|CYCLE_STATUS|","color":"dark_gray"},{"nbt":"selected.id","storage":"obsidian:main"}]
# 60/61: Rename Entry
execute if score @s obs_action matches 60 run tellraw @s ["",{"text":"[Umbenennen] ","color":"red"},{"text":"Item in NEUEN Namen umbenennen. Halten & ","color":"gray"},{"text":"[BESTÄTIGEN]","color":"red","bold":true,"clickEvent":{"action":"run_command","value":"/trigger obs_action set 61"}}]
execute if score @s obs_action matches 61 run tellraw @a [{"text":"LOG|RENAME_ENTRY|","color":"dark_gray"},{"nbt":"selected.id","storage":"obsidian:main"},{"text":"|"},{"nbt":"SelectedItem.tag.display.Name","entity":"@s"}]
execute if score @s obs_action matches 61 run data modify storage obsidian:main selected.id set from entity @s SelectedItem.tag.display.Name
# Reset
scoreboard players set @s obs_action 0
scoreboard players enable @s obs_action`
},
{
name: 'help.mcfunction',
path: 'obsidian_core/data/obsidian/functions/ui/help.mcfunction',
language: 'mcfunction',
content: `tellraw @s ["",{"text":"\\n=== OBSIDIAN ANLEITUNG ===\\n","color":"dark_aqua","bold":true}]
tellraw @s [{"text":"[!] ","color":"yellow"},{"text":"Texteingabe ohne Befehle:","color":"gray"}]
tellraw @s [{"text":"\\n1. Item umbenennen: ","color":"white","bold":true},{"text":"Benenne ein Papier (oder Item) im Amboss um (Dein Text).","color":"gray"}]
tellraw @s [{"text":"\\n2. Item halten: ","color":"white","bold":true},{"text":"Halte das Item in der Haupthand.","color":"gray"}]
tellraw @s [{"text":"\\n3. Aktion klicken: ","color":"white","bold":true},{"text":"Klicke [Bestätigen] oder [Wählen] im Menü.","color":"gray"}]
tellraw @s [{"text":"\\nDas System liest den Item-Namen als Eingabe.","color":"gray","italic":true}]`
},
{
name: 'export.mcfunction',
path: 'obsidian_core/data/obsidian/functions/system/export.mcfunction',
language: 'mcfunction',
content: `# Admin Only Export
tellraw @a {"text":"JSON_EXPORT_START|DB_DUMP|", "color":"white"}
tellraw @a {"nbt":"Cities","storage":"obsidian:db"}
tellraw @a {"nbt":"Ventures","storage":"obsidian:db"}`
}
];
const currentFile = files.find(f => f.name === activeFile);
return (
<div className="max-w-6xl mx-auto grid grid-cols-1 lg:grid-cols-12 gap-8 animate-in fade-in">
{/* Intro Sidebar */}
<div className="lg:col-span-4 space-y-6">
<div>
<div className="flex items-center gap-2 mb-2">
<span className="bg-accentSuccess/10 text-accentSuccess border border-accentSuccess/20 text-xs font-bold px-2 py-1 rounded uppercase tracking-wider">v2.4 Non-OP (DE)</span>
<span className="text-textMuted text-xs">Trigger System</span>
</div>
<h1 className="text-3xl font-bold mb-2">Datapack Generator</h1>
<p className="text-textMuted">
Non-OP Management System. Nutzt <strong>Item-Umbenennung</strong> als sichere Eingabemethode für Spielertexte.
</p>
</div>
{/* PLAYER GUIDE SECTION */}
<div className="bg-surface border border-border rounded-xl overflow-hidden shadow-card">
<div className="p-4 bg-surfaceHighlight/30 border-b border-white/5">
<h3 className="font-bold text-white flex items-center gap-2">
<Icons.Users className="w-4 h-4 text-accentSuccess" />
Spieler Anleitung
</h3>
</div>
<div className="p-5 space-y-4">
<p className="text-xs text-textMuted leading-relaxed">
Verteile diese Anleitung an deine Spieler. Da normale Spieler keine Befehle nutzen können, nutzt dieses Pack ein immersives <strong>"Item Key"</strong> System.
</p>
<div className="space-y-4 mt-2">
<div className="flex gap-3">
<div className="w-6 h-6 rounded bg-blue-500/10 text-blue-400 border border-blue-500/20 flex items-center justify-center font-bold text-xs shrink-0">1</div>
<div className="text-sm">
<strong className="block text-gray-200 text-xs uppercase tracking-wide mb-1">Erstellen</strong>
<p className="text-textMuted text-xs leading-relaxed">Klicke [+ Unternehmung], benenne ein Item zu "Mein Shop", halte es, und klicke den Bestätigungs-Link.</p>
</div>
</div>
<div className="flex gap-3">
<div className="w-6 h-6 rounded bg-blue-500/10 text-blue-400 border border-blue-500/20 flex items-center justify-center font-bold text-xs shrink-0">2</div>
<div className="text-sm">
<strong className="block text-gray-200 text-xs uppercase tracking-wide mb-1">Zum Bearbeiten wählen</strong>
<p className="text-textMuted text-xs leading-relaxed">Halte ein Item mit dem <strong>exakten Namen</strong> deiner Firma. Klicke <strong>[Wähle per Name]</strong>. Das Menü visiert nun diesen Eintrag an.</p>
</div>
</div>
<div className="flex gap-3">
<div className="w-6 h-6 rounded bg-blue-500/10 text-blue-400 border border-blue-500/20 flex items-center justify-center font-bold text-xs shrink-0">3</div>
<div className="text-sm">
<strong className="block text-gray-200 text-xs uppercase tracking-wide mb-1">Modifizieren</strong>
<p className="text-textMuted text-xs leading-relaxed">
Nutze <strong>[Umbenennen]</strong> oder <strong>[Beschr. ändern]</strong>. Du wirst aufgefordert, ein Item zum NEUEN Wert umzubenennen und zu bestätigen.
</p>
</div>
</div>
</div>
</div>
</div>
{/* Admin Note */}
<div className="p-4 bg-surfaceHighlight/10 border border-border rounded-lg text-xs text-textMuted">
<strong className="text-accentInfo block mb-1">Wichtig:</strong>
Ich habe <code>load.json</code> hinzugefügt, um sicherzustellen, dass das Scoreboard automatisch erstellt wird. Bitte führe <code>/reload</code> nach der Installation aus.
</div>
</div>
{/* Code Viewer */}
<div className="lg:col-span-8 bg-[#0b0b0d] border border-border rounded-xl overflow-hidden shadow-2xl flex flex-col min-h-[600px]">
{/* Tabs */}
<div className="flex overflow-x-auto border-b border-white/5 bg-surface/50">
{files.map(file => (
<button
key={file.name}
onClick={() => setActiveFile(file.name)}
className={`px-4 py-3 text-xs font-mono border-r border-white/5 transition-colors whitespace-nowrap ${
activeFile === file.name
? 'bg-[#0b0b0d] text-accentInfo'
: 'text-textMuted hover:bg-white/5 hover:text-gray-300'
}`}
>
{file.name}
</button>
))}
</div>
{/* Editor Content */}
<div className="flex-1 p-6 relative group overflow-y-auto custom-scrollbar">
<div className="absolute top-0 right-0 p-4">
<button
onClick={() => currentFile && navigator.clipboard.writeText(currentFile.content)}
className="text-xs bg-surfaceHighlight hover:bg-white/10 text-textMuted hover:text-white px-3 py-1.5 rounded transition-colors border border-white/10"
>
Inhalt kopieren
</button>
</div>
{currentFile && (
<div>
<div className="text-xs text-gray-500 mb-4 font-mono select-none">
Dateipfad: <span className="text-gray-400">{currentFile.path}</span>
</div>
<pre className="font-mono text-sm text-gray-300 leading-relaxed whitespace-pre-wrap">
{currentFile.content}
</pre>
</div>
)}
</div>
</div>
</div>
);
};
export default DatapackGenerator;