Compare commits

...

175 Commits

Author SHA1 Message Date
github-actions[bot]
ba8072c669 Update version.json with commit count
Some checks failed
Bleeding Update version / update-version (push) Has been cancelled
Version Change Action / version-release (push) Has been cancelled
2025-03-03 04:12:50 +00:00
Nix
785e9be9f9
Update version.json 2025-03-03 01:12:37 -03:00
github-actions[bot]
0cbd000be4 Update version.json with commit count 2025-03-03 04:11:40 +00:00
Nixietab
52b635285e Moved the health checks to a OOP method 2025-03-03 01:10:53 -03:00
github-actions[bot]
67a16c008a Update version.json with commit count
Some checks failed
Bleeding Update version / update-version (push) Has been cancelled
Version Change Action / version-release (push) Has been cancelled
2025-03-01 08:34:21 +00:00
Nix
a4bd707461
Delete healtcheck.py 2025-03-01 05:34:12 -03:00
github-actions[bot]
1b27fffc96 Update version.json with commit count 2025-03-01 08:34:00 +00:00
Nix
fade5f86b7
Update picodulce.py 2025-03-01 05:33:51 -03:00
github-actions[bot]
823b438840 Update version.json with commit count 2025-03-01 08:33:36 +00:00
Nix
9a8c3f44d0
Update version.json 2025-03-01 05:33:25 -03:00
github-actions[bot]
6b65fb0d1e Update version.json with commit count 2025-03-01 08:33:18 +00:00
Nix
8247009d60
Delete locales directory 2025-03-01 05:33:07 -03:00
github-actions[bot]
e5c395d031 Update version.json with commit count 2025-03-01 08:06:58 +00:00
Nix
263e6eae07
Added rudimentary translations (#11)
* Update picodulce.py

* Update picodulce.py

* Update picodulce.py

* Update picodulce.py

* Create healtcheck.py

* Update picodulce.py

* Update version.json

* Create locales-go-here

* Add files via upload

* Update version.json

* Update picodulce.py

* Update healtcheck.py

* Update picodulce.py

* Added more locales

* Update version.json

* Update picodulce.py
2025-03-01 05:06:48 -03:00
github-actions[bot]
ec99488326 Update version.json with commit count
Some checks failed
Bleeding Update version / update-version (push) Has been cancelled
Version Change Action / version-release (push) Has been cancelled
2025-02-23 04:26:44 +00:00
Nix
61cd427beb
Delete locales directory 2025-02-23 01:26:35 -03:00
github-actions[bot]
cb2f5b52b3 Update version.json with commit count 2025-02-23 04:26:29 +00:00
Nix
ba40354a5d
Create bogosbinted.json 2025-02-23 01:26:19 -03:00
github-actions[bot]
0c151b058e Update version.json with commit count
Some checks failed
Bleeding Update version / update-version (push) Has been cancelled
Version Change Action / version-release (push) Has been cancelled
2025-02-12 19:13:11 +00:00
Nix
fc7f47d273
put the loading theme background in a separate function 2025-02-12 16:12:59 -03:00
github-actions[bot]
4f4ff35ee5 Update version.json with commit count
Some checks failed
Bleeding Update version / update-version (push) Has been cancelled
Version Change Action / version-release (push) Has been cancelled
2025-02-11 11:52:38 +00:00
Nix
8b9827b422
Update version.json 2025-02-11 08:52:27 -03:00
github-actions[bot]
892cbc4d07 Update version.json with commit count 2025-02-11 11:51:51 +00:00
Nix
f61f15fe7e
Update version.json 2025-02-11 08:51:39 -03:00
github-actions[bot]
d077a922c0 Update version.json with commit count 2025-02-11 11:50:38 +00:00
Nix
9b70503d26
auth done right 2025-02-11 08:50:27 -03:00
github-actions[bot]
ae9f25a7a8 Update version.json with commit count 2025-02-11 11:49:55 +00:00
Nix
00ed5f97b9
authentication done right 2025-02-11 08:49:44 -03:00
github-actions[bot]
5dbbfd5d87 Update version.json with commit count 2025-02-11 05:45:27 +00:00
Nix
37a1c5b0df
Update version.json 2025-02-11 02:45:16 -03:00
github-actions[bot]
f2a1989993 Update version.json with commit count 2025-02-11 05:38:13 +00:00
Nix
3d40ce7df3
fixxed the need of re-opening the settings menu to refresh the themes list 2025-02-11 02:38:02 -03:00
github-actions[bot]
36ff8896ef Update version.json with commit count
Some checks failed
Bleeding Update version / update-version (push) Has been cancelled
Version Change Action / version-release (push) Has been cancelled
2025-02-04 16:42:58 +00:00
Nix
5f59acf0b4
Merge pull request #10 from refrigerador67/main
Removed popup when checking for updates on startup when in latest version
2025-02-04 13:42:46 -03:00
github-actions[bot]
c48a193d9a Update version.json with commit count 2025-02-04 16:39:08 +00:00
refrigerador67
47a843c669
Removed popup at latest version when checking updates at startup 2025-02-04 13:38:57 -03:00
github-actions[bot]
52be28bb6c Update version.json with commit count 2025-02-04 16:30:53 +00:00
github-actions[bot]
6522b70066 Update version.json with commit count
Some checks failed
Bleeding Update version / update-version (push) Has been cancelled
Version Change Action / version-release (push) Has been cancelled
2025-01-29 02:03:17 +00:00
Nix
8d486a9af2
Update version.json 2025-01-28 23:03:07 -03:00
github-actions[bot]
97393e4ae7 Update version.json with commit count 2025-01-29 02:02:18 +00:00
Nix
e35120bb36
fixxed bleeding edge 2025-01-28 23:02:07 -03:00
github-actions[bot]
f2cfb3ceb3 Update version.json with commit count 2025-01-29 01:47:18 +00:00
Nix
15246cd535
Create Bleeding-Job.yaml 2025-01-28 22:47:06 -03:00
Nix
3edcd10c12
Update Build.yml 2025-01-28 22:43:44 -03:00
Nix
874e513b47
Update requirements.txt 2025-01-21 10:05:08 -03:00
Nix
a10318e00d
Update picodulce.py 2025-01-20 15:11:04 -03:00
Nix
7608b647fe
minnor fix to the instance stuff
Some checks failed
Version Change Action / version-release (push) Has been cancelled
2025-01-14 02:22:32 -03:00
Nix
60d16326b0
Update picodulce.py 2025-01-14 02:21:55 -03:00
Nix
0d300f0435
Merge pull request #9 from refrigerador67/main
Update README.md
2025-01-14 01:56:33 -03:00
refrigerador67
3123ed30cf
Update README.md 2025-01-14 04:50:05 +00:00
Nix
db41858aae
Update picodulce.py 2025-01-14 01:07:50 -03:00
Nix
8c0a794202
Merge pull request #8 from refrigerador67/main
Added PKGBUILD
2025-01-14 00:29:43 -03:00
refrigerador67
514f6427ab
Update README.md 2025-01-14 03:25:54 +00:00
refrigerador67
9920636b9c
Merge branch 'nixietab:main' into main 2025-01-14 03:22:20 +00:00
refrigerador67
5182e42f81
Added PKGBUILD 2025-01-14 03:21:48 +00:00
Nix
d2f3aa6a49
Update version.json 2025-01-14 00:15:39 -03:00
Nix
8167462838
added animated themes support! 2025-01-13 20:19:25 -03:00
Nix
51dc126c8a
minnor fixes 2025-01-09 23:20:35 -03:00
Nix
5202f8fb25
Add files via upload 2025-01-08 22:36:18 -03:00
Nix
46d053d952
minor changes 2025-01-06 16:09:57 -03:00
Nix
82f44105b5
Update version.json
Some checks failed
Version Change Action / version-release (push) Has been cancelled
2025-01-06 06:40:03 -03:00
Nix
fd2e57ffb3
Update picodulce.py 2025-01-06 06:38:11 -03:00
Nix
372075132f
Update picodulce.py 2025-01-06 00:54:35 -03:00
Nix
9c66a3eeb8
theme previews 2025-01-05 06:49:40 -03:00
Nix
27c75d1ef2
Update version.json
Some checks failed
Version Change Action / version-release (push) Has been cancelled
2025-01-02 01:41:00 -03:00
Nix
18692c3abc
Update README.md 2025-01-02 01:40:45 -03:00
Nix
c4f662235e
Update picodulce.py 2025-01-02 01:29:09 -03:00
Nix
bf30a6ecd6
added a better instance GUI 2025-01-02 01:28:37 -03:00
Nix
f4b0b39090
Update version.json
Some checks are pending
Version Change Action / version-release (push) Waiting to run
2025-01-01 13:27:48 -03:00
Nix
e02ca8ab76
Added a rudimentary Instance manager 2025-01-01 13:27:15 -03:00
Nix
b55ac71db1
Update version.json
Some checks are pending
Version Change Action / version-release (push) Waiting to run
2024-12-31 15:38:48 -03:00
Nix
f4eac0f412
Create Build.yml 2024-12-31 15:38:24 -03:00
Nix
dbca6721be
Update version.json 2024-12-31 11:27:29 -03:00
Nix
b0ec76ebc3
Update version.json 2024-12-31 10:55:07 -03:00
Nix
0028de0d69
Update version.json 2024-12-31 10:51:46 -03:00
Nix
17f5f2a8d0
Update version.json 2024-12-31 10:50:11 -03:00
Nix
70f6b2b59c
Update README.md 2024-12-26 08:36:39 -03:00
Nix
b824c2c4fb
minor changes 2024-12-23 22:28:50 -03:00
Nix
b60b5179bc
Update picodulce.py 2024-12-23 22:22:15 -03:00
Nix
58e2b018d8
Update picodulce.py 2024-12-21 21:21:44 -03:00
Nix
3ee4348dfe
Update README.md 2024-12-21 21:15:35 -03:00
Nix
b7c099c0d9
Update version.json 2024-12-21 06:21:40 -03:00
Nix
17ccedfefc
added native theme compatibility and generation
also added some fallbacks
2024-12-21 06:21:28 -03:00
Nix
afac01f3dc
Update version.json 2024-12-20 09:52:18 -03:00
Nix
fd4c23ed3b
added stylesheet support 2024-12-20 09:43:15 -03:00
refrigerador67
a19b8a1545
Minor UI changes 2024-12-18 23:11:00 -03:00
Nix
152b7d82dc
Merge pull request #6 from refrigerador67/patch-1
Update README.md
2024-12-18 22:50:30 -03:00
refrigerador67
566d3fc321
Update README.md 2024-12-18 22:42:43 -03:00
Nix
163d116005
Update version.json 2024-12-18 22:40:08 -03:00
Nix
fc6b45a394
Added full custom theme support
commit 100! yay!
2024-12-18 22:39:55 -03:00
Nix
33d85e4cb2
Update picodulce.py 2024-12-14 22:24:17 -03:00
Nix
06ddb8936a
Update version.json 2024-12-14 22:21:44 -03:00
Nix
36ef0c58ae
even better discord rp 2024-12-14 22:21:30 -03:00
Nix
d0109bb96f
Update picodulce.py 2024-12-14 20:44:54 -03:00
Nix
6226f33de8
Update version.json 2024-12-14 20:15:53 -03:00
Nix
15b1567d3e
better discord rpc 2024-12-14 20:15:30 -03:00
Nix
dc81d4285d
Update picodulce.py 2024-12-10 17:00:35 -03:00
Nix
87fc6e9842
Update version.json 2024-12-10 15:48:04 -03:00
Nix
c59516fc60
keyboard support added 2024-12-10 15:47:38 -03:00
Nix
83d59a6600
keyboard support added 2024-12-10 15:47:25 -03:00
Nix
1e03c986fd
Update version.json 2024-12-09 14:34:12 -03:00
Nix
0ebf31f223
Update picodulce.py 2024-12-09 14:33:44 -03:00
Nix
88cbd449ef
removed nested IF 2024-12-09 14:21:33 -03:00
Nix
5eda9f1de4
Update version.json 2024-12-06 20:24:20 -03:00
Nix
5d586e4b5a
a closer step to fixing the account menu! 2024-12-06 20:23:57 -03:00
Nix
0ea29235cb
changed christmas date to 8 2024-12-04 16:30:22 -03:00
Nix
8ba2aa74a3
Update README.md 2024-12-04 16:27:15 -03:00
Nix
566095978d
Update version.json 2024-11-08 21:31:12 -03:00
Nix
34df942953
fix marroc 2024-11-08 21:30:59 -03:00
Nix
d477e98bd9
Update picodulce.py 2024-10-29 00:28:18 -03:00
Nix
45883d4483
Update version.json 2024-10-28 15:40:50 -03:00
Nix
4ed3d49f6e
Merge pull request #5 from SirOlinad/main
Holiday.Ico update
2024-10-28 15:21:54 -03:00
SirOlinad
4536ca526a
Add files via upload
Holiday Icon for Picodulce!!!!
2024-10-28 15:15:38 -03:00
Nix
c1ecbbc97a
this will be replaced next commit 2024-10-28 14:49:41 -03:00
Nix
7a383875c6
Holiday!!! 2024-10-28 14:48:48 -03:00
Nix
857d0296d4
Update version.json 2024-08-25 00:53:54 -03:00
Nix
ea252215f1
fixed again the same thing 2024-08-25 00:50:15 -03:00
Nix
7917dd0a7b
Update version.json 2024-08-24 23:21:46 -03:00
Nix
593a4566eb
fixed the last version not saving on config file by dumb issue 2024-08-24 23:20:11 -03:00
Nix
6a57a70321
Update version.json 2024-08-13 09:26:55 -03:00
Nix
811caa09ab
added a button in settings to open game directory 2024-08-13 09:25:33 -03:00
Nix
d3ae7302bd
fixed the LastPlayed version not showing 2024-08-13 09:16:19 -03:00
Nix
5e80a215e1
fixed autism 2024-07-05 08:54:19 -03:00
Nix
7a12ac3075
fix the account creation 2024-07-05 08:53:42 -03:00
Nix
2f6858a0c1
Update LICENSE 2024-07-03 14:04:08 -03:00
Nix
7a8aee2681
Update README.md 2024-06-17 21:31:38 -03:00
Nix
9949a9e122
lazy load pypresence 2024-06-12 14:10:14 -03:00
Nix
b817b18331
autism 2024-06-04 20:11:17 -03:00
Nix
b56efa6b1f
Add files via upload 2024-05-29 09:21:31 -03:00
Nix
7793c1876f
Add files via upload 2024-05-29 05:08:04 -03:00
Nix
dbb7d224a2
Update README.md 2024-05-26 00:10:00 -03:00
Nix
293af5b213
Update README.md 2024-05-26 00:07:25 -03:00
Nix
0e6730147d
Update version.json 2024-05-23 21:38:57 -03:00
Nix
9446d6e404
Update picodulce.py 2024-05-23 21:37:19 -03:00
Nix
5709e849d3
Add files via upload 2024-05-15 21:55:51 -03:00
Nix
a047b0142d
added native theme 2024-05-14 23:14:06 -03:00
Nix
70777858f4
Update requirements.txt 2024-05-13 19:44:20 -03:00
Nix
ebc59e4c3e
Update version.json 2024-05-10 16:19:47 -03:00
Nix
ca8f546ac0
Add files via upload 2024-05-10 16:19:32 -03:00
Nix
413839ddbd
Update version.json 2024-05-10 00:14:20 -03:00
Nix
021f31970f
added theme support 2024-05-10 00:14:01 -03:00
Nix
60ef1694b9
Add files via upload 2024-05-09 23:26:33 -03:00
Nix
a1a8667d79
upgraded the gui 2024-05-09 18:57:30 -03:00
Nix
521e61a112
Add files via upload 2024-05-07 00:45:31 -03:00
Nix
4c608d6ab0
fixed bugs 2024-05-07 00:19:07 -03:00
Nix
bb957f07e3
added cool things
added a settings menu, with the option to check updates on start and enable or disable discord RCP
also added discord rcp
2024-05-06 23:29:24 -03:00
Nix
73bb0252f4
Add files via upload 2024-05-06 00:34:28 -03:00
Nix
fbab52db5c
Add files via upload 2024-05-06 00:33:24 -03:00
Nix
154a1dfbad
Add files via upload 2024-05-06 00:32:08 -03:00
Nix
848622a16d
Update version.json 2024-05-06 00:27:27 -03:00
Nix
9c43145e1a
Update version.json 2024-05-06 00:13:58 -03:00
Nix
372733a031
Add files via upload 2024-05-06 00:09:08 -03:00
Nix
9ebec6fb19
added update button 2024-05-06 00:04:59 -03:00
Nix
885913fce7
Update version.json 2024-05-06 00:01:38 -03:00
Nix
cbaaaa1460
Update version.json 2024-05-05 23:58:59 -03:00
Nix
5e0a191555
Update version.json 2024-05-05 23:54:03 -03:00
Nix
d7058326c5
Create version.json 2024-05-05 23:38:36 -03:00
Nix
99c7b42f3c
Delete version 2024-05-05 23:38:08 -03:00
Nix
7ef5dc69c1
Update version 2024-05-05 23:33:00 -03:00
Nix
0a9b9c2966
Create version 2024-05-05 23:24:03 -03:00
Nix
d9b3b976d7
added the auth function 2024-05-03 20:00:28 -03:00
Nix
d7d6b3de4a
Add files via upload 2024-04-25 11:30:33 -03:00
Nix
61f5e3f8dd
Update README.md 2024-04-25 08:44:44 -03:00
Nix
3523325449
Add files via upload 2024-04-25 08:41:49 -03:00
Nix
942daa79ad
fixed things 2024-04-23 21:59:34 -03:00
Nix
ce93c8522e
added the marroc mod manager 2024-04-23 06:43:26 -03:00
Nix
25e1ea4fcf
Add files via upload 2024-04-19 20:59:35 -03:00
Nix
22cbc6915e
Update picodulce.py 2024-04-17 18:53:16 -03:00
Nix
d8e28348be
Update README.md 2024-04-17 18:10:29 -03:00
Nix
65cf81ac4e
added mod loader selection
added remove account button
2024-04-17 17:57:58 -03:00
Nix
fd9dc69096
Delete LICENSE.GPL 2024-04-16 18:59:38 -03:00
Nix
fab4432969
Create LICENSE 2024-04-16 18:59:07 -03:00
Nix
dbc007e951
Update picodulce.py 2024-04-15 23:56:31 -03:00
Nix
b0062b8075
Update README.md 2024-04-15 22:34:34 -03:00
Nix
7696bdff33
Update README.md 2024-04-15 21:21:07 -03:00
16 changed files with 2707 additions and 162 deletions

36
.github/workflows/Bleeding-Job.yaml vendored Normal file
View File

@ -0,0 +1,36 @@
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 }}

