Compare commits

..

59 Commits

Author SHA1 Message Date
Nix
07571aaeb0
Update version.json
Some checks failed
Version Change Action / version-release (push) Has been cancelled
2024-12-31 15:08:07 -03:00
Nix
63dc90b239
Update Build.yml 2024-12-31 15:07:46 -03:00
Nix
fc4ac0ba56
Update version.json 2024-12-31 14:56:12 -03:00
Nix
15c161faff
Update Build.yml 2024-12-31 14:56:01 -03:00
Nix
2db2f1b18b
Update version.json 2024-12-31 14:53:18 -03:00
Nix
a582b497f8
Update Build.yml 2024-12-31 14:53:07 -03:00
Nix
93d607229e
Update version.json 2024-12-31 14:51:49 -03:00
Nix
9634a378ab
Update Build.yml 2024-12-31 14:51:31 -03:00
Nix
247f801d35
Update version.json 2024-12-31 14:48:25 -03:00
Nix
645cfeb52b
Update Build.yml 2024-12-31 14:48:10 -03:00
Nix
6596ad44f8
Update version.json 2024-12-31 14:45:08 -03:00
Nix
228565daf3
Update Build.yml 2024-12-31 14:44:44 -03:00
Nix
b45951cab6
Update version.json 2024-12-31 14:41:42 -03:00
Nix
76d88787ac
Update Build.yml 2024-12-31 14:41:10 -03:00
Nix
19332fd936
Update version.json 2024-12-31 14:40:17 -03:00
Nix
cef44074c5
Update Build.yml 2024-12-31 14:39:42 -03:00
Nix
2a4ba7cfcf
Update version.json 2024-12-31 14:37:58 -03:00
Nix
e6b4a7acf3
Update Build.yml 2024-12-31 14:37:43 -03:00
Nix
97215e4c75
Update version.json 2024-12-31 14:33:00 -03:00
Nix
6c93ab07c5
Update Build.yml 2024-12-31 14:32:09 -03:00
Nix
14855f2f00
Update version.json 2024-12-31 14:28:20 -03:00
Nix
897fa4c8b7
Update Build.yml 2024-12-31 14:27:53 -03:00
Nix
7ca5855198
Update version.json 2024-12-31 14:23:04 -03:00
Nix
5a6bdd3aad
Update Build.yml 2024-12-31 14:22:50 -03:00
Nix
b35063d0b2
Update version.json 2024-12-31 11:45:30 -03:00
Nix
fe6d409fb5
Update Build.yml 2024-12-31 11:45:14 -03:00
Nix
bce36c3728
Update version.json 2024-12-31 11:40:24 -03:00
Nix
aa8a72c8cb
Update Build.yml 2024-12-31 11:40:14 -03:00
Nix
b3155b4844
Update version.json 2024-12-31 11:37:40 -03:00
Nix
aaf141e338
Update Build.yml 2024-12-31 11:37:28 -03:00
Nix
c125f440f8
Update version.json 2024-12-31 11:33:59 -03:00
Nix
1543b36eb5
Update Build.yml 2024-12-31 11:33:40 -03:00
Nix
eb6b27ed23
Update version.json 2024-12-31 11:28:06 -03:00
Nix
0702f918dd
Update Build.yml 2024-12-31 11:27:09 -03:00
Nix
5792bcb6eb
Update version.json 2024-12-31 11:23:44 -03:00
Nix
b6241e7aad
Update Build.yml 2024-12-31 11:23:29 -03:00
Nix
0ac8a1bf51
Update version.json 2024-12-31 11:17:45 -03:00
Nix
60e532b604
Update Build.yml 2024-12-31 11:17:22 -03:00
Nix
52b07aab71
Update version.json 2024-12-31 11:13:57 -03:00
Nix
bb48b3e293
Update Build.yml 2024-12-31 11:13:19 -03:00
Nix
f86bb54abe
Update version.json 2024-12-31 11:05:01 -03:00
Nix
35e1cd7d17
Update Build.yml 2024-12-31 11:04:36 -03:00
Nix
c0ce394fda
Update version.json 2024-12-31 11:00:24 -03:00
Nix
1f739f25e8
Update Build.yml 2024-12-31 11:00:06 -03:00
Nix
2d362843c2
Update version.json 2024-12-31 10:58:39 -03:00
Nix
ae14820c4d
Update Build.yml 2024-12-31 10:58:21 -03:00
Nix
50b3f09ed1
Update version.json 2024-12-31 10:55:46 -03:00
Nix
b9bf71334b
Update Build.yml 2024-12-31 10:54:42 -03:00
Nix
40bf8ea23e
Update Build.yml 2024-12-31 10:49:57 -03:00
Nix
89cf8218f8
Update version.json 2024-12-31 10:45:32 -03:00
Nix
520a1b500f
Update Build.yml 2024-12-31 10:45:17 -03:00
Nix
b6a3218bf6
Update version.json 2024-12-31 10:40:53 -03:00
Nix
c1c98aafae
Create Build.yml 2024-12-31 10:40:30 -03:00
Nix
34c36c5b88
Update picodulce.py 2024-12-30 10:39:06 -03:00
Nix
fc058913cd
Update version.json 2024-12-29 14:07:42 -03:00
Nix
523431a557
Update README.md 2024-12-29 11:03:27 -03:00
Nix
72f7cbec9d
Update version.json 2024-12-29 11:01:06 -03:00
Nix
fbdba505c9
Added instance support 2024-12-29 11:00:48 -03:00
Nix
479bc4486a
Update version.json 2024-12-29 11:00:08 -03:00
10 changed files with 442 additions and 1029 deletions

