mirror of
https://github.com/ceratic/project_vollidioten_website.git
synced 2026-05-14 00:16:47 +02:00
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.
273 lines
15 KiB
TypeScript
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; |