De/Adding Python: Difference between revisions
m (Amicdict moved page Adding Python:de to Adding Python/de: : -> / for {{MultiPage}} use.) |
m (obsolete language category) |
||
(6 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{ | {{LanguageBar}} | ||
Eine dynamische Skriptsprache zum Spiel hinzuzufügen erlaubt es, schnelle Änderungen der Spielelemente durchzuführen und es erlaubt der Community, das Spiel selbst zu verändern und zu erweitern. Es gibt viele Skriptsprachen, die man wählen kann, also warum Python? Verglichen mit anderen Skriptsprachen bietet Python eine vergleichsweise einfache Syntax, dynamische Typisierung, eine riesige Standardbibliothek, eine einfache Anbindung an C/C++ über boost.python und eine Menge Dokumentation und Tutorials. Dennoch hat Python ein paar Kosten. Es ist schwer, Python in einer Sandbox auszuführen, wodurch es eine Menge Ausnutzungsmöglichkeiten eröffnen und es gibt einige Komplexitäten, mit denen Programmuierer umgehen müssen (aber das ist besser, als den Endbenutzer sich mit den Komplexitäten befassen zu lassen, die Python entfernt). | Eine dynamische Skriptsprache zum Spiel hinzuzufügen erlaubt es, schnelle Änderungen der Spielelemente durchzuführen und es erlaubt der Community, das Spiel selbst zu verändern und zu erweitern. Es gibt viele Skriptsprachen, die man wählen kann, also warum Python? Verglichen mit anderen Skriptsprachen bietet Python eine vergleichsweise einfache Syntax, dynamische Typisierung, eine riesige Standardbibliothek, eine einfache Anbindung an C/C++ über boost.python und eine Menge Dokumentation und Tutorials. Dennoch hat Python ein paar Kosten. Es ist schwer, Python in einer Sandbox auszuführen, wodurch es eine Menge Ausnutzungsmöglichkeiten eröffnen und es gibt einige Komplexitäten, mit denen Programmuierer umgehen müssen (aber das ist besser, als den Endbenutzer sich mit den Komplexitäten befassen zu lassen, die Python entfernt). | ||
Line 63: | Line 64: | ||
{{ | {{Note|jede Python-Instanz wird von der gleichen Python-Engine ausgeführt und sollte nur innerhalb des gleichen Threads verwendet werden (kein Source-Fehler).}} | ||
== Python initialisieren == | == Python initialisieren == | ||
Line 86: | Line 87: | ||
</source> | </source> | ||
{{ | {{Note|Der Grund, weshalb dies exernalisiert wird und keine Header eingebunden werden, ist, um einem bewusst zu machen, dass der Python Code vom Source SDK Code getrennt ist.}} | ||
Line 115: | Line 116: | ||
Nun kommt der spaßige Teil, die eigene Python-Instanz zu erstellen. Du wirst deine eigene Klasse erstellen müssen, die von PyHandle erbt und Funktionalität für Init und Shutdown bereitstellt. | Nun kommt der spaßige Teil, die eigene Python-Instanz zu erstellen. Du wirst deine eigene Klasse erstellen müssen, die von PyHandle erbt und Funktionalität für Init und Shutdown bereitstellt. | ||
{{ | {{Note|Ein Beispiel-Python-Handle ist im Paket enthalten.}} | ||
=== Init === | === Init === | ||
Line 128: | Line 129: | ||
</source> | </source> | ||
{{ | {{Note|Das Standard-Pythonverzeichnis ist modfiles\scripts\python und kann im Python-Manager geändert werden.}} | ||
=== Shutdown === | === Shutdown === | ||
Line 159: | Line 160: | ||
</source> | </source> | ||
{{ | {{Note|Es ist wichtig, Register() aufzurufen, da es sonst nicht funktioniert!}} | ||
Und erstelle letztendlich in deinem GameRules-Konstruktor einen neuen PyHandle: | Und erstelle letztendlich in deinem GameRules-Konstruktor einen neuen PyHandle: | ||
Line 186: | Line 187: | ||
</source> | </source> | ||
Ein paar Schnittstellen des | Ein paar Schnittstellen des {{LCategory|HalfLife_SDK_Python_Interface|Source SDK wurden bereits zur Verfügung gestellt}} (du kannst sie natürlich auch erweitern), du musst sie also nur noch zu deinem Projekt hinzufügen und sie dann mit der Python-Modulfunktion registrieren. | ||
== Bemerkungen zur Kompilierung von Python Notes on von Grund auf == | == Bemerkungen zur Kompilierung von Python Notes on von Grund auf == | ||
Line 200: | Line 201: | ||
Kompiliere die Boost-Python-Bibliothek erneut anhand der Solution in src\utils\python\boost, wobei du vielleicht den ausgabepfad anpassen musst, damit er der existierenden boost_pythoncore(_d).lib-Datei entspricht. | Kompiliere die Boost-Python-Bibliothek erneut anhand der Solution in src\utils\python\boost, wobei du vielleicht den ausgabepfad anpassen musst, damit er der existierenden boost_pythoncore(_d).lib-Datei entspricht. | ||
{{todo:de|Mehr (siehe | {{todo:de|Mehr (siehe {{L|Adding_Python|Originale Seite}})}} | ||
{{ACategory|Programming}} | |||
{{ACategory|Free source code}} | |||
{{ACategory|Python}} |
Latest revision as of 03:07, 22 August 2024
Eine dynamische Skriptsprache zum Spiel hinzuzufügen erlaubt es, schnelle Änderungen der Spielelemente durchzuführen und es erlaubt der Community, das Spiel selbst zu verändern und zu erweitern. Es gibt viele Skriptsprachen, die man wählen kann, also warum Python? Verglichen mit anderen Skriptsprachen bietet Python eine vergleichsweise einfache Syntax, dynamische Typisierung, eine riesige Standardbibliothek, eine einfache Anbindung an C/C++ über boost.python und eine Menge Dokumentation und Tutorials. Dennoch hat Python ein paar Kosten. Es ist schwer, Python in einer Sandbox auszuführen, wodurch es eine Menge Ausnutzungsmöglichkeiten eröffnen und es gibt einige Komplexitäten, mit denen Programmuierer umgehen müssen (aber das ist besser, als den Endbenutzer sich mit den Komplexitäten befassen zu lassen, die Python entfernt).
Beim Hinzufügen von Python zu Source ist die Source Engine von Grund auf eine Hauptaufgabe, um die verschiedenen Komponenten zum Laufen zu bekommen. Das GoldenEye Source Team hat jedoch den Großteil dessen bereits erledigt, sodass andere Teams Python einfach innerhalb von Minuten einbinden können.
Benötigte Dateien
Du wirst den Code aus dem SVN unter http://code.google.com/p/sourcesdkpython/source/checkout auschecken und dann in dein Mod-Verzeichnis exportieren müssen.
Erste Schritte
Sobald du das Paket oben heruntergeladen hast, entpacke die Verzeichnisse im src-Ordner in den Quellcode-Wurzelordner und die Ordner im mod-Ordner in dein Mod-Wurzelordner.
In den Server-Projekteinstellungen musst du ein paar Einstellungen hinzufügen, damit es fehlerfrei kompiliert. Du wirst dies zu Debug und release hinzufügen müssen, sofern nicht anders angegeben.
Add these to: Configure properties -> c++ -> General-> Additional Include Directories
..\..\public\python .\server\py
Fühe dies hinzu zu: Configure properties -> c++ -> Preprocesser -> Preprocesser defines
Für Release und Debug: Py_NO_ENABLE_SHARED BOOST_PYTHON_STATIC_LIB BOOST_PYTHON_SOURCE BOOST_PYTHON_NO_LIB Nur für Debug: Py_DEBUG
Füge dies hinzu zu: Configure properties -> Linker -> General -> Additional Library Directories
..\..\lib\python
Füge dies hinzu zu: Configure properties -> Linker -> Input -> Additional Dependencies
Für Release Build: boost_pythoncore.lib pythoncore.lib Für Debug Build: boost_pythoncore_d.lib pythoncore_d.lib
Python Manager
Füge diese beiden Dateien zu deiner Half-Life 2 SDK Solution hinzu (in einem neuen Verzeichnis namens python):
ge_pymodules.cpp ge_pymanager.cpp ge_pymanager.h
Diese Dateien definieren die Python Manager Klasse (PMC - "Python Manager Class"). Die PMC erlaubt es dir, verschiedene Instanzen von Python für verschiedene Aufgaben laufen zu haben. Jede Instanz hat ihre eigenen Verzeichnisse, welche die globalen und lokalen Defines beinhalten, sodass 2 Instanzen sich nicht gegenseitig behindern können. PMC lädt außerdem das Setup-Skript, welches Python IO auf die Konsole umleitet und das Python-Wurzelverzeichnis einstellt, damit es weiß, woher Python-Dateien geladen werden sollen. Die PMC bindet außerdem einen Befehl ein, welches dir das Ausführen von Python-Code in der globalen Python-Instanz ermöglicht. (Unterstützung für andere Instanzen kommt bald.)

Python initialisieren
Wenn das erledigt ist, wirst du deinen Code so anpassen müssen, dass er die Init- und Shutdown-Funktionen aufruft. Füge dies in DLLInit in gameinterface.cpp vor dem return true hinzu (um Zeile 550):
PythonInit();
Und füge in der DLLShutdown-Funktion dies hinzu:
PythonShutdown();
Füge außerdem dies nach den defines am Anfang hinzu:
extern void PythonInit();
extern void PythonShutdown();

Das Letzte, was getan werden muss, ist, InitHandles aufzurufen (GoldenEye Source macht dies in den GameRules, aber es kann ebenso an jeder anderen Stelle gemacht werden). Füge dies zu deinem GameRule-Konstruktor hinzu:
#ifndef CLIENT_DLL
PythonInitHandles();
#endif
Und das zum destruktor:
#ifndef CLIENT_DLL
PythonShutdownHandles();
#endif
Und wir müssen es am anfang der Datei externalisieren:
extern void PythonInitHandles();
extern void PythonShutdownHandles();
Deine eigene Python-Instanz erstellen
Nun kommt der spaßige Teil, die eigene Python-Instanz zu erstellen. Du wirst deine eigene Klasse erstellen müssen, die von PyHandle erbt und Funktionalität für Init und Shutdown bereitstellt.

Init
Init wird aufgerufen nachdem Python initialisiert wurde und liefert somit die beste Stelle zum Laden deiner Skripte.
void MyPyHandle::Init()
{
ExecFile("test.py");
}

Shutdown
Shutdown verarbeitet das Abschalten des Python-Handles und sollte Dinge machen, wie Shutdown-Funktionen der eigenen Skripte aufzurufen.
Nützliche Funktionen
Das Python-Handle ermöglicht es dir, Code in Form von C++-Strings durch Aufruf von Exec auszuführen und erhält außerdem das Dictionary, um andere Python-Funktionen zu verwenden.
Die Instanz erzeugen
Am Anfang deiner neuen PyHandle-Klasse musst du eine Funktion definieren, die einen globalen Zugriff auf die Python-Instanz ermöglicht. Füge ungefähr sowas hinzu:
MyPyHandle* g_PyHandle = NULL;
MyPyHandle *GetPyHandle()
{
return PyHandle ;
}
Und füge einen Aufruf zum setzen der Instanz im Konstruktor deines PyHandles hinzu, wenn eine neue erstellt wird:
MyPyHandle::MyPyHandle() : PyHandle()
{
g_PyHandle = this;
Register();
}

Und erstelle letztendlich in deinem GameRules-Konstruktor einen neuen PyHandle:
CGameRules::CGameRules()
{
// anderes Zeug hier
// Starte unseren Python-Handle
if (!GetPyHandle())
new MyPyHandle();
}
C++ Klassen/Funktionen Python bekannt machen
Das ist relativ einfach und eine ausführliche anleitung kann auf der boost.python Website gefunden werden. Wenn du dein Modul definiert hast, muss du es zu ge_pymodule.cpp ungefähr so hinzufügen:
void RegisterPythonModules()
{
REG( HLUtil ); // Das ist bereits da
REG( MyModule ); // Das ist dein neues Modul (ändere den Namen, damit es dem deines Moduls entspricht)
}
Ein paar Schnittstellen des Source SDK wurden bereits zur Verfügung gestellt (du kannst sie natürlich auch erweitern), du musst sie also nur noch zu deinem Projekt hinzufügen und sie dann mit der Python-Modulfunktion registrieren.
Bemerkungen zur Kompilierung von Python Notes on von Grund auf
bp-Namespace-Fehler
Wenn du einen Fehler in ge_pymodules.cpp oder woanders erhälst, der sich auf ein nicht vorhandenes Namespace bezieht, gehe sicher, dass du boost/python.hpp einbindest und das Namespace definierst, wie in ge_pymanager.cpp:
namespace bp = boost::python;
Linker-Probleme mit Visual C++ 2010
Kompiliere die Boost-Python-Bibliothek erneut anhand der Solution in src\utils\python\boost, wobei du vielleicht den ausgabepfad anpassen musst, damit er der existierenden boost_pythoncore(_d).lib-Datei entspricht.