View File

@ -1,36 +0,0 @@
name: Bleeding Update version
on:
push:
branches:
- main
jobs:
update-version:
runs-on: ubuntu-latest
steps:
- name: Check out the repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Update version.json
run: |
git fetch --prune --unshallow
commit_count=$(git rev-list --count HEAD)
version=$(jq -r '.version' version.json)
jq --arg versionBleeding "$version-$commit_count" '. + {versionBleeding: $versionBleeding}' version.json > version.tmp && mv version.tmp version.json
- name: Commit and push changes
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add version.json
git commit -m "Update version.json with commit count"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -9,8 +9,6 @@ jobs:
version-release:
runs-on: windows-latest # Use Windows 10 runner
if: github.actor != 'github-actions[bot]' # Only run if the actor is not the GitHub Actions bot
steps:
- name: Checkout repository
uses: actions/checkout@v3
@ -38,7 +36,7 @@ jobs:
run: |
dir actions-temp
dir
- name: Get version and name from version.json
id: version_info
run: |

View File

@ -1,76 +0,0 @@
pkgname=picodulce
pkgver=0.11.7
pkgrel=1
pkgdesc="Launcher for Minecraft based on the picomc library"
arch=('x86_64')
OPTIONS=(!strip !docs libtool emptydirs)
url="https://github.com/nixietab/picodulce"
license=('MIT') # Replace with your project's license
depends=('python' 'python-virtualenv' 'xdg-utils')
makedepends=('git')
source=("git+https://github.com/nixietab/picodulce.git")
sha256sums=('SKIP')
package() {
cd "$srcdir/$pkgname"
# Create a directory for the application in the user's home directory
install -dm755 "$pkgdir/usr/share/$pkgname"
# Copy all project files to the created directory
cp -r . "$pkgdir/usr/share/$pkgname"
# Create a virtual environment
python -m venv "$pkgdir/usr/share/$pkgname/venv"
# Activate the virtual environment and install dependencies
source "$pkgdir/usr/share/$pkgname/venv/bin/activate"
pip install -r requirements.txt
# Create a run.sh script
install -Dm755 /dev/stdin "$pkgdir/usr/share/$pkgname/run.sh" <<EOF
#!/bin/bash
if [ ! -d "venv" ]; then
echo "venv folder does not exist. Creating virtual environment..."
python3 -m venv venv
source venv/bin/activate
echo "Installing required packages..."
pip install -r requirements.txt
else
source venv/bin/activate
fi
python picodulce.py
EOF
# Make the run.sh script executable
chmod +x "$pkgdir/usr/share/$pkgname/run.sh"
# Create a desktop entry for the application
install -Dm644 /dev/stdin "$pkgdir/usr/share/applications/$pkgname.desktop" <<EOF
[Desktop Entry]
Name=Picodulce
Exec=/usr/share/picodulce/run.sh
Icon=/usr/share/picodulce/launcher_icon.ico
Terminal=true
Type=Application
Comment=Picodulce Launcher
Categories=Game;
EOF
# Ensure the normal user has permission to write to the picodulce folder
chown -R "$USER:$USER" "$pkgdir/usr/share/$pkgname"
chmod -R u+w "$pkgdir/usr/share/$pkgname"
#Install into bin
install -Dm755 /dev/stdin "$pkgdir/usr/bin/picodulce" <<EOF
#!/bin/bash
cd /usr/share/picodulce/
exec ./run.sh
EOF
}
# vim:set ts=2 sw=2 et:

