Die Oberfläche des Metin2-Clients ist komplett in Python geschrieben, und wenn du diese Fenster rund um deinen eigenen Server gestalten willst, beginnt die Arbeit bei den metin2 root python-Dateien. Du musst die Engine nicht anfassen, um das Inventar zu verschieben, das Chatfenster zu vergrößern oder einen neuen Button hinzuzufügen — du musst nur die richtige .py-Datei finden und eine sinnvolle Änderung vornehmen. In diesem Artikel zeige ich dir, wie das root-Paket funktioniert, wie du die Dateien öffnest und bearbeitest und wie du deine Änderungen im Client testest.
Das root-Paket und die UI-Architektur
Der Client setzt seine Oberfläche aus drei getrennten Teilen zusammen, und ohne dieses Verständnis verlierst du dich im Berg von Dateien:
- root — Hier liegt die eigentliche Python-Logik.
ui.pydefiniert das UI-Framework (Klassen wie Window, Board, Button, TextLine), während Dateien wieuiInventory.py,uiCharacter.py,uiChat.pyundinterfaceModule.pydas Verhalten jedes Fensters steuern. - uiscript — Hier wird das Layout der Fenster gespeichert. Dateien wie
inventorywindow.pysind kein HTML; sie beschreiben die Geometrie als Python-Dictionary: Koordinaten, Breite, Höhe und untergeordnete Elemente. - locale — Texte und sprachabhängige Einstellungen (
locale_string.txtund einige inuiscriptverwendete Beschriftungen) befinden sich hier.
Also wird das Aussehen eines Fensters größtenteils in uiscript festgelegt, während sein Verhalten in root liegt. Für die meisten optischen Anpassungen reicht es, nur uiscript anzufassen.
Die Dateien entpacken und eine Bearbeitungsumgebung einrichten
Der Client speichert diese Dateien in verschlüsselten Paketen: root.epk / root.eix und uiscript.epk / uiscript.eix. Zum Bearbeiten musst du sie zuerst entpacken:
- Nutze ein Tool wie EterNexus zum Ent- und Wiederpacken. Wenn du die
.eix-Datei öffnest, kannst du die enthaltene Ordnerstruktur extrahieren. - Die Dateien kommen meist als kompilierte
.pyc. Hast du die Quell-.pynicht, brauchst du einen Python-2-Decompiler (zum Beispieluncompyle2), um sie zurückzuwandeln. Da der Client auf Python 2.2 basiert, passen moderne Python-3-Tools oft nicht. - Viele private Server konfigurieren den Client so, dass er statt aus Paketen aus losen Ordnern liest, was die Entwicklung erleichtert. Ist das verfügbar, kannst du die Ordner root und uiscript direkt bearbeiten und den Pack-Schritt überspringen.
Jeder Editor mit Syntaxhervorhebung (VS Code, Notepad++) genügt. Speichere die Dateien in der vom Client erwarteten Kodierung und vermeide es, Tabs und Leerzeichen in der Einrückung zu mischen — Python ist einrückungsempfindlich.
Das Layout eines Fensters mit uiscript ändern
Die häufigste Aufgabe ist, ein Fenster zu verschieben oder in der Größe zu ändern. Die Datei uiscript/inventorywindow.py hat ungefähr diese Struktur:
window = {
"name" : "InventoryWindow",
"x" : SCREEN_WIDTH - 176,
"y" : SCREEN_HEIGHT - 37 - 565,
"style" : ("movable", "float",),
"width" : 176,
"height" : 565,
"children" : (
{
"name" : "board",
"type" : "board",
"x" : 0,
"y" : 0,
"width" : 176,
"height" : 565,
"children" : (
# Titel, Reiter, Slots...
),
},
),
}
Um das Fenster nach links zu verschieben, änderst du den Wert "x"; um es breiter zu machen, änderst du "width". Denk daran: Vergrößerst du die Breite des äußeren Fensters, musst du auch die Breite des inneren board-Elements anpassen, sonst läuft die Hintergrundgrafik über. Mit den Konstanten SCREEN_WIDTH und SCREEN_HEIGHT kannst du das Fenster an einer Bildschirmecke verankern; sie statt fester Zahlen zu verwenden, hält alles über verschiedene Auflösungen hinweg korrekt.
Die Logik innerhalb von root bearbeiten
Wenn das Layout nicht reicht, änderst du das Verhalten auf der root-Seite. Zum Beispiel lädt uiInventory.py die Layout-Datei so:
import ui
import uiScriptLocale
class InventoryWindow(ui.ScriptWindow):
def __LoadWindow(self):
pyScrLoader = ui.PythonScriptLoader()
pyScrLoader.LoadScriptFile(self, "uiscript/inventorywindow.py")
self.wndItem = self.GetChild("ItemSlot")
# ... Referenzen auf Elemente
Der Name im GetChild-Aufruf muss exakt mit dem Feld "name" in der uiscript-Datei übereinstimmen. Hast du einen neuen Button hinzugefügt, definierst du ihn zuerst in uiscript, holst ihn dann auf der root-Seite mit GetChild("NeuerButton") und bindest ihn über SetEvent an eine Funktion. Stimmen die Namen nicht überein, gibt der Client None zurück und stürzt meist mit einem 'NoneType' object has no attribute ...-Fehler ab.
ui.py anzufassen ist eine fortgeschrittene Sache: Da alle Fenster dieses Framework teilen, betrifft ein einziger Fehler hier die gesamte Oberfläche. Solange du nicht wirklich einen neuen Komponententyp brauchst, lass ui.py unangetastet.
Packen, Caching und Debugging
Bist du mit dem Bearbeiten fertig, packe die Dateien wieder ein (oder speichere im Lose-Ordner-Modus einfach) und starte den Client neu. Ein paar praktische Punkte:
- Der Client kann alte Pakete zwischenspeichern; um sicherzugehen, aktualisiere die
.epk- und.eix-Dateien gemeinsam. - Funktioniert etwas nicht, ist die erste Anlaufstelle die Datei
syserr.txtim Client-Ordner. Python-Ausnahmen werden dort samt fehlerhafter Zeilennummer protokolliert. - Häufige Fehler: Einrückungs-Konflikt (
IndentationError), eine nicht geschlossene Klammer oder ein fehlendes Komma in einem uiscript-Dict. Vergiss in Python-Dictionaries das abschließende Komma nach jedem Element nicht.
Häufige Fehler und Tipps
- Sichere das Original. Kopiere vor dem Bearbeiten die Pakete root und uiscript, damit ein Zurücksetzen Sekunden statt Minuten dauert.
- Eine Änderung nach der anderen. Bearbeite nicht zehn Dateien und teste dann erst; die Fehlersuche wird zur Qual.
- Namenskonsistenz ist alles. Der
"name"in uiscript und dasGetChildin root müssen identisch geschrieben sein; sogar die Groß-/Kleinschreibung zählt. - Denk an die Auflösung. Verwende
SCREEN_WIDTH/SCREEN_HEIGHTstatt fester Koordinaten, damit das Fenster auch auf breiten Bildschirmen an seinem Platz bleibt.
Häufige Fragen
Die root-Dateien kommen als .pyc — wie komme ich an den Quellcode?
Viele Dateien werden als kompilierte .pyc verteilt. Ein Python-2-Decompiler (wie uncompyle2) kann sie in lesbares .py verwandeln. Manche Community-Releases teilen bereits sauberen Quellcode; arbeite wenn möglich direkt mit der Quelle, statt zu dekompilieren.
Ich will nur ein Fenster verschieben — muss ich root anfassen?
Nein. Position, Größe und das Layout der untergeordneten Elemente liegen vollständig auf der uiscript-Seite. Solange du kein Button-Verhalten änderst, keine Events bindest und keine neue Logik hinzufügst, musst du die root-Dateien nie öffnen.
Meine Änderung erscheint nicht im Client — warum?
Meist wurde entweder das Paket nicht aktualisiert (erneuere das .eix/.epk-Paar gemeinsam) oder es liegt ein Python-Fehler vor. Schau zuerst in syserr.txt; dort findest du das Problem oft samt exakter Zeilennummer.
Willst du die Oberfläche von Grund auf rund um deinen eigenen Server gestalten? Wenn du Hilfe bei der Metin2-Client-Anpassung, der root-Bearbeitung oder einem maßgeschneiderten UI-Design brauchst, nimm Kontakt mit mir auf — lass uns dein Projekt gemeinsam umsetzen.