Compare commits

...

29 Commits
main ... v

Author SHA1 Message Date
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
4 changed files with 316 additions and 11 deletions

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

@ -0,0 +1,61 @@
name: Version Change Action
on:
push:
paths:
- version.json # Trigger on changes to version.json
jobs:
run-on-version-change:
runs-on: windows-latest # Use Windows 10 runner
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: Read version and name from version.json
id: version
run: |
$VERSION = (jq -r '.version' version.json)
$NAME = (jq -r '.name' version.json)
echo "VERSION=$VERSION" >> $GITHUB_ENV # Store version in the environment variable
echo "NAME=$NAME" >> $GITHUB_ENV # Store name in the environment variable
- name: Tag release
run: |
# Set Git user for the GitHub Actions runner
git config user.name "github-actions"
git config user.email "github-actions@github.com"
# Create the tag and push it to GitHub
$VERSION_NAME = "${env:VERSION} ${env:NAME}"
git tag -a "v${env:VERSION}" -m "Release $VERSION_NAME" # Tag the release with version number and name
git push origin "v${env:VERSION}" # Push the tag to GitHub
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: actions-temp/build/2hsu.exe # Specify the path to the file to upload

View File

@ -38,7 +38,7 @@
- **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
If you are on windows you may be more interested in a [installer](https://github.com/nixietab/2hsu/releases/download/release/2hsu.exe)

View File

@ -299,6 +299,7 @@ class PicomcVersionSelector(QWidget):
"IsRCPenabled": False,
"CheckUpdate": False,
"LastPlayed": "",
"Instance": "default",
"Theme": "Dark.json",
"ThemeBackground": True,
"ThemeRepository": "https://raw.githubusercontent.com/nixietab/picodulce-themes/main/repo.json"
@ -825,12 +826,18 @@ class PicomcVersionSelector(QWidget):
try:
# Set current_state to the selected instance
self.current_state = selected_instance
# Read the config.json to get the "Instance" value
with open('config.json', 'r') as config_file:
config = json.load(config_file)
instance_value = config.get("Instance", "default") # Default to "default" if not found
# Update lastplayed field in config.json on a separate thread
update_thread = threading.Thread(target=self.update_last_played, args=(selected_instance,))
update_thread.start()
# Run the game subprocess
subprocess.run(['picomc', 'play', selected_instance], check=True)
# Run the game subprocess with the instance_value from config.json
subprocess.run(['picomc', 'instance', 'launch', '--version-override', selected_instance, instance_value], check=True)
except subprocess.CalledProcessError as e:
error_message = f"Error playing {selected_instance}: {e}"
@ -843,7 +850,7 @@ class PicomcVersionSelector(QWidget):
finally:
# Reset current_state to "menu" after the game closes
self.current_state = "menu"
def update_last_played(self, selected_instance):
config_path = "config.json"
self.config["LastPlayed"] = selected_instance
@ -1235,9 +1242,11 @@ class ModLoaderAndVersionMenu(QDialog):
# Create tabs
install_mod_tab = QWidget()
download_version_tab = QWidget()
instances_tab = QWidget() # New tab for instances
tab_widget.addTab(download_version_tab, "Download Version")
tab_widget.addTab(install_mod_tab, "Install Mod Loader")
tab_widget.addTab(instances_tab, "Instances") # Add the new tab
# Add content to "Install Mod Loader" tab
self.setup_install_mod_loader_tab(install_mod_tab)
@ -1245,6 +1254,240 @@ class ModLoaderAndVersionMenu(QDialog):
# Add content to "Download Version" tab
self.setup_download_version_tab(download_version_tab)
# Add content to "Instances" tab
self.setup_instances_tab(instances_tab)
def setup_instances_tab(self, instances_tab):
layout = QVBoxLayout(instances_tab)
# Create title label
title_label = QLabel('Current Instance:')
title_label.setFont(QFont("Arial", 14))
layout.addWidget(title_label)
# Create a label to display the current instance
self.current_instance_label = QLabel('Loading...') # Placeholder text
layout.addWidget(self.current_instance_label)
# Create a QListWidget to display the instances
self.instances_list_widget = QListWidget()
layout.addWidget(self.instances_list_widget)
# Create input field and button to create a new instance
self.create_instance_input = QLineEdit()
self.create_instance_input.setPlaceholderText("Enter instance name")
layout.addWidget(self.create_instance_input)
create_instance_button = QPushButton("Create Instance")
create_instance_button.clicked.connect(self.create_instance)
layout.addWidget(create_instance_button)
# Create input field and button to rename an instance
self.rename_instance_input = QLineEdit()
self.rename_instance_input.setPlaceholderText("Enter new instance name")
layout.addWidget(self.rename_instance_input)
rename_instance_button = QPushButton("Rename Instance")
rename_instance_button.clicked.connect(self.rename_instance)
layout.addWidget(rename_instance_button)
# Create button to delete an instance
delete_instance_button = QPushButton("Delete Instance")
delete_instance_button.clicked.connect(self.delete_instance)
layout.addWidget(delete_instance_button)
# Fetch and display the current instances
self.load_instances()
# Connect the item selection to the instance selection method
self.instances_list_widget.itemClicked.connect(self.on_instance_selected)
# Update the label with the current instance from the config
self.update_instance_label()
def create_instance(self):
instance_name = self.create_instance_input.text().strip()
if instance_name:
try:
# Run the "picomc instance create" command
process = subprocess.Popen(['picomc', 'instance', 'create', instance_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
output, error = process.communicate()
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
# Notify the user that the instance was created
QMessageBox.information(self, "Instance Created", f"Instance '{instance_name}' has been created successfully.")
# Reload the instances list
self.load_instances()
# Optionally select the newly created instance
self.on_instance_selected(self.instances_list_widget.item(self.instances_list_widget.count() - 1))
except FileNotFoundError:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.")
except subprocess.CalledProcessError as e:
logging.error("Error creating instance: %s", e.stderr)
QMessageBox.critical(self, "Error", f"Failed to create instance: {e.stderr}")
else:
QMessageBox.warning(self, "Invalid Input", "Please enter a valid instance name.")
def rename_instance(self):
selected_item = self.instances_list_widget.currentItem()
if not selected_item:
QMessageBox.warning(self, "No Selection", "Please select an instance to rename.")
return
old_instance_name = selected_item.text()
new_instance_name = self.rename_instance_input.text().strip()
if not new_instance_name:
QMessageBox.warning(self, "Invalid Input", "Please enter a valid new instance name.")
return
if old_instance_name == "default":
QMessageBox.warning(self, "Cannot Rename Instance", "You cannot rename the 'default' instance.")
return
try:
# Run the "picomc instance rename" command
process = subprocess.Popen(
['picomc', 'instance', 'rename', old_instance_name, new_instance_name],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
output, error = process.communicate()
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
QMessageBox.information(self, "Instance Renamed", f"Instance '{old_instance_name}' has been renamed to '{new_instance_name}' successfully.")
# Reload the instances list
self.load_instances()
# Optionally select the newly renamed instance
matching_items = self.instances_list_widget.findItems(new_instance_name, Qt.MatchExactly)
if matching_items:
self.instances_list_widget.setCurrentItem(matching_items[0])
except FileNotFoundError:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.")
except subprocess.CalledProcessError as e:
logging.error("Error renaming instance: %s", e.stderr)
QMessageBox.critical(self, "Error", f"Failed to rename instance: {e.stderr}")
def delete_instance(self):
# Get the selected instance name
selected_instance = self.instances_list_widget.currentItem()
if selected_instance:
instance_name = selected_instance.text()
# Prevent deletion of the "default" instance
if instance_name == "default":
QMessageBox.warning(self, "Cannot Delete Instance", "You cannot delete the 'default' instance.")
return
confirm_delete = QMessageBox.question(
self, "Confirm Deletion", f"Are you sure you want to delete the instance '{instance_name}'?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No
)
if confirm_delete == QMessageBox.Yes:
try:
# Run the "picomc instance delete" command
process = subprocess.Popen(['picomc', 'instance', 'delete', instance_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
output, error = process.communicate()
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
# Notify the user that the instance was deleted
QMessageBox.information(self, "Instance Deleted", f"Instance '{instance_name}' has been deleted successfully.")
# Reload the instances list
self.load_instances()
except FileNotFoundError:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.")
except subprocess.CalledProcessError as e:
logging.error("Error deleting instance: %s", e.stderr)
QMessageBox.critical(self, "Error", f"Failed to delete instance: {e.stderr}")
else:
QMessageBox.warning(self, "No Selection", "Please select an instance to delete.")
def load_instances(self):
try:
process = subprocess.Popen(['picomc', 'instance', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
output, error = process.communicate()
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
# Parse the output and add each instance to the list widget
instances = output.splitlines()
self.instances_list_widget.clear() # Clear the previous list
self.instances_list_widget.addItems(instances)
except FileNotFoundError:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.")
except subprocess.CalledProcessError as e:
logging.error("Error fetching instances: %s", e.stderr)
def on_instance_selected(self, item):
# Get the selected instance name
selected_instance = item.text()
# Path to the config.json file
config_file = 'config.json'
# Check if the config file exists
if os.path.exists(config_file):
try:
# Load the current config.json file
with open(config_file, 'r') as file:
config_data = json.load(file)
# Update the "Instance" value with the selected instance name
config_data['Instance'] = selected_instance
# Save the updated config back to the file
with open(config_file, 'w') as file:
json.dump(config_data, file, indent=4)
logging.info(f"Config updated: Instance set to {selected_instance}")
# Update the label with the new instance
self.update_instance_label()
except (json.JSONDecodeError, FileNotFoundError) as e:
logging.error(f"Error reading config.json: {e}")
else:
logging.warning(f"{config_file} not found. Unable to update instance.")
def update_instance_label(self):
config_file = 'config.json'
if os.path.exists(config_file):
try:
# Load the config file
with open(config_file, 'r') as file:
config_data = json.load(file)
# Get the current instance from the config and update the label
current_instance = config_data.get('Instance', 'Not set')
self.current_instance_label.setText(f'Current instance: {current_instance}')
except (json.JSONDecodeError, FileNotFoundError) as e:
logging.error(f"Error reading config.json: {e}")
else:
self.current_instance_label.setText('Current instance: Not set')
def setup_install_mod_loader_tab(self, install_mod_tab):
layout = QVBoxLayout(install_mod_tab)

View File

@ -1,11 +1,12 @@
{
"version": "0.11.2",
"version": "0.11.4",
"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/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"
]
}