Skip to content

Commit 270e97b

Browse files
authored
Merge pull request #17 from thepeacockproject/feat/launcher-enhancements-v2
2 parents 4bb50b4 + c284f18 commit 270e97b

16 files changed

Lines changed: 474 additions & 82 deletions

File tree

.github/workflows/release.yml

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,65 @@
11
name: Release
22

33
on:
4-
push:
5-
tags:
6-
- "v*"
4+
push:
5+
tags:
6+
- "v*"
77

88
env:
9-
CARGO_TERM_COLOR: always
9+
CARGO_TERM_COLOR: always
1010

1111
permissions:
12-
contents: write
12+
contents: write
1313

1414
jobs:
15-
build:
16-
name: Build AppImage
17-
runs-on: ubuntu-latest
18-
19-
steps:
20-
- name: Checkout
21-
uses: actions/checkout@v6
22-
23-
- name: Install Rust toolchain
24-
uses: dtolnay/rust-toolchain@stable
25-
26-
- name: Cache Cargo
27-
uses: Swatinem/rust-cache@v2
28-
with:
29-
workspaces: launcher
30-
31-
- name: Install system dependencies
32-
run: |
33-
sudo apt-get update
34-
sudo apt-get install -y libfuse2 libgtk-3-dev libwayland-dev libxkbcommon-dev
35-
36-
- name: Install appimagetool
37-
run: |
38-
wget -q -O appimagetool https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
39-
chmod +x appimagetool
40-
sudo mv appimagetool /usr/local/bin/appimagetool
41-
42-
- name: Install cargo-appimage
43-
run: cargo install cargo-appimage
44-
45-
- name: Build AppImage
46-
working-directory: launcher
47-
run: cargo appimage
48-
49-
- name: Rename artifact
50-
run: |
51-
TAG="${GITHUB_REF_NAME}"
52-
mv launcher/target/appimage/peacock-launcher.AppImage \
53-
"peacock-launcher-${TAG}-x86_64.AppImage"
54-
55-
- name: Create GitHub Release
56-
uses: softprops/action-gh-release@v2
57-
with:
58-
generate_release_notes: true
59-
make_latest: true
60-
files: peacock-launcher-*-x86_64.AppImage
15+
build:
16+
name: Build AppImage
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v6
22+
23+
- name: Install Rust toolchain
24+
uses: dtolnay/rust-toolchain@stable
25+
26+
- name: Cache Cargo
27+
uses: Swatinem/rust-cache@v2
28+
with:
29+
workspaces: launcher
30+
31+
- name: Install system dependencies
32+
run: |
33+
sudo apt-get update
34+
sudo apt-get install -y libfuse2 libgtk-3-dev libwayland-dev libxkbcommon-dev
35+
36+
- name: Install appimagetool
37+
run: |
38+
wget -q -O appimagetool https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
39+
chmod +x appimagetool
40+
sudo mv appimagetool /usr/local/bin/appimagetool
41+
42+
- name: Install cargo-appimage
43+
run: cargo install cargo-appimage
44+
45+
- name: Set version from tag
46+
run: |
47+
VERSION="${GITHUB_REF_NAME#v}"
48+
sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" launcher/Cargo.toml
49+
50+
- name: Build AppImage
51+
working-directory: launcher
52+
run: cargo appimage
53+
54+
- name: Rename artifact
55+
run: |
56+
TAG="${GITHUB_REF_NAME}"
57+
mv launcher/target/appimage/peacock-launcher.AppImage \
58+
"peacock-launcher-${TAG}-x86_64.AppImage"
59+
60+
- name: Create GitHub Release
61+
uses: softprops/action-gh-release@v2
62+
with:
63+
generate_release_notes: true
64+
make_latest: true
65+
files: peacock-launcher-*-x86_64.AppImage