69
.github/workflows/Build.yml vendored Normal file
View File

@ -0,0 +1,69 @@
name: Version Change Action
on:
push:
paths:
- version.json # Trigger on changes to version.json
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
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x' # Specify the Python version you need
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pyqt5 requests pywin32 pyinstaller pillow # Install specific dependencies
- name: Create actions-temp folder
run: mkdir actions-temp # Create the folder called actions-temp
- name: Download picoBuild.py script
run: curl -L -o actions-temp/picoBuild.py https://raw.githubusercontent.com/nixietab/picodulce-build-script/refs/heads/main/picoBuild.py
- name: Run picoBuild.py script
run: python actions-temp/picoBuild.py
- name: Show directory structure
run: |
dir actions-temp
dir
- name: Get version and name from version.json
id: version_info
run: |
$versionJson = Get-Content version.json | ConvertFrom-Json
echo "RELEASE_NAME=Release $($versionJson.version)" >> $env:GITHUB_ENV
echo "RELEASE_TAG=$($versionJson.version)" >> $env:GITHUB_ENV
- name: Create GitHub Release
id: create_release
uses: actions/create-release@v1
with:
tag_name: ${{ env.RELEASE_TAG }}
release_name: ${{ env.RELEASE_NAME }}
body: "This release was created automatically by a GitHub Action."
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: build/2hsu.exe
asset_name: 2hsu.exe
asset_content_type: application/octet-stream
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