View File

@ -38,23 +38,9 @@
- **Offline and Online Support**: Whether you're connected to Microsoft or not, Picodulce ensures you can still enjoy your game by supporting both offline and online modes.
- **Integrated Mod Manager**: Includes the [Marroc Mod Manager](https://github.com/nixietab/marroc), enabling users to effortlessly manage and customize their game with mods and texturepacks.
- **Custom Theme Support**: Create and apply personalized themes with ease. A dedicated repository and guide are [available to help you get started.](https://github.com/nixietab/picodulce-themes)
-- **Instance Support**: Allows users to create and manage multiple game instances, each with its own configuration, mods, and settings
# Installation
## Windows
For Windows systems using the [installer](https://github.com/nixietab/picodulce/releases/latest) is recommended
## Arch Linux
The package is available in the [AUR](https://aur.archlinux.org/packages/picodulce) as ```picodulce```
For installing on Arch without using an AUR helper a PKGBUILD is provided
```
git clone https://aur.archlinux.org/picodulce.git
cd picodulce
makepkg -si
```
## Other OS
If you are on windows you may be more interested in a [installer](https://github.com/nixietab/2hsu/releases/download/release/2hsu.exe)
### 1. Clone the repository

View File

@ -1,239 +0,0 @@
import sys
import re
import colorama
import requests
from PyQt5.QtWidgets import (QApplication, QDialog, QLabel, QVBoxLayout,
QPushButton, QLineEdit, QMessageBox)
from PyQt5.QtCore import QThread, pyqtSignal, Qt, QUrl, QObject, QTimer
from PyQt5.QtGui import QDesktopServices
from picomc.logging import logger
# Constants
URL_DEVICE_AUTH = "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode"
URL_TOKEN = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"
CLIENT_ID = "c52aed44-3b4d-4215-99c5-824033d2bc0f"
SCOPE = "XboxLive.signin offline_access"
GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code"
class AuthDialog(QDialog):
def __init__(self, url, code, parent=None, error_mode=False):
super().__init__(parent)
self.setWindowTitle("Microsoft Authentication")
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
self.setModal(True)
self.setup_ui(url, code, error_mode)
def setup_ui(self, url, code, error_mode):
layout = QVBoxLayout(self)
if error_mode:
error_label = QLabel("Error in Login - Please try again")
error_label.setStyleSheet("QLabel { color: red; font-weight: bold; }")
layout.addWidget(error_label)
instructions = QLabel(
"To authenticate your Microsoft Account:\n\n"
"1. Click 'Open Authentication Page' or visit:\n"
"2. Copy the code below\n"
"3. Paste the code on the Microsoft website\n"
"4. After completing authentication, click 'I've Completed Authentication'"
)
instructions.setWordWrap(True)
layout.addWidget(instructions)
url_label = QLabel(url)
url_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
url_label.setWordWrap(True)
layout.addWidget(url_label)
self.code_input = QLineEdit(code)
self.code_input.setReadOnly(True)
self.code_input.setAlignment(Qt.AlignCenter)
self.code_input.setStyleSheet("""
QLineEdit {
font-size: 16pt;
font-weight: bold;
padding: 5px;
}
""")
layout.addWidget(self.code_input)
copy_button = QPushButton("Copy Code")
copy_button.clicked.connect(self.copy_code)
layout.addWidget(copy_button)
open_url_button = QPushButton("Open Authentication Page")
open_url_button.clicked.connect(lambda: self.open_url(url))
layout.addWidget(open_url_button)
continue_button = QPushButton("I've Completed Authentication")
continue_button.clicked.connect(self.accept)
layout.addWidget(continue_button)
def copy_code(self):
clipboard = QApplication.clipboard()
clipboard.setText(self.code_input.text())
def open_url(self, url):
QDesktopServices.openUrl(QUrl(url))
class AuthenticationThread(QThread):
auth_data_received = pyqtSignal(dict)
error_occurred = pyqtSignal(str)
auth_error_detected = pyqtSignal(str)
finished = pyqtSignal()
access_token_received = pyqtSignal(str, str)
def __init__(self, account):
super().__init__()
self.account = account
self.device_code = None
self.is_running = True
def run(self):
try:
self.authenticate(self.account)
except Exception as e:
self.error_occurred.emit(str(e))
self.finished.emit()
def authenticate(self, account):
try:
data = {"client_id": CLIENT_ID, "scope": SCOPE}
# Request device code
resp = requests.post(URL_DEVICE_AUTH, data)
resp.raise_for_status()
j = resp.json()
self.device_code = j["device_code"]
user_code = j["user_code"]
link = j["verification_uri"]
# Format message with colorama
msg = j["message"]
msg = msg.replace(
user_code, colorama.Fore.RED + user_code + colorama.Fore.RESET
).replace(link, colorama.Style.BRIGHT + link + colorama.Style.NORMAL)
# Emit auth data received signal
self.auth_data_received.emit({'url': link, 'code': user_code})
except requests.exceptions.RequestException as e:
logger.error(f"Request failed: {e}")
self.error_occurred.emit(str(e))
self.finished.emit()
def poll_for_token(self):
try:
data = {"code": self.device_code, "grant_type": GRANT_TYPE, "client_id": CLIENT_ID}
resp = requests.post(URL_TOKEN, data)
if resp.status_code == 400:
j = resp.json()
logger.debug(j)
if j["error"] == "authorization_pending":
logger.warning(j["error_description"])
self.auth_error_detected.emit(j["error_description"])
return
else:
raise Exception(j["error_description"])
resp.raise_for_status()
j = resp.json()
access_token = j["access_token"]
refresh_token = j["refresh_token"]
logger.debug("OAuth device code flow successful")
self.access_token_received.emit(access_token, refresh_token)
self.finished.emit()
except requests.exceptions.RequestException as e:
logger.error(f"Request failed: {e}")
self.error_occurred.emit(str(e))
self.finished.emit()
def send_enter(self):
self.poll_for_token()
def stop(self):
self.is_running = False
class MinecraftAuthenticator(QObject):
auth_finished = pyqtSignal(bool)
def __init__(self, parent=None):
super().__init__(parent)
self.auth_thread = None
self.current_auth_data = None
self.auth_dialog = None
self.success = False
def authenticate(self, username):
self.success = False
self.auth_thread = AuthenticationThread(username)
self.auth_thread.auth_data_received.connect(self.show_auth_dialog)
self.auth_thread.auth_error_detected.connect(self.handle_auth_error)
self.auth_thread.error_occurred.connect(self.show_error)
self.auth_thread.access_token_received.connect(self.on_access_token_received)
self.auth_thread.finished.connect(self.on_authentication_finished)
self.auth_thread.start()
def show_auth_dialog(self, auth_data):
self.current_auth_data = auth_data
if self.auth_dialog is not None:
self.auth_dialog.close()
self.auth_dialog = None
self.auth_dialog = AuthDialog(auth_data['url'], auth_data['code'])
if self.auth_dialog.exec_() == QDialog.Accepted:
self.auth_thread.send_enter()
def handle_auth_error(self, output):
if self.current_auth_data:
if self.auth_dialog is not None:
self.auth_dialog.close()
self.auth_dialog = None
self.auth_dialog = AuthDialog(
self.current_auth_data['url'],
self.current_auth_data['code'],
error_mode=True
)
if self.auth_dialog.exec_() == QDialog.Accepted:
self.auth_thread.send_enter()
def show_error(self, error_message):
QMessageBox.critical(None, "Error", f"Authentication error: {error_message}")
self.success = False
self.auth_finished.emit(False)
def on_access_token_received(self, access_token, refresh_token):
QMessageBox.information(None, "Success", "Authentication successful!")
self.success = True
self.auth_finished.emit(True)
def on_authentication_finished(self):
if self.auth_dialog is not None:
self.auth_dialog.close()
self.auth_dialog = None
if self.auth_thread:
self.auth_thread.stop()
self.auth_thread = None
if not self.success:
self.auth_finished.emit(False)
def cleanup(self):
if self.auth_dialog is not None:
self.auth_dialog.close()
self.auth_dialog = None
if self.auth_thread and self.auth_thread.isRunning():
self.auth_thread.stop()
self.auth_thread.wait()
# Example usage
if __name__ == '__main__':
app = QApplication(sys.argv)
authenticator = MinecraftAuthenticator()
authenticator.authenticate("TestUser")
sys.exit(app.exec_())

View File

@ -1,119 +0,0 @@
import os
import json
import requests
class HealthCheck:
def __init__(self):
self.config = None
def check_config_file(self):
config_path = "config.json"
default_config = {
"IsRCPenabled": False,
"CheckUpdate": False,
"IsBleeding": False,
"LastPlayed": "",
"IsFirstLaunch": True,
"Instance": "default",
"Theme": "Dark.json",
"ThemeBackground": True,
"ThemeRepository": "https://raw.githubusercontent.com/nixietab/picodulce-themes/main/repo.json",
"Locale": "en"
}
# Step 1: Check if the file exists; if not, create it with default values
if not os.path.exists(config_path):
with open(config_path, "w") as config_file:
json.dump(default_config, config_file, indent=4)
self.config = default_config
return
# Step 2: Try loading the config file, handle invalid JSON
try:
with open(config_path, "r") as config_file:
self.config = json.load(config_file)
except (json.JSONDecodeError, ValueError):
# File is corrupted, overwrite it with default configuration
with open(config_path, "w") as config_file:
json.dump(default_config, config_file, indent=4)
self.config = default_config
return
# Step 3: Check for missing keys and add defaults if necessary
updated = False
for key, value in default_config.items():
if key not in self.config: # Field is missing
self.config[key] = value
updated = True
# Step 4: Save the repaired config back to the file
if updated:
with open(config_path, "w") as config_file:
json.dump(self.config, config_file, indent=4)
def themes_integrity(self):
# Define folder and file paths
themes_folder = "themes"
dark_theme_file = os.path.join(themes_folder, "Dark.json")
native_theme_file = os.path.join(themes_folder, "Native.json")
# Define the default content for Dark.json
dark_theme_content = {
"manifest": {
"name": "Dark",
"description": "The default picodulce launcher theme",
"author": "Nixietab",
"license": "MIT"
},
"palette": {
"Window": "#353535",
"WindowText": "#ffffff",
"Base": "#191919",
"AlternateBase": "#353535",
"ToolTipBase": "#ffffff",
"ToolTipText": "#ffffff",
"Text": "#ffffff",
"Button": "#353535",
"ButtonText": "#ffffff",
"BrightText": "#ff0000",
"Link": "#2a82da",
"Highlight": "#4bb679",
"HighlightedText": "#ffffff"
},
"background_image_base64": ""
}
# Define the default content for Native.json
native_theme_content = {
"manifest": {
"name": "Native",
"description": "The native looks of your OS",
"author": "Your Qt Style",
"license": "Any"
},
"palette": {}
}
# Step 1: Ensure the themes folder exists
if not os.path.exists(themes_folder):
print(f"Creating folder: {themes_folder}")
os.makedirs(themes_folder)
# Step 2: Ensure Dark.json exists
if not os.path.isfile(dark_theme_file):
print(f"Creating file: {dark_theme_file}")
with open(dark_theme_file, "w", encoding="utf-8") as file:
json.dump(dark_theme_content, file, indent=2)
print("Dark.json has been created successfully.")
# Step 3: Ensure Native.json exists
if not os.path.isfile(native_theme_file):
print(f"Creating file: {native_theme_file}")
with open(native_theme_file, "w", encoding="utf-8") as file:
json.dump(native_theme_content, file, indent=2)
print("Native.json has been created successfully.")
# Check if both files exist and print OK message
if os.path.isfile(dark_theme_file) and os.path.isfile(native_theme_file):
print("Theme Integrity OK")

View File

@ -1,30 +0,0 @@
import click
from picomc.cli.main import picomc_cli
from io import StringIO
import sys
def run_command(command="picomc"):
# Redirect stdout and stderr to capture the command output
old_stdout, old_stderr = sys.stdout, sys.stderr
sys.stdout = mystdout = StringIO()
sys.stderr = mystderr = StringIO()
try:
picomc_cli.main(args=command.split())
except SystemExit as e:
if e.code != 0:
print(f"Command exited with code {e.code}", file=sys.stderr)
except Exception as e:
print(f"Unexpected error: {e}", file=sys.stderr)
finally:
# Restore stdout and stderr
sys.stdout = old_stdout
sys.stderr = old_stderr
output = mystdout.getvalue().strip()
error = mystderr.getvalue().strip()
if not output:
return f"Error: No output from command. Stderr: {error}"
return output

File diff suppressed because it is too large Load Diff

View File

@ -2,4 +2,3 @@ picomc
PyQt5
requests
pypresence
tqdm

View File

@ -1,15 +1,12 @@
{
"version": "0.13",
"version": "0.11.99",
"name": "Lucky Bastard",
"links": [
"https://raw.githubusercontent.com/nixietab/picodulce/main/version.json",
"https://raw.githubusercontent.com/nixietab/picodulce/main/picodulce.py",
"https://raw.githubusercontent.com/nixietab/picodulce/main/requirements.txt",
"https://raw.githubusercontent.com/nixietab/picodulce/main/drums.gif",
"https://raw.githubusercontent.com/nixietab/picodulce/main/marroc.py",
"https://raw.githubusercontent.com/nixietab/picodulce/main/holiday.ico",
"https://raw.githubusercontent.com/nixietab/picodulce/main/authser.py",
"https://raw.githubusercontent.com/nixietab/picodulce/main/healthcheck.py",
"https://raw.githubusercontent.com/nixietab/picodulce/main/modulecli.py"
],
"versionBleeding": "0.13-194"
"https://raw.githubusercontent.com/nixietab/picodulce/canary/version.json",
"https://raw.githubusercontent.com/nixietab/picodulce/canary/picodulce.py",
"https://raw.githubusercontent.com/nixietab/picodulce/canary/requirements.txt",
"https://raw.githubusercontent.com/nixietab/picodulce/canary/drums.gif",
"https://raw.githubusercontent.com/nixietab/picodulce/canary/marroc.py",
"https://raw.githubusercontent.com/nixietab/picodulce/canary/holiday.ico"
]
}