From 3f076d899be72bf0e4156fd7defeeae15d771327 Mon Sep 17 00:00:00 2001 From: ikun Date: Sat, 21 Sep 2024 11:08:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 71 ++++++++++++++++++++++++ common/__init__.py | 0 common/get_steam_path.py | 10 ++++ common/show_messagebox.py | 26 +++++++++ main.py | 104 ++++++++++++++++++++++++++++++++++++ package.json | 19 +++++++ 6 files changed, 230 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 common/__init__.py create mode 100644 common/get_steam_path.py create mode 100644 common/show_messagebox.py create mode 100644 main.py create mode 100644 package.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..6697989 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,71 @@ +name: Build + +on: + push: + branches: + - main + +jobs: + build: + runs-on: windows-2019 + steps: + - name: Check out git repository + uses: actions/checkout@v4 + + # Push tag to GitHub if package.json version's tag is not tagged + - name: Get package version + shell: powershell + run: | + $version = (Get-Content package.json | ConvertFrom-Json).version + echo "PACKAGE_VERSION=$version" >> $env:GITHUB_ENV + + + - name: Set up Python 3.11 + uses: actions/setup-python@v3 + with: + python-version: 3.11.9 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Build + uses: Nuitka/Nuitka-Action@main + with: + nuitka-version: main + script-name: main.py + standalone: true + onefile: true + show-memory: true + windows-uac-admin: true + windows-icon-from-ico: icon.jpg + company-name: ikunshare + product-name: Game Uninstaller + file-version: ${{ env.PACKAGE_VERSION }} + product-version: ${{ env.PACKAGE_VERSION }} + file-description: 删除SteamTools或GreenLuma解锁的游戏 + copyright: Copyright © 2024 ikun0014 + output-file: Game Uninstaller---v${{ env.PACKAGE_VERSION }}.exe + assume-yes-for-downloads: true + output-dir: build + + - name: Create git tag + uses: pkgdeps/git-tag-action@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + github_repo: ${{ github.repository }} + version: ${{ env.PACKAGE_VERSION }} + git_commit_sha: ${{ github.sha }} + git_tag_prefix: "v" + + - name: Release + uses: softprops/action-gh-release@v2 + with: + prerelease: false + draft: false + tag_name: v${{ env.PACKAGE_VERSION }} + files: | + build/Game Uninstaller---v${{ env.PACKAGE_VERSION }}.exe + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/common/__init__.py b/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/common/get_steam_path.py b/common/get_steam_path.py new file mode 100644 index 0000000..a590c10 --- /dev/null +++ b/common/get_steam_path.py @@ -0,0 +1,10 @@ +import winreg + +from pathlib import Path + +def get_steam_path(): + key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Valve\Steam') + steam_path = Path(winreg.QueryValueEx(key, 'SteamPath')[0]) + return steam_path + +steam_path = get_steam_path() \ No newline at end of file diff --git a/common/show_messagebox.py b/common/show_messagebox.py new file mode 100644 index 0000000..46f6e73 --- /dev/null +++ b/common/show_messagebox.py @@ -0,0 +1,26 @@ +from tkinter import messagebox +import tkinter as tk + +def show_messagebox(parent, title, message, type="info"): + """ + 显示消息框并确保其在顶部显示 + :param parent: 父窗口 + :param title: 消息框标题 + :param message: 消息内容 + :param type: 消息框类型(info, warning, error, yesno) + :return: None 或 bool(仅在 yesno 类型时返回) + """ + messagebox_window = tk.Toplevel(parent) + messagebox_window.withdraw() # 隐藏主窗口 + messagebox_window.attributes("-topmost", True) # 确保置顶 + + if type == "info": + messagebox.showinfo(title, message, parent=messagebox_window) + elif type == "warning": + messagebox.showwarning(title, message, parent=messagebox_window) + elif type == "error": + messagebox.showerror(title, message, parent=messagebox_window) + elif type == "yesno": + return messagebox.askyesno(title, message, parent=messagebox_window) + + messagebox_window.destroy() \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..4134fa5 --- /dev/null +++ b/main.py @@ -0,0 +1,104 @@ +import os +import tkinter as tk +from tkinter import ttk +import sv_ttk +from common.get_steam_path import steam_path +from common.show_messagebox import show_messagebox + +def load_unlocked_games(): + games = [] + + if os.path.exists(stplug_path): + for filename in os.listdir(stplug_path): + if filename.endswith('.st'): + appid = filename.replace('.st', '') + games.append({"appid": appid, "name": f"Game {appid}", "type": "SteamTools"}) + else: + print(f"Path not found: {stplug_path}") + + if os.path.exists(greenluma_path): + for filename in os.listdir(greenluma_path): + if filename.endswith('.txt'): + appid = filename.replace('.txt', '') + games.append({"appid": appid, "name": f"Game {appid}", "type": "GreenLuma"}) + else: + print(f"Path not found: {greenluma_path}") + + return games + +def filter_games(): + search_term = search_var.get().lower() + for row in tree.get_children(): + tree.delete(row) + for game in unlocked_games: + if search_term in game["appid"].lower() or search_term in game["name"].lower() or search_term in game["type"].lower(): + tree.insert("", "end", values=(game["appid"], game["name"], game["type"])) + +def delete_game(appid, game_type): + if game_type == "SteamTools": + file_path = os.path.join(stplug_path, f"{appid}.st") + elif game_type == "GreenLuma": + file_path = os.path.join(greenluma_path, f"{appid}.txt") + + if os.path.exists(file_path): + os.remove(file_path) + refresh_games() + +def refresh_games(): + global unlocked_games + unlocked_games = load_unlocked_games() + filter_games() + +def on_delete(): + selected_item = tree.selection() + if not selected_item: + show_messagebox(root, "Warning", "No game selected. Please select a game to delete.", "warning") + return + appid = tree.item(selected_item[0], "values")[0] + game_type = tree.item(selected_item[0], "values")[2] + delete_game(appid, game_type) + show_messagebox(root, title="Success", message=f"Game: {appid}, Delete Success.", type="warning") + +def on_key_press(event): + if event.keysym == 'Delete': + on_delete() + elif event.keysym == 'F5': + refresh_games() + +root = tk.Tk() +root.title("Unlocked Games Manager") +root.geometry("600x400") + +sv_ttk.use_light_theme() + +search_var = tk.StringVar() +search_entry = ttk.Entry(root, textvariable=search_var) +search_entry.pack(pady=10) + +search_button = ttk.Button(root, text="Search", command=filter_games) +search_button.pack() + +columns = ("AppID", "Name", "Type") +tree = ttk.Treeview(root, columns=columns, show="headings") +tree.heading("AppID", text="AppID") +tree.heading("Name", text="Name") +tree.heading("Type", text="Type") +tree.pack(expand=True, fill="both") + +delete_button = ttk.Button(root, text="Delete (Delete)", command=on_delete) +delete_button.pack(pady=10) + +root.bind('', on_key_press) +root.bind('', on_key_press) + +stplug_path = steam_path / 'config' / 'stplug-in' +greenluma_path = steam_path / 'AppList' + +if not os.path.exists(stplug_path) and not os.path.exists(greenluma_path): + show_messagebox(root, "Error", "Both SteamTools and GreenLuma paths do not exist.", "error") + root.destroy() +else: + unlocked_games = load_unlocked_games() + filter_games() + +root.mainloop() diff --git a/package.json b/package.json new file mode 100644 index 0000000..06633fa --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "game-uninstaller", + "version": "1.0.0", + "description": "删除SteamTools或GreenLuma解锁的游戏", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ikunshare/Game-Uninstaller.git" + }, + "author": "ikun0014", + "license": "MIT", + "bugs": { + "url": "https://github.com/ikunshare/Game-Uninstaller/issues" + }, + "homepage": "https://github.com/ikunshare/Game-Uninstaller#readme" +}