MIGRATION.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Migration Guide
2+
3+
This guide is for players moving from the old shell-script-based `linux-steam-setup` to the AppImage launcher.
4+
5+
## What Changes
6+
7+
- Peacock and Node.js move into the launcher-managed install directory.
8+
- The old `peacock.service` is replaced with the launcher's service definition.
9+
- If your old service started automatically or was already running, the launcher restores that state.
10+
- Legacy patcher files such as `PeacockPatcher.exe` and `WineLaunch.bat` are removed from detected game folders.
11+
- The old batch-file injection flow is retired. Use ZHMModSDK with OnlineTools after migrating.
12+
13+
## Before You Start
14+
15+
1. Make sure the legacy install still exists on disk.
16+
2. Close HITMAN 3 before starting migration.
17+
3. If you edited your old setup manually, keep the legacy directory until you confirm the new launcher setup works.
18+
19+
## Migration Steps
20+
21+
1. Launch the AppImage.
22+
2. Select **Migrate from old setup**.
23+
3. Confirm the detected folder, or choose **Browse for folder…** if your install lives somewhere else.
24+
4. Start migration.
25+
5. When the wizard finishes, keep the old directory until you have tested the new setup once.
26+
27+
## Switch From The Old Patcher Method
28+
29+
After migration, do not go back to `WineLaunch.bat`, `Hitman 3 (Peacock).desktop`, or `PeacockPatcher.exe`.
30+
31+
Instead:
32+
33+
1. In the launcher, open **Manage ZHMModSDK**.
34+
2. Install ZHMModSDK into your HITMAN 3 directory.
35+
3. Start the game normally through Steam or Heroic.
36+
4. Open the SDK panel in-game and enable **OnlineTools**.
37+
5. In OnlineTools, use **Help****Load Old Patcher Settings**.
38+
6. Confirm the server address is `localhost:3000` unless you changed the Peacock port.
39+
40+
If you changed the Peacock port in the launcher settings, use `localhost:PORT` with your selected port instead.
41+
42+
## After Migration
43+
44+
1. Check **Manage Service** in the launcher and confirm the service is installed.
45+
2. If you want Peacock running in the background automatically, ensure **Enable on Boot** is set.
46+
3. Start HITMAN 3 and verify OnlineTools connects successfully.
47+
4. Delete the old legacy directory only after you are satisfied the new setup works.
48+
49+
## Troubleshooting
50+
51+
- If Peacock is not reachable, open **Manage Service** in the launcher and verify the service is running.
52+
- If OnlineTools is missing, reinstall ZHMModSDK from the launcher and restart the game.
53+
- If you still have old patcher files in a custom game folder the launcher did not detect, remove `PeacockPatcher.exe` and `WineLaunch.bat` manually and continue using the normal game launch path.

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,21 @@ A TUI (Terminal User Interface) application for managing [Peacock](https://thepe
2727
./peacock-launcher-*.AppImage # Or double-click the file in your file manager
2828
```
2929
4. Select **Install / Update Peacock & Node** from the main menu
30-
5. Select **Manage Service****Install Service****Start Service**
31-
6. (Optional) Select **Manage ZHMModSDK** to install the SDK into your Hitman 3 directory
30+
5. Select **Manage Service****Install Service****Start Service** to have Peacock running in the background
31+
6. (Optional) Select **Enable on Boot** to have Peacock start automatically when you log in
32+
7. (Optional) Select **Manage ZHMModSDK** to install the SDK into your Hitman 3 directory
33+
34+
## Migrating From The Legacy Setup
35+
36+
If you were using the old shell-script setup, open the launcher and select **Migrate from old setup**.
37+
38+
- The launcher copies your Peacock and Node.js files into the new managed location.
39+
- Any existing `peacock.service` is replaced with the launcher-managed service definition.
40+
- If the old service was enabled or running, that state is restored after migration.
41+
- Old `PeacockPatcher.exe` and `WineLaunch.bat` files are removed from detected game folders.
42+
- After migration, switch to **ZHMModSDK + OnlineTools** for patching. Do not keep using the old batch-file injection flow.
43+
44+
See [MIGRATION.md](MIGRATION.md) for the full migration checklist.
3245

3346
## Navigation
3447

@@ -37,7 +50,6 @@ A TUI (Terminal User Interface) application for managing [Peacock](https://thepe
3750
| `` `` | Move between menu items |
3851
| `Enter` | Select / confirm |
3952
| `Esc` | Go back |
40-
| `q` | Quit (from main menu) |
4153

4254
## Connecting to Peacock
4355

@@ -117,7 +129,7 @@ cargo appimage
117129

118130
## Legacy Setup
119131

120-
The old shell-script-based setup files are preserved in the [`legacy/`](legacy/) directory for reference. The launcher includes a migration wizard to move an existing legacy install to the new location.
132+
The old shell-script-based setup files are preserved in the [`legacy/`](legacy/) directory for reference. The launcher includes a migration wizard to move an existing legacy install to the new location, and the recommended path is documented in [MIGRATION.md](MIGRATION.md).
121133

122134

123135
## License

launcher/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

launcher/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "peacock-launcher"
3-
version = "0.1.0"
3+
version = "0.0.0"
44
edition = "2024"
55

66
[dependencies]

launcher/src/app.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use tokio::sync::mpsc;
44

55
use crate::core::config::Config;
66
use crate::core::game_detect::GameInstall;
7-
use crate::core::migration::LegacyInstall;
7+
use crate::core::launcher::LauncherStatus;
8+
use crate::core::migration::{LegacyInstall, MigrationResult};
89
use crate::core::node::NodeStatus;
910
use crate::core::options::PeacockOption;
1011
use crate::core::peacock::PeacockStatus;
@@ -39,8 +40,12 @@ pub enum AppMessage {
3940
ConfigUpdated(Config),
4041
/// Peacock status fetched asynchronously
4142
PeacockStatusLoaded(PeacockStatus),
43+
/// Launcher update check completed asynchronously
44+
LauncherStatusLoaded(LauncherStatus),
4245
/// Folder picked from the native file dialog (None if cancelled)
4346
FolderPicked(Option<PathBuf>),
47+
/// Migration completed and produced a detailed result.
48+
MigrationFinished(MigrationResult, Config),
4449
}
4550

4651
/// Which field is being edited in Settings.
@@ -71,6 +76,7 @@ pub struct App {
7176

7277
// Status data (cached, refreshed on demand)
7378
pub peacock_status: Option<PeacockStatus>,
79+
pub launcher_status: Option<LauncherStatus>,
7480
pub node_status: Option<NodeStatus>,
7581
pub service_status: Option<ServiceStatus>,
7682
pub game_installs: Vec<GameInstall>,
@@ -119,6 +125,7 @@ pub struct App {
119125
pub migration_confirmed: bool,
120126
pub migration_done: bool,
121127
pub migration_error: Option<String>,
128+
pub migration_result: Option<MigrationResult>,
122129
pub migration_remove_old: bool,
123130

124131
// Async message channel
@@ -144,6 +151,7 @@ pub enum MenuAction {
144151
Settings,
145152
Options,
146153
Migration,
154+
DownloadLauncher,
147155
Quit,
148156
}
149157

@@ -160,6 +168,7 @@ impl App {
160168
should_quit: false,
161169

162170
peacock_status: None,
171+
launcher_status: None,
163172
node_status: None,
164173
service_status: None,
165174
game_installs: Vec::new(),
@@ -201,6 +210,7 @@ impl App {
201210
migration_confirmed: false,
202211
migration_done: false,
203212
migration_error: None,
213+
migration_result: None,
204214
migration_remove_old: false,
205215

206216
msg_tx,
@@ -265,6 +275,18 @@ impl App {
265275
});
266276
}
267277

278+
let download_label = match &self.launcher_status {
279+
Some(s) if s.update_available() => {
280+
"⬇ Download latest launcher (update available!)".into()
281+
}
282+
_ => "Download latest launcher".into(),
283+
};
284+
items.push(MenuItem {
285+
label: download_label,
286+
action: MenuAction::DownloadLauncher,
287+
enabled: true,
288+
});
289+
268290
items.push(MenuItem {
269291
label: "Quit".into(),
270292
action: MenuAction::Quit,
@@ -338,6 +360,10 @@ impl App {
338360
AppMessage::PeacockStatusLoaded(status) => {
339361
self.peacock_status = Some(status);
340362
}
363+
AppMessage::LauncherStatusLoaded(status) => {
364+
self.launcher_status = Some(status);
365+
self.rebuild_menu();
366+
}
341367
AppMessage::FolderPicked(path) => {
342368
if self.screen == Screen::Migration {
343369
if let Some(path) = path {
@@ -356,6 +382,12 @@ impl App {
356382
}
357383
}
358384
}
385+
AppMessage::MigrationFinished(result, config) => {
386+
self.task_running = false;
387+
self.config = config;
388+
self.migration_done = true;
389+
self.migration_result = Some(result);
390+
}
359391
}
360392
}
361393
}
@@ -402,6 +434,7 @@ impl App {
402434
self.migration_confirmed = false;
403435
self.migration_done = false;
404436
self.migration_error = None;
437+
self.migration_result = None;
405438
self.migration_remove_old = false;
406439
}
407440
Screen::MainMenu => {

0 commit comments

Comments
 (0)