mirror of
https://github.com/xgui4/LCE-Qt-Launcher.git
synced 2026-07-16 02:40:38 +00:00
Merge pull request #24 from xgui4/beta
Upgrade to Nightly 1 Beta 0.0.2.0
This commit is contained in:
BIN
.github/screenshots/image.png
vendored
BIN
.github/screenshots/image.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 109 KiB |
12
.github/workflows/nightly.yml
vendored
12
.github/workflows/nightly.yml
vendored
@@ -56,14 +56,14 @@ jobs:
|
||||
- name: Compile .ISS
|
||||
uses: Minionguyjpro/Inno-Setup-Action@v1.2.2
|
||||
with:
|
||||
path: packages/windows/windows-setup-nigthly.iss
|
||||
path: packages\windows\windows-setup-nigthly.iss
|
||||
options: '/O+ /F"LCE_Qt_Launcher_Windows_Nigthly_Setup"'
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: installer-windows
|
||||
path: packages/windows/*.exe
|
||||
path: packages\windows\Output\*.exe
|
||||
|
||||
# --- JOB 3 : Making Arch Linux Packages ---
|
||||
build_arch_installer:
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
Experimental Build (Nightly) generated by GitHub Action. The nighy build are experimental nuitka compilation from the nighly branch.
|
||||
Package for GNU/Linux and Installer for Windows is coming late. Now includes installers."
|
||||
files: |
|
||||
./artifacts/*.exe
|
||||
./artifacts/*.zip
|
||||
./artifacts/*.pkg.tar.zst
|
||||
./artifacts/*.tar.gz
|
||||
./artifacts/****.exe
|
||||
./artifacts/****.zip
|
||||
./artifacts/****.pkg.tar.zst
|
||||
./artifacts/****.tar.gz
|
||||
63
.github/workspace/PKGBUILD
vendored
63
.github/workspace/PKGBUILD
vendored
@@ -1 +1,62 @@
|
||||
../../packages/linux/nigthly/PKGBUILD
|
||||
# Maintainer: Xgui4
|
||||
pkgname=lce-qt-launcher-git
|
||||
pkgver=r149.804311b
|
||||
pkgrel=1
|
||||
pkgdesc="A custom Minecraft LCE Launcher written in Python and Qt with GNU/Linux support in mind. (Nigthly/Git Build)"
|
||||
arch=('any')
|
||||
url="https://github.com/xgui4/LCE-Qt-Launcher"
|
||||
license=('GPL-3.0-or-later')
|
||||
depends=(
|
||||
'python'
|
||||
'pyside6'
|
||||
'python-requests'
|
||||
'python-platformdirs'
|
||||
'python-rich'
|
||||
)
|
||||
makedepends=(
|
||||
'git'
|
||||
'bash'
|
||||
'curl'
|
||||
'python-build'
|
||||
'python-installer'
|
||||
'python-hatchling'
|
||||
'python-wheel'
|
||||
'qt6-tools'
|
||||
)
|
||||
optdepends=(
|
||||
'wine: Allow to launch non-Linux-native Minecraft LCE ports'
|
||||
'steam: Allow for Steam integration'
|
||||
'ttc-monocraft: Minecraft Font for the UI (Availaible in the AUR)'
|
||||
)
|
||||
|
||||
provides=("${pkgname%-git}" "${pkgname%-nightly}" "${pkgname%}")
|
||||
conflicts=("${pkgname%-dev}" "${pkgname%-stable}" "${pkgname%}")
|
||||
source=("${pkgname}::git+${url}.git#branch=nightly")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$pkgname"
|
||||
# cutting off 'foo-' prefix that presents in the git tag
|
||||
git describe --long --abbrev=7 | sed 's/^foo-//;s/\([^-]*-g\)/r\1/;s/-/./g'
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$pkgname"
|
||||
rm -rf dist/ build/
|
||||
/usr/bin/python -m build --wheel --no-isolation
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$pkgname"
|
||||
/usr/bin/python -m installer --destdir="$pkgdir" dist/*.whl
|
||||
install -d "$pkgdir/opt/lce_qt_launcher"
|
||||
cp -r data assets "$pkgdir"
|
||||
install -Dm644 "data/lce_qt_launcher.ini" "$pkgdir/etc/lce_qt_launcher.ini"
|
||||
install -Dm644 "packages/io.github.xgui4.lce_qt_launcher.desktop" "$pkgdir/usr/share/applications/io.github.xgui4.lce_qt_launcher.desktop"
|
||||
install -Dm644 "packages/lce_inst-mime.xml" "$pkgdir/usr/share/mime/packages/io.github.xgui4.lce_qt_launcher.gtk.metainfo.xml"
|
||||
install -Dm644 "license.md" -t "$pkgdir/usr/share/licenses/$pkgname/"
|
||||
install -Dm644 "readme.md" "code-of-conduct.md" -t "$pkgdir/usr/share/doc/$pkgname/"
|
||||
install -Dm644 "packages/io.github.xgui4.lce_qt_launcher.metainfo.xml" "$pkgdir/usr/share/metainfo/io.github.xgui4.lce_qt_launcher.gtk.metainfo.xml"
|
||||
install -Dm644 "assets/io.github.xgui4.lce_qt_launcher.png" "$pkgdir/usr/share/icons/hicolor/128x128/apps/io.github.xgui4.lce_qt_launcher.png"
|
||||
install -Dm644 "assets/lce_inst.png" "$pkgdir/usr/share/icons/hicolor/128x128/mimetypes/application-x-lce_inst.png"
|
||||
}
|
||||
|
||||
BIN
assets/images/piston.png
Normal file
BIN
assets/images/piston.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
14
data/defaults_instances/360Revived.lce_inst
Normal file
14
data/defaults_instances/360Revived.lce_inst
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema" : "https://raw.githubusercontent.com/xgui4/LCE-Qt-Launcher/refs/heads/nightly/schemas/x-application-lce_inst_config.json",
|
||||
"name": "360Revived",
|
||||
"installation_path": ".lce-360Revived",
|
||||
"username": "Steve",
|
||||
"archive_file": "LCEWindows64.zip",
|
||||
"exe_name": "Minecraft.Client.exe",
|
||||
"repo_url": "https://github.com/BluTac10/360Revived",
|
||||
"image" : ":/assets/minecraft.png",
|
||||
"news_feed" : "https://github.com/BluTac10/360Revived/commits/main/",
|
||||
"instance_source": "InstanceSource.GITHUB_RELEASE",
|
||||
"instance_type": "InstanceType.CLIENT_VANILLA",
|
||||
"version": "nightly"
|
||||
}
|
||||
14
data/defaults_instances/hellishends.lce_inst
Normal file
14
data/defaults_instances/hellishends.lce_inst
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema" : "https://raw.githubusercontent.com/xgui4/LCE-Qt-Launcher/refs/heads/nightly/schemas/x-application-lce_inst_config.json",
|
||||
"name": "HellishEnds",
|
||||
"installation_path": ".lce-HellishEnds",
|
||||
"username": "Steve",
|
||||
"archive_file": "LCEWindows64.zip",
|
||||
"exe_name": "Minecraft.Client.exe",
|
||||
"repo_url": "hhttps://github.com/deadvoxelx/HellishEnds",
|
||||
"image" : ":/assets/minecraft.png",
|
||||
"news_feed" : "https://github.com/deadvoxelx/HellishEnds/commits/main/",
|
||||
"instance_source": "InstanceSource.GITHUB_RELEASE",
|
||||
"instance_type": "InstanceType.CLIENT_VANILLA",
|
||||
"version": "nightly"
|
||||
}
|
||||
14
data/defaults_instances/revelation.lce_inst
Normal file
14
data/defaults_instances/revelation.lce_inst
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema" : "https://raw.githubusercontent.com/xgui4/LCE-Qt-Launcher/refs/heads/nightly/schemas/x-application-lce_inst_config.json",
|
||||
"name": "Revelations",
|
||||
"installation_path": ".lce-revelations ",
|
||||
"username": "Steve",
|
||||
"archive_file": "LCE-Revelations-Client-Win64.zip",
|
||||
"exe_name": "Minecraft.Client.exe",
|
||||
"repo_url": "https://github.com/itsRevela/LCE-Revelations",
|
||||
"image" : ":/assets/minecraft.png",
|
||||
"news_feed" : "https://github.com/itsRevela/LCE-Revelations/commits/main/",
|
||||
"instance_source": "InstanceSource.GITHUB_RELEASE",
|
||||
"instance_type": "InstanceType.CLIENT_VANILLA",
|
||||
"version": "Nightly"
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
pkgs.python3Packages.buildPythonApplication rec {
|
||||
pname = "lce-qt-launcher";
|
||||
version = "2026.4.26";
|
||||
version = "2026.5.1";
|
||||
format = "pyproject";
|
||||
|
||||
src = ./.;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
packages.default = python.pkgs.buildPythonApplication {
|
||||
pname = "lce_qt_launcher";
|
||||
version = "0.0.1";
|
||||
version = "0.0.2.0";
|
||||
format = "hatchling";
|
||||
license = pkgs.lib.licenses.gpl3plus;
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import subprocess
|
||||
import os
|
||||
from typing import override
|
||||
|
||||
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
||||
|
||||
class CustomBuildHook(BuildHookInterface): # pyright: ignore[reportMissingTypeArgument]
|
||||
@override
|
||||
def clean(self, versions) -> None: # pyright: ignore[reportMissingParameterType]
|
||||
if os.name == "posix":
|
||||
_ = subprocess.run("./scripts/clean.sh", check=True)
|
||||
@@ -13,7 +11,6 @@ class CustomBuildHook(BuildHookInterface): # pyright: ignore[reportMissingTypeA
|
||||
_ = subprocess.run("scripts\\clean.cmd", check=True, shell=True)
|
||||
return super().clean(versions)
|
||||
|
||||
@override
|
||||
def initialize(self, version, build_data) -> None: # pyright: ignore[reportMissingParameterType]
|
||||
if os.name == "posix":
|
||||
_ = subprocess.run("./scripts/build.sh", check=True)
|
||||
|
||||
129
lisezmoi.md
129
lisezmoi.md
@@ -1,38 +1,48 @@
|
||||
# LCE QT Launcher
|
||||
# LCE Qt Launcher
|
||||
|
||||
[Version Anglaise](readme.md)
|
||||
[Version anglaise](readme.md)
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
> [!WARNING]
|
||||
> Ce lanceur est en cours de développement et ses fonctionnalités peuvent être modifiées ou supprimées à tout moment.
|
||||
> Les contributions (PR) sont les bienvenues pour corriger ou ajouter des fonctionnalités. Veuillez respecter la [licence GPLv3](license.md) et le [Code de conduite](CODE-DE-CONDUITE.md).
|
||||
> Les contributions (PR) sont les bienvenues pour corriger ou ajouter des fonctionnalités. Veuillez respecter la [licence GPLv3](license.md) et le [Code de conduite](code-of-conduct.md).
|
||||
|
||||
## À propos
|
||||
|
||||
Il s'agit d'un lanceur LCE personnalisé pour Minecraft, écrit en Python et Qt avec Freedom et conçu pour être compatible avec GNU/Linux.
|
||||
Il s'agit d'un lanceur LCE personnalisé pour Minecraft, écrit en Python et Qt avec Freedom et conçu pour GNU/Linux.
|
||||
|
||||
## Pourquoi le lanceur LCE Qt ?
|
||||
|
||||
- Développé en Python avec Qt 6 : léger et compatible avec le thème Plasma 6/Qt 6 de GNU/Linux
|
||||
- Personnalisation avec les thèmes et les modules/plugins (prochainement)
|
||||
- Intégration avec les outils communautaires
|
||||
- Compatibilité GNU/Linux optimale
|
||||
- Licence copyleft (GPLv3), donc sans big tech
|
||||
- Gratuit comme Freedom Launcher
|
||||
- Thème Minecraft par défaut
|
||||
|
||||
## Fonctionnalités
|
||||
|
||||
- Interface en ligne de commande (CLI)
|
||||
- Interface graphique Qt 6 (interface de type natif)
|
||||
- Écrit en Python (sans Electron ni Rust)
|
||||
- Personnalisable
|
||||
- Logiciel libre (GPLv3)
|
||||
- Instances multiples (en cours de développement)
|
||||
- Localisations (en cours de développement)
|
||||
<!-- Prochainement :
|
||||
- Plugins du Lanceur
|
||||
- Prise en charge des skin
|
||||
- Prise en charge des mods -->
|
||||
- Plusieurs instances par défaut : MCLE et Legacy Evolved
|
||||
- Prise en charge de plusieurs instances (en cours de développement)
|
||||
- Prise en charge des localisations (en cours de développement)
|
||||
- Instances préconfigurées :
|
||||
- [MCLCE/MinecraftConsoles](https://github.com/mclce/minecraftconsoles) (anciennement smartcmd/MinecraftConsoles)
|
||||
- LegacyEvolved (sera bientôt supprimé car remplacé par NeoLegacy)
|
||||
- [NeoLegacy](https://github.com/pieeebot/neoLegacy/)
|
||||
- Places de marché / Workshop :
|
||||
- [Atelier du lanceur Emeralds de LCE Hub](https://github.com/LCE-Hub/piston)
|
||||
- [LegacyMods (bientôt disponible)](https://legacymods.org/)
|
||||
- Actualités intégrées
|
||||
- Thème Minecraft préconfiguré
|
||||
|
||||
## Objectif à long terme
|
||||
## Objectif à long terme / Feuille de route
|
||||
|
||||
- Accessibilité
|
||||
- Prise en charge des mods
|
||||
- Plugins pour le lanceur
|
||||
- Prise en charge des thèmes
|
||||
- Compatibilité GNU/Linux
|
||||
- Prise en charge de Windows
|
||||
- Prise en charge expérimentale de FreeBSD
|
||||
@@ -42,18 +52,51 @@ Il s'agit d'un lanceur LCE personnalisé pour Minecraft, écrit en Python et Qt
|
||||
|
||||
### VSCode
|
||||
|
||||
1. Créez un environnement virtuel Python avec un outil comme UV.
|
||||
2. Configurez VSCode pour utiliser cet environnement virtuel Python.
|
||||
> [!NOTE]
|
||||
> Sous Windows, remplacez `/` par `\`.
|
||||
|
||||
> [!WARNING]
|
||||
> Cette méthode n'est ni recommandée ni testée pour NixOS. Consultez la section NixOS pour la procédure spécifique à ce système d'exploitation.
|
||||
|
||||
1. Créez un environnement virtuel Python à l'aide d'un outil comme UV (si ce n'est pas déjà fait).
|
||||
2. Configurez VS Code pour utiliser cet environnement virtuel Python.
|
||||
3. Exécutez « PySide : Sync Virtual Env and Launch ».
|
||||
4. Exécutez l'application via le mode débogage de VS Code ou via directement le fichier [`src/main.py`](src/main.py).
|
||||
4. Exécutez l'application via le mode débogage de VS Code ou directement le fichier [`src/lce_qt_launcher/main.py`](src/lce_qt_launcher/main.py).
|
||||
|
||||
### NixOS
|
||||
|
||||
1. Lancez le shell Nix avec la commande `nix-shell`.
|
||||
2. Compilez l'interface utilisateur et le fichier de ressources avec `scripts/build.sh`.
|
||||
3. Executé l'application avec `python src/lce_qt_launcher/main.py`.
|
||||
|
||||
### Autres
|
||||
|
||||
Guide à venir
|
||||
À venir
|
||||
|
||||
## Comment compiler
|
||||
|
||||
Disponible dans la prochaine version stable, lorsque le programme sera plus stable.
|
||||
### Compilation portable avec Nuitka
|
||||
|
||||
0. Créez un environnement virtuel Python avec un outil comme UV (si ce n'est pas déjà fait).
|
||||
1. Exécutez `hatch run packages`.
|
||||
|
||||
### Arch Linux
|
||||
|
||||
1. Accédez au répertoire `packages/linux`.
|
||||
2. Choisissez un canal : dev, nightly ou stable (accédez au répertoire correspondant).
|
||||
3. Exécutez `makepkg -si` ou `makepkg -s` (pour une installation sans paquets) dans l'un de ces répertoires.
|
||||
|
||||
### Paquet Nix
|
||||
|
||||
#### Nix Flake (Non testé/En cours de développement)
|
||||
Exécutez `nix build`
|
||||
|
||||
#### Nixpkg
|
||||
Exécutez `nix-build default.nix`
|
||||
|
||||
### Installateurs Flatpak et Windows
|
||||
|
||||
- Guide à venir
|
||||
|
||||
## Versions Quotidiennes (Nightly Release)
|
||||
|
||||
@@ -61,48 +104,56 @@ Disponible dans la prochaine version stable, lorsque le programme sera plus stab
|
||||
> Les versions quotidiennes automatiques sont actuellement instable, très expérimentale et en développement actif.
|
||||
> Cette branche n'est pas stable et des modifications y sont apportées presque quotidiennement ; elle peut donc parfois dysfonctionner. De plus, macOS n'est pas disponible dans la compilation nocturne en raison des restrictions d'Apple et du fait que je ne possède pas de Mac.
|
||||
|
||||
Sur cette page [GitHub Release](https://github.com/xgui4/LCE-Qt-Launcher/releases/tag/nightly), vous trouverez les versions de développement quotidiennes automatiques (Nighly Build), générées automatiquement via GitHub Actions lors de modifications apportées à la branche `nighly`.
|
||||
Sur cette page [GitHub Release](https://github.com/xgui4/LCE-Qt-Launcher/releases/tag/nightly), vous trouverez les versions nightly, générées automatiquement via GitHub Actions lors de modifications apportées à la branche `nighly`.
|
||||
|
||||
## Configuration logicielle requise
|
||||
|
||||
- [Python 3.11 (Pour FreeBSD) ou Python 3.12 ((GNU/Linux, Windows ou MacOS)](https://www.python.org)
|
||||
- Un environnement virtuel avec les bibliothèques requises installées (spécifiées dans le fichier README et [`pyproject.toml`](pyproject.toml))
|
||||
- [Python 3.11 (pour FreeBSD) à Python 3.12 (GNU/Linux, Windows et macOS)](https://www.python.org)
|
||||
- Un environnement virtuel avec les bibliothèques requises installées (spécifiées dans le fichier README et le fichier [`pyproject.toml`](pyproject.toml))
|
||||
- [PySide6](https://pypi.org/project/PySide6/)
|
||||
- [Police Monocraft](https://github.com/IdreesInc/Monocraft) installée
|
||||
- Pour un système de type UNIX
|
||||
- Un serveur d'affichage ou un compositeur (sauf sur macOS où un serveur propriétaire est utilisé)
|
||||
- Bash (Généralement préinstallé sous Linux, mais souvent requis sous *BSD et macOS)
|
||||
- Pour les systèmes de type UNIX
|
||||
- Un serveur d'affichage ou un compositeur (sauf sur macOS où un serveur propriétaire est utilisé).
|
||||
- Bash (normalement préinstallé sous Linux, mais souvent requis sous *BSD et macOS)
|
||||
|
||||
## Bibliothèques et outils Python utilisés
|
||||
|
||||
- PySide 6
|
||||
- requests
|
||||
- platformdirs
|
||||
- rich
|
||||
- hatch
|
||||
- uv
|
||||
|
||||
## Systèmes d'exploitation compatibles
|
||||
|
||||
### Compatibilité optimale
|
||||
|
||||
### Compatibilité officielle
|
||||
Plateformes testées régulièrement et avec implémentation/correctif finalisé
|
||||
- Windows 10 et versions ultérieures
|
||||
- GNU/Linux
|
||||
|
||||
### Compatibilité expérimentale
|
||||
Plateforme testée avec implémentation en cours de developement
|
||||
- NixOS
|
||||
|
||||
- FreeBSD
|
||||
### Plateformes prises en charge partiellement
|
||||
Plateformes non testées, mais avec implémentation
|
||||
- FreeBSD (Bien que cela puisse fonctionner, cela n'a pas encore été testé et le fonctionnement n'est pas garanti)
|
||||
- Flatpak (Bien que cela puisse fonctionner, cela n'a pas encore été testé et le fonctionnement n'est pas garanti)
|
||||
|
||||
### Systèmes d'exploitation non pris en charge
|
||||
Ces plateformes n'ont pas été testées et leur fonctionnement n'est pas garantis :
|
||||
- Autres systèmes *BSD, car Minecraft LCE n'est pas pris en charge sur ces systèmes et Wine n'est pas disponible.
|
||||
- Minecraft LCE sur Android est actuellement assez lent et bogué.
|
||||
- macOS : LCE Qt Launcher ne prend pas officiellement en charge macOS et n'est pas testé lors des contributions, mais la compatibilité POISX devrait permettre son utilisation.
|
||||
|
||||
- Autres systèmes *BSD, car Minecraft LCE n'est pas pris en charge sur ceux-ci et Wine n'est pas disponible.
|
||||
- Android : Minecraft LCE a actuellement des ralentissements et des bugs importants sur Android.
|
||||
- macOS : LCE Qt Launcher ne supporte pas officialiement MacOS et n'est pas tester lors des PR, mais la compatibilité POISX devrait permettre de l'utiliser.
|
||||
|
||||
## Remerciements
|
||||
### Remerciements particuliers à :
|
||||
|
||||
- [Prism Launcher](https://github.com/PrismLauncher/PrismLauncher) pour certains éléments et fichiers d'interface utilisateur
|
||||
- [MCLCE/MinecraftConsoles](https://github.com/MCLCE/MinecraftConsoles) pour le portage du jeu pour PC
|
||||
- [pieeebot/neoLegacy](https://github.com/pieeebot/neoLegacy) pour le backportage des mise a jours pour le pc port
|
||||
- [MCLCE/MinecraftConsoles](https://github.com/MCLCE/MinecraftConsoles)
|
||||
aftConsoles) pour le portage du jeu sur PC
|
||||
- [pieeebot/neoLegacy](https://github.com/pieeebot/neoLegacy) pour la rétrocompatibilité des mises à jour pour le portage PC
|
||||
- [LCE Hub](https://github.com/LCE-Hub) pour la Marketplace/Workshop
|
||||
|
||||
## Code de conduite
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ sdk: org.kde.Sdk
|
||||
|
||||
name: LCE Qt Launcher
|
||||
command: lce_qt_launcher
|
||||
summary: My First GTK App
|
||||
summary: An Minecraft Legacy Console Launcher For GNU/Linux
|
||||
description: |
|
||||
This is a custom Minecraft LCE Launcher written in
|
||||
Python and Qt with Freedom and with GNU/Linux support in mind.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Maintainer: Xgui4
|
||||
pkgname=lce-qt-launcher
|
||||
pkgver=0.0.1
|
||||
pkgver=0.0.2.0
|
||||
pkgrel=1
|
||||
pkgdesc="A custom Minecraft LCE Launcher written with PySide6 (Python) with GNU/Linux support in mind. (Master/Stable Branch)"
|
||||
arch=('any')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
; Non-commercial use only
|
||||
|
||||
#define MyAppName "LCE Qt Launcher (Nightly Preview Inno Setup 7 Installer)"
|
||||
#define MyAppVersion "2026.4.26"
|
||||
#define MyAppVersion "2026.5.1"
|
||||
#define MyAppPublisher "Xgui4"
|
||||
#define MyAppURL "https://github.com/xgui4/lce-qt-launcher"
|
||||
#define MyAppExeName "main.exe"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
; Non-commercial use only
|
||||
|
||||
#define MyAppName "LCE Qt Launcher (Nightly)"
|
||||
#define MyAppVersion "2026.4.26"
|
||||
#define MyAppVersion "2026.5.1"
|
||||
#define MyAppPublisher "Xgui4"
|
||||
#define MyAppURL "https://github.com/xgui4/lce-qt-launcher"
|
||||
#define MyAppExeName "main.exe"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
; Non-commercial use only
|
||||
|
||||
#define MyAppName "LCE Qt Launcher"
|
||||
#define MyAppVersion "1.0.0.1"
|
||||
#define MyAppVersion "1.0.2.0"
|
||||
#define MyAppPublisher "Xgui4"
|
||||
#define MyAppURL "https://github.com/xgui4/lce-qt-launcher"
|
||||
#define MyAppExeName "main.exe"
|
||||
|
||||
@@ -7,7 +7,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "LCE-Qt-Launcher"
|
||||
version = "0.0.1b1"
|
||||
version = "0.0.2b0"
|
||||
description = "This is a custom Free/Libre Minecraft LCE Launcher written in Python and Qt. (Beta Build)"
|
||||
requires-python = ">3.10, <3.13"
|
||||
license = "GPL-3.0-or-later"
|
||||
@@ -26,6 +26,7 @@ dependencies = [
|
||||
|
||||
[project.scripts]
|
||||
lce-qt-launcher = "lce_qt_launcher.main:main"
|
||||
lce-mod-managers = "lce_qt_launcher.managers.mod_managers:main"
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/xgui4/LCE-QT-Launcher"
|
||||
@@ -76,6 +77,7 @@ files = [
|
||||
"src/lce_qt_launcher/managers/system_managers.py",
|
||||
"src/lce_qt_launcher/managers/steam_managers.py",
|
||||
"src/lce_qt_launcher/managers/proton_managers.py",
|
||||
"src/lce_qt_launcher/managers/mod_managers.py",
|
||||
"src/lce_qt_launcher/models/__init__.py",
|
||||
"src/lce_qt_launcher/models/image_class.py",
|
||||
"src/lce_qt_launcher/models/preferences.py",
|
||||
|
||||
99
readme.md
99
readme.md
@@ -1,8 +1,8 @@
|
||||
# LCE QT Launcher
|
||||
|
||||
[French Version](lisezmoi.md)
|
||||
[French Version](lisezmoi.md) (Not updated yet)
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
> [!WARNING]
|
||||
@@ -13,26 +13,39 @@
|
||||
|
||||
This is a custom Minecraft LCE Launcher written in Python and Qt with Freedom and with GNU/Linux support in mind.
|
||||
|
||||
## Why LCE Qt Launcher ?
|
||||
|
||||
- Made in Python with Qt 6 : bloat free and integrate with GNU/Linux Plasma 6/Qt 6 Theme
|
||||
- Customisation with Themes and laters modules/plugins
|
||||
- Integration with Community Tools
|
||||
- GNU/Linux first class support
|
||||
- Licensed via copyleft licensing (GPLv3), so big tech free
|
||||
- Free as Freedom Launcher
|
||||
- Minecraft Themed by default
|
||||
|
||||
## Features
|
||||
|
||||
- Command Line interface (CLI)
|
||||
- Qt 6 GUI (Native like Interface)
|
||||
- Written in Python (No Electron or Rust)
|
||||
- Customisable
|
||||
- Free Software (GPLv3)
|
||||
- Multiple Instances (Work in progress)
|
||||
- localisations (Work in progress)
|
||||
<!-- Coming laters:
|
||||
- Launcher Plugins
|
||||
- Skin support
|
||||
- Modding Support -->
|
||||
- Multiples Defaults Instances : MCLE and Legacy Evolved
|
||||
- Multiple Instances support (Work in progress)
|
||||
- localisations support (Work in progress)
|
||||
- Pre-Configured ones :
|
||||
- [MCLCE/MinecraftConsoles](https://github.com/mclce/minecraftconsoles) (previously smartcmd/MinecraftConsoles)
|
||||
- LegacyEvolved (will be removed soon as was replaced with NeoLegacy)
|
||||
- [NeoLegacy](https://github.com/pieeebot/neoLegacy/)
|
||||
- [360Revived](https://github.com/BluTac10/360Revived)
|
||||
- [LCE-Revelations](https://github.com/itsRevela/LCE-Revelations)
|
||||
- [HellishEnds](https://github.com/deadvoxelx/HellishEnds)
|
||||
- Marketplaces :
|
||||
- [LCE Hub Emeralds Launcher Workshop](https://github.com/LCE-Hub/piston)
|
||||
- [LegacyMods (coming soon)](https://legacymods.org/)
|
||||
- in-app news
|
||||
- Minecraft Theme pre-configured
|
||||
|
||||
## Long Term Goal
|
||||
## Long Term Goal / Roadmap
|
||||
|
||||
- Accessibility
|
||||
- Modding Support
|
||||
- Launcher Plugins
|
||||
- Skin support
|
||||
- GNU/Linux compatibility
|
||||
- Windows support
|
||||
- Experimental FreeBSD support
|
||||
@@ -40,20 +53,51 @@ This is a custom Minecraft LCE Launcher written in Python and Qt with Freedom an
|
||||
|
||||
## How to run
|
||||
|
||||
### VSCode
|
||||
### VSCode
|
||||
|
||||
1. Create a Python Virtual Env via a tool like UV
|
||||
> [!NOTE]
|
||||
> In Windows where you need to replace `/` with `\`
|
||||
|
||||
> [!WARNING]
|
||||
> This method is not recommed nore tested for NixOS, go to the NixOS Section, for the step for this particular OS.
|
||||
|
||||
1. Create a Python Virtual Env via a tool like UV (if not already done)
|
||||
2. Set VSCode to that Python Virtual Env
|
||||
3. Run "Pyside : Sync Virtual Env and Launch"
|
||||
4. Run the app via Vscode debug mode or directly the [`src/main.py`](src/main.py) file.
|
||||
4. Run the app via Vscode debug mode or directly the [`src/lce_qt_launcher/main.py`](src/lce_qt_launcher/main.py) file.
|
||||
|
||||
### NixOS
|
||||
|
||||
1. load the nix shell with `nix-shell` command
|
||||
2. compiled the ui and ressource file with [`scripts/build.sh`](scripts/build.sh)
|
||||
3. load the app with [`python src/lce_qt_launcher/main.py`](src/lce_qt_launcher/main.py)
|
||||
|
||||
### Others
|
||||
|
||||
Guide coming laters
|
||||
coming soon
|
||||
|
||||
## How to build
|
||||
|
||||
Coming in the next stable release when the program will be more stable
|
||||
### Portable Nuitka Build
|
||||
|
||||
0. Create a Python Virtual Env via a tool like UV (if not already done)
|
||||
1. Run `hatch run packages`
|
||||
|
||||
### Arch Linux
|
||||
|
||||
1. Go the [`packages/linux` directory](packages/linux)
|
||||
2. Choose a channel dev, nigthly or stable (go to the directory)
|
||||
3. Run `makepkg -si` or `makepkg -s` (for no install) in one of these directory
|
||||
|
||||
### Nix Package
|
||||
|
||||
#### Nix Flake (Not tested yet/Work in progress)
|
||||
Run `nix build`
|
||||
#### Nixpkg
|
||||
Run `nix-build default.nix`
|
||||
|
||||
### Flatpak and Windows Installers
|
||||
- Guide Coming Later
|
||||
|
||||
## Nigthly Build
|
||||
|
||||
@@ -77,6 +121,7 @@ In this [GitHub Release](https://github.com/xgui4/LCE-Qt-Launcher/releases/tag/n
|
||||
|
||||
- PySide 6
|
||||
- requests
|
||||
- platformdirs
|
||||
- rich
|
||||
- hatch
|
||||
- uv
|
||||
@@ -84,25 +129,31 @@ In this [GitHub Release](https://github.com/xgui4/LCE-Qt-Launcher/releases/tag/n
|
||||
## Compatible Operating System
|
||||
|
||||
### Golden Support
|
||||
|
||||
Platform Tested Regurlaly and with completed implemation/patch
|
||||
- Windows 10 and later
|
||||
- GNU/Linux
|
||||
|
||||
### Experimental Support
|
||||
Plattform tested with work in progress implemation
|
||||
- NixOS
|
||||
|
||||
- FreeBSD
|
||||
### Partly Supported Platform
|
||||
Platform not tested yet, but with implementation
|
||||
- FreeBSD (While it may worked, it is not tested for it yet and might not worked at all)
|
||||
- Flatpak (While it may worked, it is not tested for it yet and might not worked at all)
|
||||
|
||||
### Unsupported OS
|
||||
|
||||
These platform are not tested and may work or not at all
|
||||
- Other *BSD system, as Minecraft LCE is not supported on those and Wine is not available.
|
||||
- Minecraft LCE on Android is currently quite laggy and buggy
|
||||
- macOS: LCE Qt Launcher does not officially support MacOS and is not tested during PRs, but POISX compatibility should allow its use.
|
||||
|
||||
## Thank to
|
||||
## Special Thank to
|
||||
|
||||
- [Prism Launcher](https://github.com/PrismLauncher/PrismLauncher) for certain UI elements and ui files
|
||||
- [MCLCE/MinecraftConsoles](https://github.com/MCLCE/MinecraftConsoles) for the port of the game for PC
|
||||
- [pieeebot/neoLegacy](https://github.com/pieeebot/neoLegacy) for backporting updates for the PC port
|
||||
- [LCE Hub](https://github.com/LCE-Hub) for the Marketplace/Workshop
|
||||
|
||||
## Code of Respect
|
||||
|
||||
|
||||
4
res.qrc
4
res.qrc
@@ -19,6 +19,7 @@
|
||||
<file alias="lce-evolved-ico.png">assets/images/lce-evolved-ico.png</file>
|
||||
<file alias="lce-hub-ico.png">assets/images/lce-hub-ico.png</file>
|
||||
<file alias="chest.png">assets/images/chest.png</file>
|
||||
<file alias="piston.png">assets/images/piston.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/styles">
|
||||
<file alias="minecraft.qss">assets/styles/minecraft.qss</file>
|
||||
@@ -29,6 +30,9 @@
|
||||
<file alias="default.lce_inst">data/defaults_instances/default.lce_inst</file>
|
||||
<file alias="legact_evolved.lce_inst">data/defaults_instances/legacy_evolved.lce_inst</file>
|
||||
<file alias="neoLegacy.lce_inst">data/defaults_instances/neoLegacy.lce_inst</file>
|
||||
<file alias="hellishends.lce_inst">data/defaults_instances/hellishends.lce_inst</file>
|
||||
<file alias="360Revived.lce_inst">data/defaults_instances/360Revived.lce_inst</file>
|
||||
<file alias="revelations.lce_inst">data/defaults_instances/revelation.lce_inst</file>
|
||||
</qresource>
|
||||
<qresource prefix="/languages">
|
||||
<file alias="fallback.json">assets/languages/translations.json</file>
|
||||
|
||||
251
src/form.ui
251
src/form.ui
@@ -35,7 +35,7 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<widget class="QTabWidget" name="instancesListWidget">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@@ -420,198 +420,78 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="instancesListTab">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="InstancesList">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../res.qrc">
|
||||
<normaloff>:/assets/chest.png</normaloff>:/assets/chest.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Instances (Coming Soon)</string>
|
||||
<string>Instances Lists</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="InstancesListTabMasterLayout">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="instancesList">
|
||||
<layout class="QVBoxLayout" name="InstancesListLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="defaulnstancesList">
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>24</pointsize>
|
||||
<bold>true</bold>
|
||||
<underline>false</underline>
|
||||
</font>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Default</string>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="resizeMode">
|
||||
<enum>QListView::ResizeMode::Fixed</enum>
|
||||
</property>
|
||||
<property name="itemAlignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
<property name="supportedDragActions">
|
||||
<set>Qt::DropAction::ActionMask</set>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="defaultsInstanceList">
|
||||
<item alignment="Qt::AlignmentFlag::AlignHCenter|Qt::AlignmentFlag::AlignTop">
|
||||
<widget class="QWidget" name="defaultInstance1" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTipDuration">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="defaultInstance1Layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="defaultInstance1Icon">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>75</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../res.qrc">:/assets/minecraft.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="defaultInstance1Name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1. Default
|
||||
(MCLCE)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||
<widget class="QWidget" name="defaultInstance2" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="defaultInstance2Layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="defaultInstance2Icon">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../res.qrc">:/assets/lce-evolved-ico.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="defaultInstance2Name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2. Legacy Evolved </string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignmentFlag::AlignHCenter|Qt::AlignmentFlag::AlignTop">
|
||||
<widget class="QWidget" name="defaultInstance3" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="defaultInstance3Layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="defaultInstance3Icon">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>75</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../res.qrc">:/assets/lce-hub-ico.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="defaultInstance3Name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3. neoLegacy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="Marketplaces">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../res.qrc">
|
||||
<normaloff>:/assets/piston.png</normaloff>:/assets/piston.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Marketplaces</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="marketplacesFrameGrid">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="marketplaceFrameRow">
|
||||
<item>
|
||||
<widget class="QWebEngineView" name="marketplacesWebsiteEngine">
|
||||
<property name="url">
|
||||
<url>
|
||||
<string>https://lce-hub.github.io/piston/</string>
|
||||
</url>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="NewsTab">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../res.qrc">
|
||||
@@ -705,10 +585,18 @@
|
||||
<addaction name="actionNews"/>
|
||||
<addaction name="actionSetting_2"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuMarketplace">
|
||||
<property name="title">
|
||||
<string>Marketplace</string>
|
||||
</property>
|
||||
<addaction name="actionLCE_Hub_Workshop"/>
|
||||
<addaction name="actionLegacyMods_Coming_Soon"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuEdit"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuFolders"/>
|
||||
<addaction name="menuMarketplace"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<action name="actionQuit">
|
||||
@@ -1015,6 +903,23 @@
|
||||
<string>Report a Bugs or Suggest a feature </string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLCE_Hub_Workshop">
|
||||
<property name="icon">
|
||||
<iconset resource="../res.qrc">
|
||||
<normaloff>:/assets/piston.png</normaloff>:/assets/piston.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>LCE-Hub Workshop</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLegacyMods_Coming_Soon">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>LegacyMods (Coming Soon)</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from enum import StrEnum
|
||||
|
||||
FALLBACK_APP_NAME = "LCE Qt Launcher"
|
||||
FALLBACK_VERSION_NUMBER = "0.0.1b1"
|
||||
FALLBACK_VERSION_NUMBER = "0.0.2b1"
|
||||
FALLBACK_LICENSE = "GPLv3"
|
||||
FALLBACK_LICENSE_LINK = "https://www.gnu.org/licenses/gpl-3.0"
|
||||
FALLBACK_GIT_REPO_URL = "https://github.com/xgui4/LCE-QT-Launcher"
|
||||
|
||||
@@ -14,8 +14,10 @@ from PySide6.QtWidgets import (
|
||||
|
||||
from lce_qt_launcher.app_context import AppContext
|
||||
from lce_qt_launcher.build_info import BuildInfo
|
||||
from lce_qt_launcher.managers import import_managers
|
||||
from lce_qt_launcher.managers.instance_manager import Instance, InstanceManager
|
||||
from lce_qt_launcher.managers.system_manager import SystemManager
|
||||
from lce_qt_launcher.models.app_data import AppData
|
||||
from lce_qt_launcher.models.preferences import UserPref
|
||||
from lce_qt_launcher.ui_settingDialog import Ui_settingDialog
|
||||
from lce_qt_launcher.views.browser_dialog import BrowserDialog
|
||||
@@ -82,13 +84,14 @@ def show_instance_editor(parent : QWidget) -> None:
|
||||
"""Features : Open the Instance Editor"""
|
||||
parent.instance_window.show()
|
||||
|
||||
def load_instance(parent : QWidget, instanceManager : InstanceManager, appContext: AppContext, buildInfo : BuildInfo) -> None:
|
||||
def load_instance(parent : QWidget, instanceManager : InstanceManager, appContext: AppContext, buildInfo : BuildInfo, appData : AppData) -> None:
|
||||
"""Features : Load the Selected Instance"""
|
||||
file_name: tuple[str, str] = QFileDialog.getOpenFileName(
|
||||
parent, "Load Instance File",
|
||||
appContext.sys_man.found_default_save_path(),
|
||||
f"{buildInfo.app_name} Instance (*{buildInfo.instance_extension})")
|
||||
instanceManager.load_instance(file_name[0])
|
||||
import_managers.import_inst_file_to_app_data(file_name[0], appData)
|
||||
|
||||
def show_about_qt(parent : QWidget) -> None:
|
||||
"""Features : Load the Selected Instance"""
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
# nuitka-project: --include-data-dir=data=data
|
||||
# nuitka-project: --include-qt-plugins=sensible
|
||||
# nuitka-project: --windows-console-mode=force
|
||||
# nuitka-project: --product-version="1.0.0.11"
|
||||
# nuitka-project: --file-version="1.0.0.11"
|
||||
# nuitka-project: --product-version="1.0.0.20"
|
||||
# nuitka-project: --file-version="1.0.0.20"
|
||||
# nuitka-project: --file-description="Custom Free/Libre Minecraft LCE Launcher (Nightly)"
|
||||
# nuitka-projet: --include-distribution-metadata=lce-qt-launcher
|
||||
# nuitka-project: --copyright="Copyleft Xgui4 2026 (GPLv3)"
|
||||
|
||||
12
src/lce_qt_launcher/managers/import_managers.py
Normal file
12
src/lce_qt_launcher/managers/import_managers.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from lce_qt_launcher.models.app_data import AppData
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import os
|
||||
|
||||
def import_inst_file_to_app_data(instance_file_path : str, appData : AppData, filename : str = ""):
|
||||
if filename == "":
|
||||
filename_Path = Path(f"{instance_file_path}")
|
||||
filename = filename_Path.name
|
||||
destinations = os.path.join(appData.appDataDirs[0], "instances", filename)
|
||||
os.symlink(instance_file_path, destinations)
|
||||
@@ -20,6 +20,8 @@ import subprocess
|
||||
import json
|
||||
import os
|
||||
|
||||
SCHEME_VERSION = "https://raw.githubusercontent.com/xgui4/LCE-Qt-Launcher/refs/heads/beta/schemas/x-application-lce_inst.json"
|
||||
|
||||
class InstanceSource(Enum):
|
||||
"""_summary_ The 4 Type of Instances (2 functional, the othes coming soon)
|
||||
"""
|
||||
@@ -146,8 +148,6 @@ _DEFAULT_INST_TYPE_STRING = "InstanceType.CLIENT_VANILLA"
|
||||
_DEFAULT_IMAGE = ":/assets/minecraft.png"
|
||||
_DEFAULT_NEWS_FEED = "https://github.com/MCLCE/minecraftconsoles/commits"
|
||||
_DEFAULT_VERSION = "nightly"
|
||||
_DEFAULT_SKIN_PATH = ""
|
||||
_DEFAULT_SERVERS: list[str] = []
|
||||
|
||||
class Instance:
|
||||
"""_summary_ An config and inform an instance of Minecraft LCE Installed or to install
|
||||
@@ -164,8 +164,6 @@ class Instance:
|
||||
instance_type : InstanceType = _DEFAULT_INST_TYPE,
|
||||
news_feed : str = _DEFAULT_NEWS_FEED,
|
||||
version : str = _DEFAULT_VERSION,
|
||||
skin_path : str = _DEFAULT_SKIN_PATH,
|
||||
servers : list[str] = _DEFAULT_SERVERS
|
||||
) -> None:
|
||||
self.name: str = name
|
||||
self.installation_path: str = installation_path
|
||||
@@ -178,8 +176,6 @@ class Instance:
|
||||
self.image : str = image
|
||||
self.news_feed : str = news_feed
|
||||
self.version: str = version
|
||||
self.skin_path: str = skin_path
|
||||
self.servers: list[str] = servers
|
||||
|
||||
def load_inst_from_dict(self, inst_dict: dict[str, str]) -> None:
|
||||
"""_summary_ Load A JSON to a empty Instance Object to import it
|
||||
@@ -198,9 +194,6 @@ class Instance:
|
||||
self.image = inst_dict.get("image", _DEFAULT_IMAGE)
|
||||
self.news_feed = inst_dict.get("news_feed", _DEFAULT_NEWS_FEED)
|
||||
self.version = inst_dict.get("version", _DEFAULT_VERSION)
|
||||
# self.skin_path = inst_dict.get("skin_path", _DEFAULT_SKIN_PATH)
|
||||
# self.servers = inst_dict.get("servers", _DEFAULT_SERVERS)
|
||||
|
||||
def get_download_url(self) -> str:
|
||||
"""_summary_ Get the download URL of a Instance
|
||||
|
||||
@@ -224,6 +217,23 @@ class Instance:
|
||||
else:
|
||||
raise RuntimeError("Not implemented yet!")
|
||||
|
||||
def to_dict(self) -> dict[str, str]:
|
||||
dict_to_return : dict[str, str ] = {
|
||||
"$schema" : SCHEME_VERSION,
|
||||
"name" : self.name,
|
||||
"installation_path" : self.installation_path,
|
||||
"username" : self.username,
|
||||
"exe_name" : self.exe_name,
|
||||
"archive_file" : self.archive_file,
|
||||
"repo_url" : self.repo_url,
|
||||
"instance_source" : self.instance_source.name,
|
||||
"instance_type" : self.instance_type.name,
|
||||
"image" : self.image,
|
||||
"news_feed" : self.news_feed,
|
||||
"version" : self.version
|
||||
}
|
||||
return dict_to_return
|
||||
|
||||
def display(self) -> None:
|
||||
print(f"Name : {self.name}")
|
||||
print(f"=============================")
|
||||
@@ -237,8 +247,7 @@ class Instance:
|
||||
print(f"instance type : {self.instance_source.value}")
|
||||
print(f"news_feed : {self.news_feed}")
|
||||
print(f"version : {self.version}")
|
||||
print(f"skin : {self.skin_path}")
|
||||
print(f"servers : {self.servers}")
|
||||
# print(f"servers : {self.servers}")
|
||||
|
||||
class InstanceManager:
|
||||
"""_summary_ The Manager for Instances objects"""
|
||||
@@ -254,7 +263,8 @@ class InstanceManager:
|
||||
str: _description_ error message or status and exit codes
|
||||
"""
|
||||
try:
|
||||
game_process = subprocess.run(os.path.join(self.instance.installation_path, self.instance.exe_name))
|
||||
client_path : str = os.path.join(self.instance.installation_path, self.instance.exe_name)
|
||||
game_process = subprocess.run([client_path, "-name", self.instance.username])
|
||||
except TimeoutExpired as err:
|
||||
term_service.print_error(f"process of lauching instance {self.instance.name} Failed. Reason : Timeout Expired.\n traceback : {err.with_traceback}")
|
||||
return f"process of lauching instance {self.instance.name} Failed. Reason : Timeout Expired.\n traceback : {err.with_traceback}"
|
||||
@@ -287,14 +297,15 @@ class InstanceManager:
|
||||
Args:
|
||||
save_file (str): _description_ specified save file and location
|
||||
"""
|
||||
full_save_file = save_file
|
||||
json_string : str = ""
|
||||
try:
|
||||
json_string = json.dumps(vars(self.instance), indent=4,)
|
||||
except:
|
||||
json_string = json.dumps(obj=vars(self.instance), indent=4, default=str)
|
||||
if not save_file.endswith(self._build_info.instance_extension):
|
||||
save_file: str = save_file + self._build_info.instance_extension
|
||||
with open(file=save_file, mode='w') as f:
|
||||
full_save_file: str = save_file + self._build_info.instance_extension
|
||||
with open(file=full_save_file, mode='w') as f:
|
||||
_ = f.write(json_string)
|
||||
|
||||
def load_instance(self, save_file : str) -> None:
|
||||
@@ -307,8 +318,5 @@ class InstanceManager:
|
||||
"""
|
||||
with open(file=save_file, mode='r') as json_file:
|
||||
json_data = json.load(json_file) # pyright: ignore[reportAny]
|
||||
#if json_data == dict[str, str]:
|
||||
inst_dict : dict[str, str] = json_data # pyright: ignore[reportAny]
|
||||
#else:
|
||||
# raise RuntimeError("Invalid Dictionary")
|
||||
self.instance.load_inst_from_dict(inst_dict)
|
||||
|
||||
167
src/lce_qt_launcher/managers/mod_managers.py
Executable file
167
src/lce_qt_launcher/managers/mod_managers.py
Executable file
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
LCE Mods Manager
|
||||
Copyright (C) 2026 Xgui4
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from enum import StrEnum
|
||||
from zipfile import ZipFile
|
||||
|
||||
DLC_LOCATION = os.path.join("Windows64Media", "DLC")
|
||||
WORLD_LOCATION = os.path.join("Windows64", "GameHDD")
|
||||
MOD_LOCATION = os.path.join("Windows64", "Media")
|
||||
|
||||
class ContentType(StrEnum):
|
||||
DLC = DLC_LOCATION
|
||||
WORLD = WORLD_LOCATION
|
||||
MOD = MOD_LOCATION
|
||||
NONE = "0"
|
||||
CUSTOM_SKIN = "-1" # Temporaly placeholder DO NOT USE,
|
||||
|
||||
LEGAL_TEXT = """
|
||||
LCE Mods Managers Copyright (C) 2026 Xgui4
|
||||
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
"""
|
||||
|
||||
def extract_zip(data : ZipFile, extraction_path : str) -> None:
|
||||
"""
|
||||
_summary_ : extract the zipfile of the content to the desired path
|
||||
|
||||
Args:
|
||||
data : the zip file itself
|
||||
extraction_path : the specified extraction path
|
||||
#TODO Make Async
|
||||
"""
|
||||
data.extractall(extraction_path)
|
||||
|
||||
def install_content(instance_path : str, contentType : ContentType, archive_file : str):
|
||||
"""_summary_ #TODO docstring
|
||||
|
||||
Args:
|
||||
instance_path (str): _description_
|
||||
contentType (ContentType): _description_
|
||||
archive_file (str): _description_
|
||||
"""
|
||||
zipFile = ZipFile(archive_file)
|
||||
|
||||
content_path : str = os.path.join(instance_path, contentType.value)
|
||||
|
||||
extract_zip(zipFile, content_path)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="LCE Mods Manager",
|
||||
description="Manage DLC, World and Mods for Minecraft LCE"
|
||||
)
|
||||
|
||||
file : str = ""
|
||||
contentType : str = ""
|
||||
instance_path : str = ""
|
||||
contentTypeEnum : ContentType = ContentType.NONE
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
parser.add_help = True
|
||||
parser.epilog = LEGAL_TEXT
|
||||
|
||||
parser.add_argument("--instance_path", type=str, help="Path of the instance to install the content on")
|
||||
parser.add_argument("--content_type", type=str, help="Content Type, possible valie : DLC, World and Mod")
|
||||
parser.add_argument("--file", type=str, help="The Archive file to install")
|
||||
|
||||
parsed_cmd_args = parser.parse_known_intermixed_args()
|
||||
|
||||
contentType : str = parsed_cmd_args[0].content_type
|
||||
|
||||
contentTypeEnum : ContentType = ContentType.NONE
|
||||
|
||||
if parsed_cmd_args[0].content_type == "None":
|
||||
print(r"""
|
||||
1. Install Maps/World
|
||||
2. Install DLC
|
||||
3. Install Mods
|
||||
4. Install Custom Skin (Coming Soon)
|
||||
5. Cancel
|
||||
""")
|
||||
|
||||
user_input = input("Choose a option")
|
||||
|
||||
if user_input == "1":
|
||||
contentTypeEnum = ContentType.WORLD
|
||||
if user_input == "2":
|
||||
contentTypeEnum = ContentType.DLC
|
||||
if user_input == "3":
|
||||
contentTypeEnum = ContentType.MOD
|
||||
else:
|
||||
raise RuntimeError("Not impleted Yet")
|
||||
|
||||
if (contentType == "DLC"):
|
||||
contentTypeEnum = ContentType.DLC
|
||||
if (contentType == "World"):
|
||||
contentTypeEnum = ContentType.WORLD
|
||||
if (contentType == "Mod"):
|
||||
contentTypeEnum = ContentType.MOD
|
||||
else:
|
||||
pass
|
||||
|
||||
instance_path = parsed_cmd_args[0].instance_path
|
||||
|
||||
if instance_path == "None":
|
||||
instance_path = input("Enter the Instance path.")
|
||||
|
||||
file : str = parsed_cmd_args[0].file
|
||||
|
||||
if file == "None":
|
||||
file = input(f"Enter the archive of the {contentTypeEnum.name}")
|
||||
|
||||
else:
|
||||
print(r"""
|
||||
1. Install Maps/World
|
||||
2. Install DLC
|
||||
3. Install Mods
|
||||
4. Install Custom Skin (Coming Soon)
|
||||
5. Cancel
|
||||
""")
|
||||
|
||||
user_input = input("Choose a option")
|
||||
|
||||
if user_input == "1":
|
||||
contentTypeEnum = ContentType.WORLD
|
||||
if user_input == "2":
|
||||
contentTypeEnum = ContentType.DLC
|
||||
if user_input == "3":
|
||||
contentTypeEnum = ContentType.MOD
|
||||
else:
|
||||
raise RuntimeError("Not impleted Yet")
|
||||
|
||||
instance_path = input("Enter the Instance path.")
|
||||
|
||||
file = input(f"Enter the archive of the {contentTypeEnum.name}")
|
||||
|
||||
print(LEGAL_TEXT)
|
||||
|
||||
print(f"""File : {file}
|
||||
Content Type : {contentTypeEnum.value}
|
||||
Instance_Path : {instance_path}""")
|
||||
|
||||
install_content(instance_path, contentTypeEnum, file)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -9,6 +9,8 @@ from pathlib import Path
|
||||
import json
|
||||
import os
|
||||
|
||||
from lce_qt_launcher.views import term_service
|
||||
|
||||
def _is_compiled() -> bool:
|
||||
return "__compiled__" in globals()
|
||||
|
||||
@@ -37,7 +39,15 @@ class AppData(QObject):
|
||||
#TODO : docstring
|
||||
"""
|
||||
defaults_insts_dir : Path = Path(os.path.join(self.appDataDirs[0], "instances"))
|
||||
print(defaults_insts_dir)
|
||||
if not defaults_insts_dir.exists():
|
||||
term_service.print_information(f"{defaults_insts_dir} did not exist. Trying to recreate it.")
|
||||
try:
|
||||
os.makedirs(defaults_insts_dir)
|
||||
except OSError:
|
||||
term_service.print_error("An OS error have occured : {OSError}")
|
||||
except RuntimeError:
|
||||
term_service.print_error("An une error have occured : {RuntineError}")
|
||||
return
|
||||
instancesLists : list[Instance] = []
|
||||
for file_path in defaults_insts_dir.iterdir():
|
||||
@@ -49,7 +59,9 @@ class AppData(QObject):
|
||||
new_inst.load_inst_from_dict(context_dict)
|
||||
instancesLists.append(new_inst)
|
||||
except (json.JSONDecodeError, OSError, ValueError):
|
||||
continue
|
||||
term_service.print_error(f"Cannot decode JSON {OSError} {ValueError} {json.JSONDecodeError}")
|
||||
else:
|
||||
term_service.print_information(f"{file_path} was not a file.")
|
||||
self.instsList = instancesLists
|
||||
|
||||
def _get_source_dir(self) -> str:
|
||||
@@ -98,7 +110,7 @@ class AppData(QObject):
|
||||
Returns:
|
||||
str: _description_
|
||||
"""
|
||||
dirs: PlatformDirs = PlatformDirs("Xgui4", "LCE-Qt-Launcher")
|
||||
dirs: PlatformDirs = PlatformDirs("LCE-Qt-Launcher", "Xgui4")
|
||||
return dirs.user_data_dir
|
||||
|
||||
def _get_site_app_data_dir(self) -> str:
|
||||
@@ -107,7 +119,7 @@ class AppData(QObject):
|
||||
Returns:
|
||||
str: _description_
|
||||
"""
|
||||
dirs: PlatformDirs = PlatformDirs("Xgui4", "LCE-Qt-Launcher")
|
||||
dirs: PlatformDirs = PlatformDirs("LCE-Qt-Launcher", "Xgui4")
|
||||
return dirs.site_data_dir
|
||||
|
||||
def _get_app_cache_dir(self) -> str:
|
||||
@@ -116,7 +128,7 @@ class AppData(QObject):
|
||||
Returns:
|
||||
str: _description_
|
||||
"""
|
||||
dirs: PlatformDirs = PlatformDirs("Xgui4", "LCE-Qt-Launcher")
|
||||
dirs: PlatformDirs = PlatformDirs("LCE-Qt-Launcher", "Xgui4")
|
||||
return dirs.user_cache_dir
|
||||
|
||||
def _get_app_log_dir(self) -> str:
|
||||
@@ -125,7 +137,7 @@ class AppData(QObject):
|
||||
Returns:
|
||||
str: _description_
|
||||
"""
|
||||
dirs: PlatformDirs = PlatformDirs("Xgui4", "LCE-Qt-Launcher")
|
||||
dirs: PlatformDirs = PlatformDirs("LCE-Qt-Launcher", "Xgui4")
|
||||
return dirs.user_log_dir
|
||||
|
||||
def _get_app_config_dir(self) -> str:
|
||||
@@ -134,5 +146,5 @@ class AppData(QObject):
|
||||
Returns:
|
||||
str: _description_
|
||||
"""
|
||||
dirs: PlatformDirs = PlatformDirs("Xgui4", "LCE-Qt-Launcher")
|
||||
dirs: PlatformDirs = PlatformDirs("LCE-Qt-Launcher", "Xgui4")
|
||||
return dirs.user_config_dir
|
||||
22
src/lce_qt_launcher/views/instance_view.py
Normal file
22
src/lce_qt_launcher/views/instance_view.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from PySide6.QtWidgets import QDialog, QHBoxLayout, QWidget
|
||||
from PySide6.QtWebEngineWidgets import QWebEngineView
|
||||
from PySide6.QtCore import QUrl
|
||||
|
||||
from lce_qt_launcher.build_info import BuildInfo
|
||||
|
||||
class InstanceView(QDialog):
|
||||
"""_summary_ #TODO docstring
|
||||
|
||||
Args:
|
||||
QDialog (_type_): _description_
|
||||
"""
|
||||
def __init__(self, parent : QWidget, url : str, build_info : BuildInfo) -> None:
|
||||
super().__init__()
|
||||
browser_dialog = QDialog(parent)
|
||||
webview = QWebEngineView()
|
||||
webview.load(QUrl(url))
|
||||
browser_dialog.setWindowTitle(build_info.app_name)
|
||||
layout = QHBoxLayout()
|
||||
layout.addWidget(webview)
|
||||
browser_dialog.setLayout(layout)
|
||||
browser_dialog.show()
|
||||
@@ -2,15 +2,17 @@ from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
QMainWindow,
|
||||
QLabel,
|
||||
QDialog
|
||||
QDialog,
|
||||
QListWidgetItem
|
||||
)
|
||||
from PySide6.QtGui import (
|
||||
QPalette,
|
||||
QPixmap,
|
||||
QPixmap,
|
||||
QBrush
|
||||
)
|
||||
from PySide6.QtCore import (
|
||||
qVersion
|
||||
qVersion,
|
||||
Qt
|
||||
)
|
||||
|
||||
import sys
|
||||
@@ -22,7 +24,7 @@ from pathlib import Path
|
||||
|
||||
from lce_qt_launcher.managers.system_manager import SystemManager
|
||||
from lce_qt_launcher.app_context import AppContext
|
||||
from lce_qt_launcher.managers.instance_manager import InstanceManager
|
||||
from lce_qt_launcher.managers.instance_manager import Instance, InstanceManager
|
||||
from lce_qt_launcher.build_info import BuildInfo
|
||||
from lce_qt_launcher.models.app_data import AppData
|
||||
from lce_qt_launcher.ui_about import Ui_AboutDialog
|
||||
@@ -118,7 +120,7 @@ class Launcher(QMainWindow):
|
||||
def load_instance() -> None:
|
||||
"""_summary_ Open the Load Save File Dialog
|
||||
"""
|
||||
features.load_instance(self, instanceManager, appContext, buildInfo)
|
||||
features.load_instance(self, instanceManager, appContext, buildInfo, appData)
|
||||
self.image_label = instanceManager.instance.image
|
||||
self.news_feed = instanceManager.instance.news_feed
|
||||
self.instance_name = instanceManager.instance.name
|
||||
@@ -128,7 +130,7 @@ class Launcher(QMainWindow):
|
||||
pixmap = QPixmap(self.image_label)
|
||||
self.ui.instance_img.setPixmap(pixmap)
|
||||
self.ui.repo_name_branch.setText(self.instance_name)
|
||||
self.ui.newsEngineView.setUrl(self.news_feed)
|
||||
self.ui.newsEngineView.setUrl(self.news_feed)
|
||||
|
||||
def show_setting_dialog() -> None:
|
||||
"""_summary_ Show the setting Dialog
|
||||
@@ -247,6 +249,14 @@ class Launcher(QMainWindow):
|
||||
_ = self.ui.actionSave.triggered.connect(save_instance)
|
||||
_ = self.ui.actionImport_Instance.triggered.connect(load_instance)
|
||||
|
||||
open_workshop = lambda : features.show_webbrowser(self, "https://lce-hub.github.io/piston/", buildInfo);
|
||||
|
||||
_ = self.ui.actionLCE_Hub_Workshop.triggered.connect(open_workshop)
|
||||
|
||||
open_legacymods = lambda : features.show_webbrowser(self, "https://legacymods.org/", buildInfo);
|
||||
|
||||
_ = self.ui.actionLegacyMods_Coming_Soon.triggered.connect(open_legacymods)
|
||||
|
||||
openAppRoot = lambda : systemManager.open_url_with_system(appData.projectRootDir);
|
||||
_= self.ui.actionApp_Root.triggered.connect(openAppRoot)
|
||||
|
||||
@@ -256,6 +266,16 @@ class Launcher(QMainWindow):
|
||||
open_github_issues = lambda : webbrowser.open(appContext.buildInfo.git_repo_url + "/issues")
|
||||
_ = self.ui.actionReport_a_Bugs_or_Sugess_a_feature.triggered.connect(open_github_issues)
|
||||
|
||||
instances : list[Instance] = list()
|
||||
|
||||
for inst in appData.instsList:
|
||||
instances.append(inst)
|
||||
item = QListWidgetItem()
|
||||
item.setText(inst.name)
|
||||
item.setIcon(QPixmap(inst.image))
|
||||
item.setData(Qt.ItemDataRole.FileInfoRole, inst)
|
||||
self.ui.listWidget.addItem(item)
|
||||
|
||||
self.versionlabel: QLabel = QLabel(f"Version {buildInfo.version}")
|
||||
self.ui.statusbar.addPermanentWidget(self.versionlabel)
|
||||
holyday_label: QLabel = QLabel(holiday.get_holiday())
|
||||
|
||||
Reference in New Issue
Block a user