76
PKGBUILD Normal file
View File

@ -0,0 +1,76 @@
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

@ -1,12 +1,92 @@
<p align="center">
<img src="https://github.com/nixietab/picodulce/assets/75538775/36fee78f-fb46-400c-8b14-dda5ec6191ef" alt="launcher_icon">
# picodulce
</p>
a launcher for block game made in Qt5 and a GUI for the picomc project.
<h1 align="center">Picodulce Launcher</h1>
it should download all the versions and start them as well. it works offline and online
<p align="center">The simple FOSS launcher you been looking for</p>
![a capture of the launcher](https://i.imgur.com/Ui92vta.png)
<p align="center">
<a href="https://github.com/nixietab/picodulce/releases">
<img src="https://img.shields.io/github/v/release/nixietab/picodulce" alt="Latest Release">
</a>
<a href="https://github.com/nixietab/picodulce/issues">
<img src="https://img.shields.io/github/issues/nixietab/picodulce" alt="Issues">
</a>
<a href="https://github.com/nixietab/picodulce/pulls">
<img src="https://img.shields.io/github/issues-pr/nixietab/picodulce" alt="Pull Requests">
</a>
<a href="https://github.com/nixietab/picodulce/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/nixietab/picodulce" alt="License">
</a>
<a href="https://github.com/nixietab/picodulce">
<img src="https://img.shields.io/github/stars/nixietab/picodulce?style=social" alt="GitHub Stars">
</a>
</p>
Picodulce is a feature-rich launcher for Minecraft, developed using Qt5. It serves as a graphical user interface (GUI) for the picomc project, providing users with a seamless experience in managing and launching game versions.
![imagen](https://github.com/user-attachments/assets/115b39be-47d3-4ac7-893a-5849c1e4570c)
## Key Features
- **Version Management**: Picodulce is designed to download and launch all available game versions, ensuring users have easy access to the latest updates as well as older versions.
- **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)
# 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
### 1. Clone the repository
``` git clone https://github.com/nixietab/picodulce ```
### 2. (Optional) Set Up a Virtual Environment
Setting up a virtual environment is recommended to avoid dependency conflicts. Picodulce relies on the path of the `picomc` project, and using a virtual environment helps prevent errors.
Create the virtual environment:
``` python -m venv venv ```
- **Linux/Mac:**
`source venv/bin/activate`
- **Windows:**
`.\\venv\\Scripts\\activate`
### Install requirements
Now on the venv you can install the requirements safely
```pip install -r requirements.txt ```
### Running the launcher
On the venv run it as a normal python script
```python picodulce.py```
Just make sure you have Java installed for running the actual game
### About the name
pico dulce is the name of a well known argentinean candy and i think is apropiate say that this is a really "sweetened" way of using picomc
The name "Picodulce" comes from a popular Argentinian candy. This reflects the enjoyable and user-friendly experience that the launcher aims to provide, making game management straightforward and pleasant.

244
authser.py Normal file
View File

@ -0,0 +1,244 @@
import sys
import subprocess
import re
from PyQt5.QtWidgets import (QApplication, QDialog, QLabel, QVBoxLayout,
QPushButton, QLineEdit, QMessageBox)
from PyQt5.QtCore import QThread, pyqtSignal, Qt, QUrl, QObject
from PyQt5.QtGui import QDesktopServices
class AuthenticationParser:
@staticmethod
def clean_ansi(text):
ansi_clean = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
printable_clean = re.compile(r'[^\x20-\x7E\n]')
text = ansi_clean.sub('', text)
text = printable_clean.sub('', text)
return text.strip()
@staticmethod
def is_auth_error(output):
cleaned_output = AuthenticationParser.clean_ansi(output)
return "AADSTS70016" in cleaned_output and "not yet been authorized" in cleaned_output
@staticmethod
def parse_auth_output(output):
cleaned_output = AuthenticationParser.clean_ansi(output)
if AuthenticationParser.is_auth_error(cleaned_output):
return None
pattern = r"https://[^\s]+"
code_pattern = r"code\s+([A-Z0-9]+)"
url_match = re.search(pattern, cleaned_output)
code_match = re.search(code_pattern, cleaned_output, re.IGNORECASE)
if url_match and code_match:
return {
'url': url_match.group(0),
'code': code_match.group(1)
}
return None
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()
def __init__(self, account):
super().__init__()
self.account = account
self.process = None
self.is_running = True
self.current_output = ""
self.waiting_for_auth = False
def run(self):
try:
command = f'picomc account authenticate {self.account}'
self.process = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdin=subprocess.PIPE,
text=True,
bufsize=1,
universal_newlines=True
)
self.current_output = ""
while self.is_running and self.process.poll() is None:
line = self.process.stdout.readline()
if line:
self.current_output += line
if not self.waiting_for_auth:
parsed_data = AuthenticationParser.parse_auth_output(self.current_output)
if parsed_data:
self.auth_data_received.emit(parsed_data)
self.waiting_for_auth = True
self.current_output = ""
elif AuthenticationParser.is_auth_error(self.current_output):
self.auth_error_detected.emit(self.current_output)
self.waiting_for_auth = False
self.current_output = ""
self.process.wait()
self.finished.emit()
except Exception as e:
self.error_occurred.emit(str(e))
self.finished.emit()
def send_enter(self):
if self.process and self.process.poll() is None:
self.process.stdin.write("\n")
self.process.stdin.flush()
def stop(self):
self.is_running = False
if self.process:
self.process.terminate()
class MinecraftAuthenticator(QObject): # Changed to inherit from QObject
auth_finished = pyqtSignal(bool) # Add signal for completion
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):
"""
Start the authentication process for the given username
Returns immediately, authentication result will be emitted via auth_finished signal
"""
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.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_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
self.success = True
self.auth_finished.emit(True)
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__':
authenticator = MinecraftAuthenticator()
authenticator.authenticate("TestUser")

