diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index e1ee600..d12fc4a 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -16,7 +16,22 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' + + - name: Create .env file from secrets + shell: powershell + run: | + $envContent = @" + # Default Collection URLs + CORE_COLLECTION_URL=${{ secrets.CORE_COLLECTION_URL || 'https://steamcommunity.com/workshop/filedetails/?id=3521297585' }} + CONTENT_COLLECTION_URL=${{ secrets.CONTENT_COLLECTION_URL || 'steam://openurl/https://steamcommunity.com/sharedfiles/filedetails/?id=3521319712' }} + COSMETICS_COLLECTION_URL=${{ secrets.COSMETICS_COLLECTION_URL || 'steam://openurl/https://steamcommunity.com/sharedfiles/filedetails/?id=3637541646' }} + + # ModsConfig.xml Path Template + MODSCONFIG_PATH_TEMPLATE=${{ secrets.MODSCONFIG_PATH_TEMPLATE || '%USERPROFILE%\AppData\LocalLow\Ludeon Studios\RimWorld by Ludeon Studios\Config\ModsConfig.xml' }} + "@ + $envContent | Out-File -FilePath .env -Encoding UTF8 -Force + Write-Host "Created .env file with configuration" - name: Install dependencies shell: powershell @@ -29,28 +44,14 @@ jobs: shell: powershell run: | $ErrorActionPreference = 'Stop' - # Stamp version into sealoader_version.py from release tag - if ($env:GITHUB_EVENT_NAME -eq 'release') { - $tag = '${{ github.event.release.tag_name }}' - } else { - $tag = (git describe --tags --always) 2>$null - if (-not $tag) { $tag = "0.0.0-dev" } - } - ("__version__ = '" + $tag + "'") | Out-File -FilePath sealoader_version.py -Encoding UTF8 -Force - # Bundle PNG resources referenced at runtime - pyinstaller --noconfirm --onefile --windowed sealoader_gui.py --name SeaLoader ` - --add-data "SeaLoader.png;." ` - --add-data "hrsys.png;." ` - --icon SeaLoader.ico + # Build standalone executable with all assets bundled + pyinstaller --clean --onefile --windowed --icon=art/Progression.ico --add-data "art;art" --add-data ".env;." --name ProgressionLoader steam_workshop_gui.py - name: Prepare artifact shell: powershell run: | - New-Item -ItemType Directory -Force -Path dist_upload | Out-Null - Copy-Item dist\SeaLoader.exe dist_upload\SeaLoader.exe - if (Test-Path README.md) { Copy-Item README.md dist_upload\ } - if (Test-Path LICENSE) { Copy-Item LICENSE dist_upload\ } - Compress-Archive -Path dist_upload\* -DestinationPath SeaLoader_Windows_x64.zip -Force + # Just upload the standalone .exe file + Copy-Item dist\ProgressionLoader.exe ProgressionLoader.exe - name: Upload asset to Release if: ${{ github.event_name == 'release' && github.event.action == 'published' }} @@ -62,9 +63,7 @@ jobs: SERVER_URL: ${{ github.server_url }} run: | $ErrorActionPreference = 'Stop' - $uploadUrl = "$env:SERVER_URL/api/v1/repos/$env:REPO/releases/$env:RELEASE_ID/assets?name=SeaLoader_Windows_x64.zip" - Write-Host "Uploading asset to $uploadUrl" - Invoke-RestMethod -Method Post -Uri $uploadUrl -Headers @{ Authorization = "token $env:TOKEN" } -ContentType "application/zip" -InFile "SeaLoader_Windows_x64.zip" - - # CI artifact upload removed for GHES compatibility + $uploadUrl = "$env:SERVER_URL/api/v1/repos/$env:REPO/releases/$env:RELEASE_ID/assets?name=ProgressionLoader.exe" + Write-Host "Uploading ProgressionLoader.exe to $uploadUrl" + Invoke-RestMethod -Method Post -Uri $uploadUrl -Headers @{ Authorization = "token $env:TOKEN" } -ContentType "application/octet-stream" -InFile "ProgressionLoader.exe" diff --git a/steam_workshop_gui.py b/steam_workshop_gui.py index 698c52d..5f7f9e2 100644 --- a/steam_workshop_gui.py +++ b/steam_workshop_gui.py @@ -5,6 +5,7 @@ import re from urllib.parse import urlparse, parse_qs import threading import os +import sys from pathlib import Path import xml.etree.ElementTree as ET from dotenv import load_dotenv @@ -15,6 +16,16 @@ import webbrowser # Load environment variables load_dotenv() +def get_resource_path(relative_path): + """Get absolute path to resource, works for dev and for PyInstaller""" + try: + # PyInstaller creates a temp folder and stores path in _MEIPASS + base_path = sys._MEIPASS + except Exception: + base_path = os.path.abspath(".") + + return os.path.join(base_path, relative_path) + class LoadingScreen: def __init__(self, root, on_complete_callback): self.root = root @@ -32,7 +43,7 @@ class LoadingScreen: # Set window icon try: - icon_path = os.path.join("art", "Progression.ico") + icon_path = get_resource_path(get_resource_path(os.path.join("art", "Progression.ico"))) if os.path.exists(icon_path): self.loading_window.iconbitmap(icon_path) except Exception as e: @@ -56,7 +67,7 @@ class LoadingScreen: def load_custom_font(self): """Load the RimWorld font using Windows AddFontResourceEx with private flag""" try: - font_path = os.path.join("art", "RimWordFont4.ttf") + font_path = get_resource_path(os.path.join("art", "RimWordFont4.ttf")) if os.path.exists(font_path): abs_font_path = os.path.abspath(font_path) @@ -190,11 +201,11 @@ class LoadingScreen: """Load all required images""" try: # Load game title - self.game_title_img = Image.open("art/GameTitle.png") + self.game_title_img = Image.open(get_resource_path("art/GameTitle.png")) self.game_title_tk = ImageTk.PhotoImage(self.game_title_img) # Load HR Systems logo - self.hr_logo_img = Image.open("art/hudsonriggssystems.png") + self.hr_logo_img = Image.open(get_resource_path("art/hudsonriggssystems.png")) # Resize HR logo to be smaller hr_width, hr_height = self.hr_logo_img.size new_hr_height = 60 @@ -207,7 +218,7 @@ class LoadingScreen: # Load expansion images - dynamically find all NotOwned_ files self.expansion_images = {} - art_dir = "art" + art_dir = get_resource_path("art") if os.path.exists(art_dir): for file in os.listdir(art_dir): @@ -460,7 +471,7 @@ class LoadingScreen: if not modsconfig_path or not os.path.exists(modsconfig_path): # If no ModsConfig found, get all NotOwned_ files and assume all are missing - art_dir = "art" + art_dir = get_resource_path("art") not_owned_files = [] if os.path.exists(art_dir): for file in os.listdir(art_dir): @@ -479,7 +490,7 @@ class LoadingScreen: except Exception as e: print(f"Error checking expansions: {e}") # Assume all missing on error - get from NotOwned_ files - art_dir = "art" + art_dir = get_resource_path("art") not_owned_files = [] if os.path.exists(art_dir): for file in os.listdir(art_dir): @@ -506,7 +517,7 @@ class LoadingScreen: def parse_known_expansions(self, modsconfig_path): """Parse ModsConfig.xml to check which expansions are owned""" # Get all NotOwned_ PNG files from art directory - art_dir = "art" + art_dir = get_resource_path("art") not_owned_files = [] if os.path.exists(art_dir): for file in os.listdir(art_dir): @@ -738,7 +749,7 @@ class LoadingScreen: # Set window icon try: - icon_path = os.path.join("art", "Progression.ico") + icon_path = get_resource_path(os.path.join("art", "Progression.ico")) if os.path.exists(icon_path): warning_window.iconbitmap(icon_path) except Exception: @@ -903,7 +914,7 @@ All collections are required for the complete Progression experience.""" # Set window icon try: - icon_path = os.path.join("art", "Progression.ico") + icon_path = get_resource_path(os.path.join("art", "Progression.ico")) if os.path.exists(icon_path): instruction_window.iconbitmap(icon_path) except Exception: @@ -1166,7 +1177,7 @@ class SteamWorkshopGUI: # Load and display progression logo (using game title as progression logo) try: # Load the game title image as progression logo - progression_img = Image.open("art/GameTitle.png") + progression_img = Image.open(get_resource_path("art/GameTitle.png")) # Resize to fit header img_width, img_height = progression_img.size new_height = 80 @@ -1204,7 +1215,7 @@ class SteamWorkshopGUI: try: # Load HR Systems logo - hr_img = Image.open("art/hudsonriggssystems.png") + hr_img = Image.open(get_resource_path("art/hudsonriggssystems.png")) # Resize to appropriate size for footer - slightly larger for better visibility img_width, img_height = hr_img.size new_height = 60 # Increased from 50 to 60 @@ -1337,7 +1348,7 @@ class SteamWorkshopGUI: def load_custom_font(self): """Load the RimWorld font using Windows AddFontResourceEx with private flag""" try: - font_path = os.path.join("art", "RimWordFont4.ttf") + font_path = get_resource_path(os.path.join("art", "RimWordFont4.ttf")) if os.path.exists(font_path): abs_font_path = os.path.abspath(font_path) @@ -2389,7 +2400,7 @@ class SteamWorkshopGUI: # Set window icon try: - icon_path = os.path.join("art", "Progression.ico") + icon_path = get_resource_path(os.path.join("art", "Progression.ico")) if os.path.exists(icon_path): self.success_window.iconbitmap(icon_path) except Exception: @@ -2406,7 +2417,7 @@ class SteamWorkshopGUI: # Load and prepare logo for animation try: # Load the progression logo (GameTitle.png) - success_logo_img = Image.open("art/GameTitle.png") + success_logo_img = Image.open(get_resource_path("art/GameTitle.png")) # Start with smaller size (current header size) start_height = 80 start_width = int((start_height / success_logo_img.size[1]) * success_logo_img.size[0]) @@ -2569,7 +2580,7 @@ def main(): # Set window icon try: - icon_path = os.path.join("art", "Progression.ico") + icon_path = get_resource_path(os.path.join("art", "Progression.ico")) if os.path.exists(icon_path): root.iconbitmap(icon_path) except Exception as e: @@ -2586,4 +2597,4 @@ def main(): root.mainloop() if __name__ == "__main__": - main() \ No newline at end of file + main()