1. Automatiser lâexportation de projet Godot
La premiĂšre tĂąche que jâai eu lors de mon stage fut dâautomatiser le processus dâexportation de projet du moteur Godot.
1. Les templates dâexportation
Jâai commencĂ© par utiliser Godot et exporter un projet depuis lâinterface graphique du logiciel.
Le fait dâutiliser lâinterface mâa permis de comprendre et dâidentifier les diffĂ©rents paramĂštres importants Ă lâexportation dâun projet.
Notamment lors de la premiĂšre exportation, si le logiciel ne dĂ©tecte pas de template dâexportation, il propose dâen tĂ©lĂ©charger un depuis le miroir de notre choix.
Suite Ă cette dĂ©couverte, jâai ajoutĂ© le code suivant dans mon script pour vĂ©rifier si un template de la bonne version existe dĂ©jĂ . Si ce nâest pas le cas, je le tĂ©lĂ©charge depuis GitHub.
# Check if there are already export templates
exportTpl=
linkVersion=
# Download export templates if there aren't already downloaded
if ;
then
else
fi
2. Les presets dâexportation
Ensuite, jâai suivi la documentation de Godot pour lâutiliser en CLI. Jâai trouvĂ© des commandes qui se sont avĂ©rĂ©es utiles pour rĂ©aliser ma mission.
En observant les arguments, nous retrouvons preset et path. Path qui signifie tout simplement le chemin absolu ou relatif vers le projet godot, alors que Preset est un peu complexe Ă comprendre.
Jâai compris quâajouter un preset dâexportation au projet comme sur lâimage suivante :
Permet de générer, si non existant, le fichier export_presets.cfg
Ă la racine du projet Godot et ajoute la configuration du preset dedans avec les options que nous lui affectons.
Voici Ă quoi ressemble un preset dans le fichier export_presets.cfg
:
[preset.0]
name="Web"
platform="Web"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter="*.csv"
exclude_filter=""
export_path="Exported_'$name'/'$name'.html"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.0.options]
custom_template/debug=""
custom_template/release=""
variant/extensions_support=false
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/export_icon=true
html/custom_html_shell=""
html/head_include=""
html/canvas_resize_policy=2
html/focus_canvas_on_start=true
html/experimental_virtual_keyboard=false
progressive_web_app/enabled=false
progressive_web_app/offline_page=""
progressive_web_app/display=1
progressive_web_app/orientation=0
progressive_web_app/icon_144x144=""
progressive_web_app/icon_180x180=""
progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)
3. Hébergé le projet exporté
Ensuite, pour ouvrir le projet exportĂ© vers de lâHTML5, jâai utilisĂ© un serveur Python pour accĂ©der aux fichiers dans mon navigateur. Voici le code que jâai ajoutĂ© Ă mon script pour crĂ©er un fichier .py afin dâavoir un serveur Python pour hĂ©berger le projet exportĂ© :
# Create a python virtual environment to install needed libs
if ! | ;
then
fi
# Installing libs in the python virtual env
# Create a python server to host godot
godotServer="from http.server import SimpleHTTPRequestHandler
from http.server import HTTPServer
from socketserver import ThreadingMixIn
import os
class CustomRequestHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token')
self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
super().end_headers()
def translate_path(self, path):
if path == '/':
return os.path.join(os.getcwd(), ' .html')
return super().translate_path(path)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass
def run(server_class=ThreadedHTTPServer, handler_class=CustomRequestHandler, port=8000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print(f'Starting server on port {port}...')
httpd.serve_forever()
if __name__ == '__main__':
run()"
Le dĂ©but du code sert surtout Ă Ă©viter dâinstaller les librairies nĂ©cessaires pour crĂ©er un serveur avec Python sur la machine hĂŽte, mais plutĂŽt sur un environnement virtuel.
4. AccĂšder aux ressources externes
Il y a une subtilitĂ© dans la tĂąche que jâai dĂ» rĂ©aliser : je devais crĂ©er un script pour automatiser lâexportation de projet Godot vers le web. Cependant, le projet sur lequel je devais tester mon script nĂ©cessitait un fichier CSV externe au projet.
La solution que jâai adoptĂ©e pour rĂ©cupĂ©rer les informations du CSV a Ă©tĂ© de lâhĂ©berger sur le dĂ©pĂŽt GitLab du script, et dâutiliser un autre serveur Python avec les autorisations CORS nĂ©cessaires pour y accĂ©der.
# Creating a server to handle request for godot project
requestServer="from flask import Flask, request, jsonify, send_from_directory
import requests
app = Flask(__name__)
@app.route('/proxy', methods=['GET'])
def proxy():
# Récupérez l'URL de la demande client
url = request.args.get('url')
# Faites une requĂȘte HTTP vers Gitlab
response = requests.get(url)
# Renvoyez la rĂ©ponse du serveur Gitlab avec les en-tĂȘtes CORS appropriĂ©s
response_headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token',
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin'
}
return (response.text, response.status_code, response_headers)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)"
Voir le script en entier
#!/bin/bash
scriptUsage () {
echo -e "Usage: $0 <godot_path> <export_preset>
Examples :
$0 godot Web
$0 /bin/godot Web
$0 Godot_v4.2.1.stable Web"
}
godot=$1
if [[ $godot == "" ]];
then
scriptUsage
exit 1
fi
preset=$2
if [[ $preset == "" ]];
then
scriptUsage
exit 2
fi
name=$(pwd | rev | cut -d'/' -f1 | rev)
version=$($godot --version | cut -d "." -f 1,2,3,4 | sed 's/\.official//')
if [[ $version == "" ]];
then
echo "Wrong godot path!"
exit 5
fi
# Export preset to HTML5 (Web)
echo "Setup export preset..."
presetCfg='[preset.0]
name="Web"
platform="Web"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter="*.csv"
exclude_filter=""
export_path="Exported_'$name'/'$name'.html"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.0.options]
custom_template/debug=""
custom_template/release=""
variant/extensions_support=false
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/export_icon=true
html/custom_html_shell=""
html/head_include=""
html/canvas_resize_policy=2
html/focus_canvas_on_start=true
html/experimental_virtual_keyboard=false
progressive_web_app/enabled=false
progressive_web_app/offline_page=""
progressive_web_app/display=1
progressive_web_app/orientation=0
progressive_web_app/icon_144x144=""
progressive_web_app/icon_180x180=""
progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)'
echo -e "$presetCfg" > export_presets.cfg
# Check if there are already export templates
echo "Check if there are export templates..."
mkdir -p ~/.local/share/godot/export_templates/$version
exportTpl=$(ls ~/.local/share/godot/export_templates/$version)
linkVersion=$(echo $version | grep -oP '(\d+(\.\d+)+)')
# Download export templates if there aren't already downloaded
if [[ $exportTpl == "" ]];
then
echo "Export templates not found..."
echo "Downloading export templates..."
wget -q https://github.com/godotengine/godot/releases/download/$linkVersion-stable/Godot_v$linkVersion-stable_export_templates.tpz
unzip -qq Godot_v$linkVersion-stable_export_templates.tpz
mv templates/* ~/.local/share/godot/export_templates/$version
rm -r templates
rm Godot_v$linkVersion-stable_export_templates.tpz
else
echo "Export templates found..."
fi
mkdir -p Exported_$name
echo "Exporting godot project..."
$godot --headless --export-release $preset Exported_$name/$name.html &>/dev/null
# Create a python virtual environment to install needed libs
echo "Check if python venv is installed..."
if ! dpkg -l | grep -q python3-venv;
then
echo "Installing python venv..."
sudo apt install python3-venv -y
fi
python3 -m venv Exported_$name/venv
# Installing libs in the python virtual env
echo "Creating python virtual environment..."
source Exported_$name/venv/bin/activate
echo "Installing python libs..."
python3 -m pip install Flask &>/dev/null
python3 -m pip install requests &>/dev/null
# Create a python server to host godot
echo "Creating server to host godot..."
godotServer="from http.server import SimpleHTTPRequestHandler
from http.server import HTTPServer
from socketserver import ThreadingMixIn
import os
class CustomRequestHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token')
self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
super().end_headers()
def translate_path(self, path):
if path == '/':
return os.path.join(os.getcwd(), '$name.html')
return super().translate_path(path)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass
def run(server_class=ThreadedHTTPServer, handler_class=CustomRequestHandler, port=8000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print(f'Starting server on port {port}...')
httpd.serve_forever()
if __name__ == '__main__':
run()"
echo -e "$godotServer" > Exported_$name/godotServer.py
# Creating a server to handle request for godot project
echo "Creating python server to make request..."
requestServer="from flask import Flask, request, jsonify, send_from_directory
import requests
app = Flask(__name__)
@app.route('/proxy', methods=['GET'])
def proxy():
# Récupérez l'URL de la demande client
url = request.args.get('url')
# Faites une requĂȘte HTTP vers Gitlab
response = requests.get(url)
# Renvoyez la rĂ©ponse du serveur Gitlab avec les en-tĂȘtes CORS appropriĂ©s
response_headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token',
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin'
}
return (response.text, response.status_code, response_headers)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)"
echo -e "$requestServer" > Exported_$name/proxy_server.py
exit 0