BIN
drums.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

119
healthcheck.py Normal file
View File

@ -0,0 +1,119 @@
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")

BIN
holiday.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
marroc.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

416
marroc.py Normal file
View File

@ -0,0 +1,416 @@
import sys
import os
import shutil
import json
import threading
import requests
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QListWidget, QListWidgetItem, QMessageBox, QComboBox, QDialog, QTabWidget, QMainWindow, QSpacerItem, QSizePolicy
from PyQt5.QtCore import Qt, QSize, QObject, pyqtSignal
from PyQt5.QtGui import QIcon, QPalette, QColor, QPixmap
CONFIG_FILE = "config.json"
class IconLoader(QObject, threading.Thread):
icon_loaded = pyqtSignal(QPixmap)
def __init__(self, icon_url):
super().__init__()
threading.Thread.__init__(self)
self.icon_url = icon_url
def run(self):
try:
response = requests.get(self.icon_url)
if response.status_code == 200:
pixmap = QPixmap()
pixmap.loadFromData(response.content)
self.icon_loaded.emit(pixmap.scaled(QSize(42, 42), Qt.KeepAspectRatio, Qt.SmoothTransformation))
else:
self.icon_loaded.emit(QPixmap("missing.png"))
except Exception as e:
print("Error loading icon:", e)
self.icon_loaded.emit(QPixmap("missing.png"))
class ModrinthSearchApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Marroc Mod Manager")
self.setGeometry(100, 100, 500, 400)
self.ensure_directories_exist()
layout = QVBoxLayout()
tab_widget = QTabWidget()
self.search_tab = QWidget()
self.mods_tab = QWidget()
tab_widget.addTab(self.search_tab, "Search")
tab_widget.addTab(self.mods_tab, "Manager")
self.init_search_tab()
self.init_mods_tab()
layout.addWidget(tab_widget)
self.setLayout(layout)
def keyPressEvent(self, event):
focus_widget = self.focusWidget()
if event.key() == Qt.Key_Down:
self.focusNextChild() # Move focus to the next widget
elif event.key() == Qt.Key_Up:
self.focusPreviousChild() # Move focus to the previous widget
elif event.key() in [Qt.Key_Return, Qt.Key_Enter]:
if isinstance(focus_widget, QPushButton):
focus_widget.click() # Trigger the button click
elif isinstance(focus_widget, QComboBox):
focus_widget.showPopup() # Show dropdown for combo box
else:
super().keyPressEvent(event)
def ensure_directories_exist(self):
directories = ["marroc/mods", "marroc/resourcepacks"]
for directory in directories:
if not os.path.exists(directory):
os.makedirs(directory)
def init_search_tab(self):
layout = QVBoxLayout()
search_layout = QHBoxLayout()
self.search_input = QLineEdit()
self.search_input.setPlaceholderText("Enter a search term...")
search_layout.addWidget(self.search_input)
self.search_button = QPushButton("Search")
self.search_button.clicked.connect(self.search_mods)
search_layout.addWidget(self.search_button)
self.search_type_dropdown = QComboBox()
self.search_type_dropdown.addItems(["Mod", "Texture Pack"])
search_layout.addWidget(self.search_type_dropdown)
layout.addLayout(search_layout)
self.mods_list = QListWidget()
layout.addWidget(self.mods_list)
self.select_button = QPushButton("Select")
self.select_button.clicked.connect(self.show_mod_details_window)
layout.addWidget(self.select_button)
self.selected_mod = None
self.search_tab.setLayout(layout)
def init_mods_tab(self):
layout = QVBoxLayout()
self.mod_manager_window = ModManagerWindow()
layout.addWidget(self.mod_manager_window)
self.mods_tab.setLayout(layout)
def search_mods(self):
self.mods_list.clear()
mod_name = self.search_input.text()
search_type = self.search_type_dropdown.currentText().lower()
if search_type == "texture pack":
api_url = f"https://api.modrinth.com/v2/search?query={mod_name}&limit=20&facets=%5B%5B%22project_type%3Aresourcepack%22%5D%5D"
else:
api_url = f"https://api.modrinth.com/v2/search?query={mod_name}&limit=20&facets=%5B%5B%22project_type%3A{search_type}%22%5D%5D"
response = requests.get(api_url)
if response.status_code == 200:
mods_data = json.loads(response.text)
for mod in mods_data['hits']:
mod_name = mod['title']
mod_description = mod['description']
icon_url = mod['icon_url']
item = QListWidgetItem(f"Title: {mod_name}\nDescription: {mod_description}")
item.setSizeHint(QSize(200, 50))
icon_loader = IconLoader(icon_url)
icon_loader.icon_loaded.connect(lambda pixmap, item=item: self.set_item_icon(item, pixmap))
icon_loader.start()
item.mod_data = mod
self.mods_list.addItem(item)
else:
self.mods_list.addItem("Failed to fetch mods. Please try again later.")
def set_item_icon(self, item, pixmap):
if pixmap:
item.setData(Qt.DecorationRole, pixmap)
else:
# Set a default icon if loading failed
item.setIcon(QIcon("missing.png"))
def show_mod_details_window(self):
selected_item = self.mods_list.currentItem()
if selected_item is not None:
mod_data = selected_item.mod_data
mod_slug = mod_data.get('slug')
if mod_slug:
api_url = f"https://api.modrinth.com/v2/project/{mod_slug}"
response = requests.get(api_url)
if response.status_code == 200:
mod_info = json.loads(response.text)
icon_url = mod_info.get('icon_url')
mod_versions = self.get_mod_versions(mod_slug)
mod_details_window = ModDetailsWindow(mod_data, icon_url, mod_versions)
mod_details_window.exec_()
else:
QMessageBox.warning(self, "Failed to Fetch Mod Details", "Failed to fetch mod details. Please try again later.")
else:
QMessageBox.warning(self, "No Mod Slug", "Selected mod has no slug.")
else:
QMessageBox.warning(self, "No Mod Selected", "Please select a mod first.")
def get_mod_versions(self, mod_slug):
api_url = f"https://api.modrinth.com/v2/project/{mod_slug}/version"
response = requests.get(api_url)
if response.status_code == 200:
versions = json.loads(response.text)
mod_versions = []
for version in versions:
version_name = version['name']
version_files = version.get('files', [])
if version_files:
file_urls = [file['url'] for file in version_files]
mod_versions.append({'version': version_name, 'files': file_urls})
else:
mod_versions.append({'version': version_name, 'files': []})
return mod_versions
else:
return []
class ModManagerWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Mod Manager")
self.setGeometry(100, 100, 600, 400)
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QHBoxLayout(self.central_widget)
self.file_type_combo_box = QComboBox()
self.file_type_combo_box.addItems(["Mods", "Resource Packs"])
self.file_type_combo_box.currentIndexChanged.connect(self.load_files)
self.available_files_widget = QListWidget()
self.installed_files_widget = QListWidget()
self.button_dropdown_layout = QVBoxLayout()
self.button_dropdown_layout.addWidget(self.file_type_combo_box)
self.button_dropdown_layout.addSpacerItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))
self.move_right_button = QPushButton(">")
self.move_right_button.clicked.connect(self.move_right)
self.button_dropdown_layout.addWidget(self.move_right_button)
self.move_left_button = QPushButton("<")
self.move_left_button.clicked.connect(self.move_left)
self.button_dropdown_layout.addWidget(self.move_left_button)
self.delete_button = QPushButton("Delete")
self.delete_button.clicked.connect(self.delete_selected_item)
self.button_dropdown_layout.addWidget(self.delete_button)
self.button_dropdown_layout.addSpacerItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))
self.layout.addWidget(self.available_files_widget)
self.layout.addLayout(self.button_dropdown_layout)
self.layout.addWidget(self.installed_files_widget)
self.load_files()
def load_files(self):
file_type = self.file_type_combo_box.currentText()
if file_type == "Mods":
self.load_mods()
elif file_type == "Resource Packs":
self.load_resource_packs()
def load_mods(self):
mods_directory = "marroc/mods"
if os.path.exists(mods_directory) and os.path.isdir(mods_directory):
mods = os.listdir(mods_directory)
self.available_files_widget.clear()
self.available_files_widget.addItems(mods)
self.load_installed_mods("mods")
def load_resource_packs(self):
resource_packs_directory = "marroc/resourcepacks"
if os.path.exists(resource_packs_directory) and os.path.isdir(resource_packs_directory):
resource_packs = os.listdir(resource_packs_directory)
self.available_files_widget.clear()
self.available_files_widget.addItems(resource_packs)
self.load_installed_mods("resourcepacks")
def load_installed_mods(self, file_type):
if sys.platform.startswith('linux'):
minecraft_directory = os.path.expanduser("~/.local/share/picomc/instances/default/minecraft")
elif sys.platform.startswith('win'):
minecraft_directory = os.path.join(os.getenv('APPDATA'), '.picomc/instances/default/minecraft')
else:
minecraft_directory = ""
if minecraft_directory:
installed_files_directory = os.path.join(minecraft_directory, file_type)
if os.path.exists(installed_files_directory) and os.path.isdir(installed_files_directory):
installed_files = os.listdir(installed_files_directory)
self.installed_files_widget.clear()
self.installed_files_widget.addItems(installed_files)
def move_right(self):
selected_item = self.available_files_widget.currentItem()
if selected_item:
source_directory = self.get_source_directory()
destination_directory = self.get_destination_directory()
file_name = selected_item.text()
source_path = os.path.join(source_directory, file_name)
destination_path = os.path.join(destination_directory, file_name)
shutil.move(source_path, destination_path)
self.load_files()
def move_left(self):
selected_item = self.installed_files_widget.currentItem()
if selected_item:
source_directory = self.get_destination_directory()
destination_directory = self.get_source_directory()
file_name = selected_item.text()
source_path = os.path.join(source_directory, file_name)
destination_path = os.path.join(destination_directory, file_name)
shutil.move(source_path, destination_path)
self.load_files()
def delete_selected_item(self):
selected_item = self.available_files_widget.currentItem() or self.installed_files_widget.currentItem()
if selected_item:
file_name = selected_item.text()
reply = QMessageBox.question(self, 'Delete Item', f'Are you sure you want to delete "{file_name}"?',
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
file_type = self.file_type_combo_box.currentText()
if file_type == "Mods":
directory = "marroc/mods"
elif file_type == "Resource Packs":
directory = "marroc/resourcepacks"
else:
return
file_path = os.path.join(directory, file_name)
if os.path.exists(file_path):
os.remove(file_path)
self.load_files()
else:
QMessageBox.warning(self, 'File Not Found', 'The selected file does not exist.')
def get_source_directory(self):
file_type = self.file_type_combo_box.currentText()
if file_type == "Mods":
return "marroc/mods"
elif file_type == "Resource Packs":
return "marroc/resourcepacks"
else:
return ""
def get_destination_directory(self):
file_type = self.file_type_combo_box.currentText()
if file_type == "Mods":
if sys.platform.startswith('linux'):
return os.path.expanduser("~/.local/share/picomc/instances/default/minecraft/mods")
elif sys.platform.startswith('win'):
return os.path.join(os.getenv('APPDATA'), '.picomc/instances/default/minecraft/mods')
elif file_type == "Resource Packs":
if sys.platform.startswith('linux'):
return os.path.expanduser("~/.local/share/picomc/instances/default/minecraft/resourcepacks")
elif sys.platform.startswith('win'):
return os.path.join(os.getenv('APPDATA'), '.picomc/instances/default/minecraft/resourcepacks')
else:
return ""
class ModDetailsWindow(QDialog):
def __init__(self, mod_data, icon_url, mod_versions):
super().__init__()
self.setWindowTitle("Mod Details")
self.setGeometry(100, 100, 400, 300)
self.mod_data = mod_data
layout = QVBoxLayout()
mod_name_label = QLabel(f"<h2>{mod_data['title']}</h2>")
mod_name_label.setAlignment(Qt.AlignCenter)
layout.addWidget(mod_name_label)
mod_description_label = QLabel(mod_data['description'])
mod_description_label.setWordWrap(True)
layout.addWidget(mod_description_label)
icon_pixmap = self.load_icon(icon_url)
icon_label = QLabel()
if icon_pixmap:
icon_label.setPixmap(icon_pixmap)
icon_label.setAlignment(Qt.AlignCenter)
layout.addWidget(icon_label)
self.version_dropdown = QComboBox()
for version in mod_versions:
self.version_dropdown.addItem(version['version'])
self.version_dropdown.setItemData(self.version_dropdown.count() - 1, version['files'], Qt.UserRole)
layout.addWidget(self.version_dropdown)
self.download_button = QPushButton("Download")
self.download_button.clicked.connect(self.download_mod)
layout.addWidget(self.download_button)
self.download_url_label = QLabel()
self.download_url_label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.download_url_label)
layout.addStretch(1)
self.setLayout(layout)
def load_icon(self, icon_url):
try:
response = requests.get(icon_url)
if response.status_code == 200:
pixmap = QPixmap()
pixmap.loadFromData(response.content)
return pixmap.scaled(QSize(128, 128), Qt.KeepAspectRatio, Qt.SmoothTransformation)
else:
return None
except Exception as e:
print("Error loading icon:", e)
return None
def download_mod(self):
selected_version_index = self.version_dropdown.currentIndex()
selected_version_files = self.version_dropdown.itemData(selected_version_index, Qt.UserRole)
if selected_version_files:
for file_url in selected_version_files:
filename = os.path.basename(file_url)
try:
response = requests.get(file_url)
response.raise_for_status()
save_dir = "marroc/mods" if filename.endswith('.jar') else "marroc/resourcepacks"
with open(os.path.join(save_dir, filename), 'wb') as f:
f.write(response.content)
QMessageBox.information(self, "Download Mod", f"Downloaded {filename} successfully.")
return
except requests.exceptions.RequestException as e:
QMessageBox.warning(self, "Download Error", f"Error downloading mod: {e}")
return
QMessageBox.warning(self, "Download Mod", "Failed to download the mod.")
if __name__ == "__main__":
app = QApplication(sys.argv)
app_icon = QIcon('marroc.ico')
app.setWindowIcon(app_icon)
window = ModrinthSearchApp()
window.show()
sys.exit(app.exec_())

BIN
missing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,5 @@
picomc
PyQt5
PyQt5
requests
pypresence
tqdm

14
version.json Normal file
View File

@ -0,0 +1,14 @@
{
"version": "0.12.1",
"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"
],
"versionBleeding": "0.12.1-188"
}