Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
718eace492 | |||
ca77c609cd | |||
502ca7a4f2 | |||
7397fae6f4 | |||
a07958563a | |||
c80204579f | |||
11909e8502 | |||
8ec2cc6da2 | |||
14db7719a3 | |||
d03c5ee7cc | |||
704570d4a7 | |||
49b696c898 | |||
4e22ca8714 |
@@ -2,5 +2,5 @@
|
|||||||
Icon = "Icon.png"
|
Icon = "Icon.png"
|
||||||
Name = "EpochSilicon"
|
Name = "EpochSilicon"
|
||||||
ID = "com.burkey.epochsilicon"
|
ID = "com.burkey.epochsilicon"
|
||||||
Version = "1.0.1"
|
Version = "1.0.9"
|
||||||
Build = 19
|
Build = 31
|
||||||
|
6
Makefile
6
Makefile
@@ -19,11 +19,7 @@ build: build-dev
|
|||||||
build-release:
|
build-release:
|
||||||
@rm -rf ./EpochSilicon.app
|
@rm -rf ./EpochSilicon.app
|
||||||
@echo "Building optimized release version..."
|
@echo "Building optimized release version..."
|
||||||
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build \
|
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -trimpath -tags=release -o epochsilicon .
|
||||||
-ldflags="-s -w" \
|
|
||||||
-trimpath \
|
|
||||||
-tags=release \
|
|
||||||
-o epochsilicon .
|
|
||||||
@echo "Packaging with fyne..."
|
@echo "Packaging with fyne..."
|
||||||
GOOS=darwin GOARCH=arm64 fyne package --release --executable epochsilicon
|
GOOS=darwin GOARCH=arm64 fyne package --release --executable epochsilicon
|
||||||
@echo "Copying additional resources to app bundle..."
|
@echo "Copying additional resources to app bundle..."
|
||||||
|
34
README.md
34
README.md
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
A user-friendly launcher for Project Epoch on Apple Silicon Macs, with one-click patching of winerosetta, rosettax87 and d9vk.
|
A user-friendly launcher for Project Epoch on Apple Silicon Macs, with one-click patching of winerosetta, rosettax87 and d9vk.
|
||||||
|
|
||||||
|
**This software is currently in active development, there WILL be bugs and constant updates as Epoch rolls out**
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* **Apple Silicon Compatibility:** Runs 32-bit DirectX9 World of Warcraft (v3.3.5a) on M1/M2/M3/M4 Macs without "illegal instruction" errors.
|
* **Apple Silicon Compatibility:** Runs 32-bit DirectX9 World of Warcraft (v3.3.5a) on M1/M2/M3/M4 Macs without "illegal instruction" errors.
|
||||||
@@ -16,7 +18,7 @@ A user-friendly launcher for Project Epoch on Apple Silicon Macs, with one-click
|
|||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
- For one tester, it took up to a minute for Wow to start after hitting the "Play" button. This is currently being investigated.
|
- For some users, it can take up to a minute for Wow to start after hitting the "Play" button. A possible fix is described in the Troubleshooting section, please let @Battlehammer know on the Epoch discord if this works for you
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -48,23 +50,37 @@ Before you begin, ensure you have the following:
|
|||||||
* Click "Patch Epoch".
|
* Click "Patch Epoch".
|
||||||
* Click "Patch CrossOver".
|
* Click "Patch CrossOver".
|
||||||
* Status indicators will turn green once patching is successful for each.
|
* Status indicators will turn green once patching is successful for each.
|
||||||
6. **Start RosettaX87 Service**:
|
5. **Start RosettaX87 Service**:
|
||||||
* Click "Start Service" and enter your sudo password when prompted.
|
* Click "Start Service" and enter your sudo password when prompted.
|
||||||
* This will run the RosettaX87 service in the background and is required for launching the game.
|
* This will run the RosettaX87 service in the background and is required for launching the game.
|
||||||
* The service will automatically stop when you close the launcher.
|
* The service will automatically stop when you close the launcher.
|
||||||
7. **Configure Options (Optional)**:
|
6. **Configure Options (Optional)**:
|
||||||
* **Enable Metal Hud**: Shows FPS counter in-game.
|
* **Enable Metal Hud**: Shows FPS counter in-game.
|
||||||
* **Show Terminal**: Displays terminal output during game launch for debugging.
|
* **Advanced Logging**: Enables debugging logs, located in `$HOME/Library/Application Support/EpochSilicon`. Enable this setting if you are generating logs for troubleshooting
|
||||||
8. **Launch Game**:
|
7. **Launch Game**:
|
||||||
* Once both paths are set, both components are patched, and the RosettaX87 service is running, the "Launch Game" button will become active. Click it.
|
* Once both paths are set, both components are patched, and the RosettaX87 service is running, the "Launch Game" button will become active. Click it.
|
||||||
9. **Enjoy**: Experience a VM free, smoother Project Epoch on your Apple Silicon Mac!
|
8. **Enjoy**: Experience a VM free, smoother Project Epoch on your Apple Silicon Mac!
|
||||||
|
|
||||||
## Troubleshooting / FAQ
|
## Troubleshooting / FAQ
|
||||||
|
|
||||||
|
### The game closes instantly when I try to login
|
||||||
|
|
||||||
|
Make sure you login to Epoch with your username, not your email. Using your email will cause the game to close with no error message
|
||||||
|
|
||||||
### The Patch Epoch step is taking forever
|
### The Patch Epoch step is taking forever
|
||||||
|
|
||||||
The initial patch download is quite large and can take a while if your internet is slow. The app will tell you when it's done.
|
The initial patch download is quite large and can take a while if your internet is slow. The app will tell you when it's done.
|
||||||
|
|
||||||
|
### After I click Play, the game takes a minute to load
|
||||||
|
|
||||||
|
This appears to be a problem with using a built-in version of `rosettax87`. In order to fix this, you must compile it yourself.
|
||||||
|
|
||||||
|
1. Install Xcode command line tools by opening a terminal and typing `xcode-select --install` and following the prompts
|
||||||
|
2. Setup [Homebrew](https://brew.sh/) if you don't have it already
|
||||||
|
3. Install Cmake by opening a terminal and enter `brew install cmake`. Cmake must be installed through Homebrew
|
||||||
|
3. Run EpochSilicon and click the `Troubleshooting` button
|
||||||
|
4. Find the line that says `Build Rosettax87 locally` and click the `Build` button, following the prompts
|
||||||
|
|
||||||
### My resolution is super blown up and I can't see the whole screen
|
### My resolution is super blown up and I can't see the whole screen
|
||||||
|
|
||||||
Wine does that on first launch if you have a large widescreen monitor.
|
Wine does that on first launch if you have a large widescreen monitor.
|
||||||
@@ -108,9 +124,7 @@ TBD
|
|||||||
|
|
||||||
## Bundled Binaries
|
## Bundled Binaries
|
||||||
|
|
||||||
The `rosettax87` and `winerosetta` components included in this application are precompiled for convenience. If you prefer, you can compile them yourself by following the instructions provided by Lifeisawful on the official repositories:
|
The `rosettax87` and `winerosetta` components included in this application are precompiled for convenience. You can compile them yourself by following the instructions provided above in the Troubleshooting section
|
||||||
[https://github.com/Lifeisawful/winerosetta](https://github.com/Lifeisawful/winerosetta)
|
|
||||||
[https://github.com/Lifeisawful/rosettax87](https://github.com/Lifeisawful/rosettax87)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
@@ -124,5 +138,5 @@ All credit for the core translation layer `winerosetta` and `rosettax87` goes to
|
|||||||
|
|
||||||
[https://github.com/Lifeisawful/rosettax87](https://github.com/Lifeisawful/rosettax87)
|
[https://github.com/Lifeisawful/rosettax87](https://github.com/Lifeisawful/rosettax87)
|
||||||
|
|
||||||
EpochSilicon is a fork of [https://turtlesilicon.github.io/](TurtleSilicon), credit for the base of the application goes to tairasu.
|
EpochSilicon is a fork of [https://turtlesilicon.github.io/](TurtleSilicon), credit for the base of the application goes to [**@tairasu**](https://github.com/tairasu)
|
||||||
|
|
||||||
|
15
go.mod
15
go.mod
@@ -8,6 +8,7 @@ require (
|
|||||||
fyne.io/fyne/v2 v2.6.1
|
fyne.io/fyne/v2 v2.6.1
|
||||||
git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b
|
git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b
|
||||||
github.com/Masterminds/semver/v3 v3.4.0
|
github.com/Masterminds/semver/v3 v3.4.0
|
||||||
|
github.com/go-git/go-git/v6 v6.0.0-20250725064440-209d7ec3c0b2
|
||||||
github.com/rs/zerolog v1.34.0
|
github.com/rs/zerolog v1.34.0
|
||||||
github.com/zalando/go-keyring v0.2.6
|
github.com/zalando/go-keyring v0.2.6
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
@@ -16,36 +17,50 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
al.essio.dev/pkg/shellescape v1.6.0 // indirect
|
al.essio.dev/pkg/shellescape v1.6.0 // indirect
|
||||||
|
dario.cat/mergo v1.0.1 // indirect
|
||||||
fyne.io/systray v1.11.0 // indirect
|
fyne.io/systray v1.11.0 // indirect
|
||||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||||
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
|
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||||
|
github.com/cloudflare/circl v1.6.1 // indirect
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||||
github.com/danieljoos/wincred v1.2.2 // indirect
|
github.com/danieljoos/wincred v1.2.2 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
github.com/fredbi/uri v1.1.0 // indirect
|
github.com/fredbi/uri v1.1.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||||
github.com/fyne-io/gl-js v0.2.0 // indirect
|
github.com/fyne-io/gl-js v0.2.0 // indirect
|
||||||
github.com/fyne-io/glfw-js v0.3.0 // indirect
|
github.com/fyne-io/glfw-js v0.3.0 // indirect
|
||||||
github.com/fyne-io/image v0.1.1 // indirect
|
github.com/fyne-io/image v0.1.1 // indirect
|
||||||
github.com/fyne-io/oksvg v0.1.0 // indirect
|
github.com/fyne-io/oksvg v0.1.0 // indirect
|
||||||
|
github.com/go-git/gcfg/v2 v2.0.2 // indirect
|
||||||
|
github.com/go-git/go-billy/v6 v6.0.0-20250627091229-31e2a16eef30 // indirect
|
||||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728 // indirect
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728 // indirect
|
||||||
github.com/go-text/render v0.2.0 // indirect
|
github.com/go-text/render v0.2.0 // indirect
|
||||||
github.com/go-text/typesetting v0.3.0 // indirect
|
github.com/go-text/typesetting v0.3.0 // indirect
|
||||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||||
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||||
github.com/hack-pad/go-indexeddb v0.3.2 // indirect
|
github.com/hack-pad/go-indexeddb v0.3.2 // indirect
|
||||||
github.com/hack-pad/safejs v0.1.1 // indirect
|
github.com/hack-pad/safejs v0.1.1 // indirect
|
||||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
|
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
|
||||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect
|
github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect
|
||||||
|
github.com/pjbgf/sha1cd v0.4.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/rymdport/portal v0.4.2 // indirect
|
github.com/rymdport/portal v0.4.2 // indirect
|
||||||
|
github.com/sergi/go-diff v1.4.0 // indirect
|
||||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
||||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
||||||
github.com/stretchr/testify v1.10.0 // indirect
|
github.com/stretchr/testify v1.10.0 // indirect
|
||||||
github.com/yuin/goldmark v1.7.13 // indirect
|
github.com/yuin/goldmark v1.7.13 // indirect
|
||||||
|
golang.org/x/crypto v0.40.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b // indirect
|
||||||
golang.org/x/image v0.29.0 // indirect
|
golang.org/x/image v0.29.0 // indirect
|
||||||
golang.org/x/net v0.42.0 // indirect
|
golang.org/x/net v0.42.0 // indirect
|
||||||
golang.org/x/sys v0.34.0 // indirect
|
golang.org/x/sys v0.34.0 // indirect
|
||||||
|
61
go.sum
61
go.sum
@@ -1,5 +1,7 @@
|
|||||||
al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA=
|
al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA=
|
||||||
al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
|
al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
|
||||||
|
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||||
|
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
fyne.io/fyne/v2 v2.6.1 h1:kjPJD4/rBS9m2nHJp+npPSuaK79yj6ObMTuzR6VQ1Is=
|
fyne.io/fyne/v2 v2.6.1 h1:kjPJD4/rBS9m2nHJp+npPSuaK79yj6ObMTuzR6VQ1Is=
|
||||||
fyne.io/fyne/v2 v2.6.1/go.mod h1:YZt7SksjvrSNJCwbWFV32WON3mE1Sr7L41D29qMZ/lU=
|
fyne.io/fyne/v2 v2.6.1/go.mod h1:YZt7SksjvrSNJCwbWFV32WON3mE1Sr7L41D29qMZ/lU=
|
||||||
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
|
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
|
||||||
@@ -10,12 +12,29 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg
|
|||||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
|
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||||
|
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
|
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||||
|
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=
|
github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=
|
||||||
github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=
|
github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||||
|
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||||
|
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||||
|
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||||
github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
|
github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
|
||||||
@@ -30,6 +49,16 @@ github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA=
|
|||||||
github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM=
|
github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM=
|
||||||
github.com/fyne-io/oksvg v0.1.0 h1:7EUKk3HV3Y2E+qypp3nWqMXD7mum0hCw2KEGhI1fnBw=
|
github.com/fyne-io/oksvg v0.1.0 h1:7EUKk3HV3Y2E+qypp3nWqMXD7mum0hCw2KEGhI1fnBw=
|
||||||
github.com/fyne-io/oksvg v0.1.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
|
github.com/fyne-io/oksvg v0.1.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
|
||||||
|
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||||
|
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||||
|
github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo=
|
||||||
|
github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs=
|
||||||
|
github.com/go-git/go-billy/v6 v6.0.0-20250627091229-31e2a16eef30 h1:4KqVJTL5eanN8Sgg3BV6f2/QzfZEFbCd+rTak1fGRRA=
|
||||||
|
github.com/go-git/go-billy/v6 v6.0.0-20250627091229-31e2a16eef30/go.mod h1:snwvGrbywVFy2d6KJdQ132zapq4aLyzLMgpo79XdEfM=
|
||||||
|
github.com/go-git/go-git-fixtures/v5 v5.1.0 h1:b8cWxDLTk0s09Ihm9x1HvNGUzxUVlRwIH7EAM0gGDKg=
|
||||||
|
github.com/go-git/go-git-fixtures/v5 v5.1.0/go.mod h1:CdmU0oQeDuy4Xh8V0i9Ym+vsTkgDDPKEiofBFEVT+aE=
|
||||||
|
github.com/go-git/go-git/v6 v6.0.0-20250725064440-209d7ec3c0b2 h1:F7u1fj/kU3+amqn25xkiMn77oh7hw0Ac7fKnZh7lqeA=
|
||||||
|
github.com/go-git/go-git/v6 v6.0.0-20250725064440-209d7ec3c0b2/go.mod h1:gI6xSrrkXH4EKP38iovrsY2EYf2XDU3DrIZRshlNDm0=
|
||||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
||||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728 h1:RkGhqHxEVAvPM0/R+8g7XRwQnHatO0KAuVcwHo8q9W8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728 h1:RkGhqHxEVAvPM0/R+8g7XRwQnHatO0KAuVcwHo8q9W8=
|
||||||
@@ -43,6 +72,8 @@ github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h
|
|||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||||
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
|
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
|
||||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||||
@@ -56,6 +87,13 @@ github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade/go.mod h1:ZDX
|
|||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
||||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
@@ -69,30 +107,40 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6
|
|||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ=
|
github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE=
|
github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||||
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||||
github.com/rymdport/portal v0.4.2 h1:7jKRSemwlTyVHHrTGgQg7gmNPJs88xkbKcIL3NlcmSU=
|
github.com/rymdport/portal v0.4.2 h1:7jKRSemwlTyVHHrTGgQg7gmNPJs88xkbKcIL3NlcmSU=
|
||||||
github.com/rymdport/portal v0.4.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
github.com/rymdport/portal v0.4.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
||||||
|
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||||
|
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
|
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
|
||||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
|
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
|
||||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
|
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
|
||||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
|
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA=
|
github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA=
|
||||||
github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||||
github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s=
|
github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s=
|
||||||
github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI=
|
github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI=
|
||||||
|
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||||
|
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||||
|
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b h1:QoALfVG9rhQ/M7vYDScfPdWjGL9dlsVVM5VGh7aKoAA=
|
||||||
|
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
|
||||||
golang.org/x/image v0.29.0 h1:HcdsyR4Gsuys/Axh0rDEmlBmB68rW1U9BUdB3UVHsas=
|
golang.org/x/image v0.29.0 h1:HcdsyR4Gsuys/Axh0rDEmlBmB68rW1U9BUdB3UVHsas=
|
||||||
golang.org/x/image v0.29.0/go.mod h1:RVJROnf3SLK8d26OW91j4FrIHGbsJ8QnbEocVTOWQDA=
|
golang.org/x/image v0.29.0/go.mod h1:RVJROnf3SLK8d26OW91j4FrIHGbsJ8QnbEocVTOWQDA=
|
||||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||||
@@ -102,14 +150,19 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||||
|
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
|
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
|
||||||
|
8
main.go
8
main.go
@@ -11,19 +11,19 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appVersion = semver.MustParse("1.0.1")
|
const appVersion = "1.0.9"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.SetupLogging()
|
log.SetupLogging()
|
||||||
|
|
||||||
PEApp := app.NewWithID("com.burkey.epochsilicon")
|
PEApp := app.NewWithID("com.burkey.epochsilicon")
|
||||||
PEWindow := PEApp.NewWindow("EpochSilicon v" + appVersion.String())
|
PEWindow := PEApp.NewWindow("EpochSilicon v" + appVersion)
|
||||||
PEWindow.Resize(fyne.NewSize(650, 500))
|
PEWindow.Resize(fyne.NewSize(650, 500))
|
||||||
PEWindow.SetFixedSize(true)
|
PEWindow.SetFixedSize(true)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
prefs, _ := utils.LoadPrefs()
|
prefs, _ := utils.LoadPrefs()
|
||||||
updateInfo, updateAvailable, err := utils.CheckForUpdateWithAssets(appVersion)
|
updateInfo, updateAvailable, err := utils.CheckForUpdateWithAssets(semver.MustParse(appVersion))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("Failed to check for updates: %v", err)
|
log.Debugf("Failed to check for updates: %v", err)
|
||||||
return
|
return
|
||||||
@@ -44,7 +44,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show enhanced update dialog
|
// Show enhanced update dialog
|
||||||
ui.ShowUpdateDialog(updateInfo, appVersion.String(), PEWindow)
|
ui.ShowUpdateDialog(updateInfo, appVersion, PEWindow)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
content := ui.CreateUI(PEWindow)
|
content := ui.CreateUI(PEWindow)
|
||||||
|
@@ -188,7 +188,7 @@ func continueLaunch(myWindow fyne.Window, wowExePath string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare environment variables
|
// Prepare environment variables
|
||||||
envVars := fmt.Sprintf(`WINEDLLOVERRIDES="d3d9=n,b" MTL_HUD_ENABLED=%s MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=1 DXVK_ASYNC=1`, mtlHudValue)
|
envVars := fmt.Sprintf(`WINEDLLOVERRIDES="d3d9=n,b" MTL_HUD_ENABLED=%s DXVK_ASYNC=1`, mtlHudValue)
|
||||||
if CustomEnvVars != "" {
|
if CustomEnvVars != "" {
|
||||||
envVars = CustomEnvVars + " " + envVars
|
envVars = CustomEnvVars + " " + envVars
|
||||||
}
|
}
|
||||||
|
@@ -10,8 +10,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logger zerolog.Logger
|
logger zerolog.Logger
|
||||||
wineLogger zerolog.Logger
|
Writer io.Writer
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupLogging() {
|
func SetupLogging() {
|
||||||
@@ -22,30 +22,14 @@ func SetupLogging() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var mw io.Writer
|
|
||||||
l := createLogWriter(path, 10, 3)
|
l := createLogWriter(path, 10, 3)
|
||||||
if l != nil {
|
if l != nil {
|
||||||
mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout}, l)
|
Writer = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout}, l)
|
||||||
} else {
|
} else {
|
||||||
mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout})
|
Writer = os.Stdout
|
||||||
}
|
}
|
||||||
logger = zerolog.New(mw).With().Timestamp().Logger()
|
logger = zerolog.New(Writer).With().Timestamp().Logger()
|
||||||
SetLevelInfo()
|
SetLevelInfo()
|
||||||
|
|
||||||
// Wine logs
|
|
||||||
wineLogPath, err := getWineLogfilePath()
|
|
||||||
if err != nil {
|
|
||||||
Errorf("Failed to get wine log path: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
l = createLogWriter(wineLogPath, 25, 1)
|
|
||||||
if l != nil {
|
|
||||||
mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout}, l)
|
|
||||||
} else {
|
|
||||||
mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout})
|
|
||||||
}
|
|
||||||
wineLogger = zerolog.New(mw).With().Timestamp().Logger()
|
|
||||||
wineLogger.Level(zerolog.InfoLevel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLogWriter(path string, maxSize int, maxBackups int) io.Writer {
|
func createLogWriter(path string, maxSize int, maxBackups int) io.Writer {
|
||||||
@@ -134,9 +118,9 @@ func Panicf(format string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WineLoggerStdout(msg string) {
|
func WineLoggerStdout(msg string) {
|
||||||
wineLogger.Info().Msgf("STDOUT: %s", msg)
|
logger.Info().Msgf("WINE STDOUT: %s", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func WineLoggerStderr(msg string) {
|
func WineLoggerStderr(msg string) {
|
||||||
wineLogger.Info().Msgf("STDERR: %s", msg)
|
logger.Info().Msgf("WINE STDERR: %s", msg)
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.burkey.co/eburk/epochcli/pkg/epoch"
|
"git.burkey.co/eburk/epochcli/pkg/epoch"
|
||||||
|
"github.com/go-git/go-git/v6"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -20,6 +21,11 @@ import (
|
|||||||
"fyne.io/fyne/v2/dialog"
|
"fyne.io/fyne/v2/dialog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CmakePath = "/opt/homebrew/bin/cmake"
|
||||||
|
ClangPath = "/usr/bin/clang"
|
||||||
|
)
|
||||||
|
|
||||||
func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) {
|
func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) {
|
||||||
log.Debug("Patch Epoch clicked")
|
log.Debug("Patch Epoch clicked")
|
||||||
if paths.EpochPath == "" {
|
if paths.EpochPath == "" {
|
||||||
@@ -84,29 +90,15 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) {
|
|||||||
log.Debugf("Successfully copied %s to %s", resourceName, destPath)
|
log.Debugf("Successfully copied %s to %s", resourceName, destPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Preparing rosettax87 directory at: %s", targetRosettaX87Dir)
|
if _, err := os.Stat(filepath.Join(paths.EpochPath, "rosettax87")); err == nil {
|
||||||
if err := os.RemoveAll(targetRosettaX87Dir); err != nil {
|
log.Debugf("rosettax87 path already exists, skipping copy")
|
||||||
log.Debugf("Warning: could not remove existing rosettax87 folder '%s': %v", targetRosettaX87Dir, err)
|
} else {
|
||||||
}
|
log.Debugf("Preparing rosettax87 directory at: %s", targetRosettaX87Dir)
|
||||||
if err := os.MkdirAll(targetRosettaX87Dir, 0755); err != nil {
|
if err := os.RemoveAll(targetRosettaX87Dir); err != nil {
|
||||||
errMsg := fmt.Sprintf("failed to create directory %s: %v", targetRosettaX87Dir, err)
|
log.Debugf("Warning: could not remove existing rosettax87 folder '%s': %v", targetRosettaX87Dir, err)
|
||||||
dialog.ShowError(errors.New(errMsg), myWindow)
|
}
|
||||||
log.Debug(errMsg)
|
if err := os.MkdirAll(targetRosettaX87Dir, 0755); err != nil {
|
||||||
paths.PatchesAppliedEpoch = false
|
errMsg := fmt.Sprintf("failed to create directory %s: %v", targetRosettaX87Dir, err)
|
||||||
updateAllStatuses()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rosettaFilesToCopy := map[string]string{
|
|
||||||
"rosettax87/rosettax87": filepath.Join(targetRosettaX87Dir, "rosettax87"),
|
|
||||||
"rosettax87/libRuntimeRosettax87": filepath.Join(targetRosettaX87Dir, "libRuntimeRosettax87"),
|
|
||||||
}
|
|
||||||
|
|
||||||
for resourceName, destPath := range rosettaFilesToCopy {
|
|
||||||
log.Debugf("Processing rosetta resource: %s to %s", resourceName, destPath)
|
|
||||||
resource, err := fyne.LoadResourceFromPath(resourceName)
|
|
||||||
if err != nil {
|
|
||||||
errMsg := fmt.Sprintf("failed to open bundled resource %s: %v", resourceName, err)
|
|
||||||
dialog.ShowError(errors.New(errMsg), myWindow)
|
dialog.ShowError(errors.New(errMsg), myWindow)
|
||||||
log.Debug(errMsg)
|
log.Debug(errMsg)
|
||||||
paths.PatchesAppliedEpoch = false
|
paths.PatchesAppliedEpoch = false
|
||||||
@@ -114,40 +106,58 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
destinationFile, err := os.Create(destPath)
|
rosettaFilesToCopy := map[string]string{
|
||||||
if err != nil {
|
"rosettax87/rosettax87": filepath.Join(targetRosettaX87Dir, "rosettax87"),
|
||||||
errMsg := fmt.Sprintf("failed to create destination file %s: %v", destPath, err)
|
"rosettax87/libRuntimeRosettax87": filepath.Join(targetRosettaX87Dir, "libRuntimeRosettax87"),
|
||||||
dialog.ShowError(errors.New(errMsg), myWindow)
|
|
||||||
log.Debug(errMsg)
|
|
||||||
paths.PatchesAppliedEpoch = false
|
|
||||||
updateAllStatuses()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = io.Copy(destinationFile, bytes.NewReader(resource.Content()))
|
for resourceName, destPath := range rosettaFilesToCopy {
|
||||||
if err != nil {
|
log.Debugf("Processing rosetta resource: %s to %s", resourceName, destPath)
|
||||||
destinationFile.Close()
|
resource, err := fyne.LoadResourceFromPath(resourceName)
|
||||||
errMsg := fmt.Sprintf("failed to copy bundled resource %s to %s: %v", resourceName, destPath, err)
|
if err != nil {
|
||||||
dialog.ShowError(errors.New(errMsg), myWindow)
|
errMsg := fmt.Sprintf("failed to open bundled resource %s: %v", resourceName, err)
|
||||||
log.Debug(errMsg)
|
|
||||||
paths.PatchesAppliedEpoch = false
|
|
||||||
updateAllStatuses()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
destinationFile.Close()
|
|
||||||
|
|
||||||
if filepath.Base(destPath) == "rosettax87" {
|
|
||||||
log.Debugf("Setting execute permission for %s", destPath)
|
|
||||||
if err := os.Chmod(destPath, 0755); err != nil {
|
|
||||||
errMsg := fmt.Sprintf("failed to set execute permission for %s: %v", destPath, err)
|
|
||||||
dialog.ShowError(errors.New(errMsg), myWindow)
|
dialog.ShowError(errors.New(errMsg), myWindow)
|
||||||
log.Debug(errMsg)
|
log.Debug(errMsg)
|
||||||
paths.PatchesAppliedEpoch = false
|
paths.PatchesAppliedEpoch = false
|
||||||
updateAllStatuses()
|
updateAllStatuses()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destinationFile, err := os.Create(destPath)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Sprintf("failed to create destination file %s: %v", destPath, err)
|
||||||
|
dialog.ShowError(errors.New(errMsg), myWindow)
|
||||||
|
log.Debug(errMsg)
|
||||||
|
paths.PatchesAppliedEpoch = false
|
||||||
|
updateAllStatuses()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(destinationFile, bytes.NewReader(resource.Content()))
|
||||||
|
if err != nil {
|
||||||
|
destinationFile.Close()
|
||||||
|
errMsg := fmt.Sprintf("failed to copy bundled resource %s to %s: %v", resourceName, destPath, err)
|
||||||
|
dialog.ShowError(errors.New(errMsg), myWindow)
|
||||||
|
log.Debug(errMsg)
|
||||||
|
paths.PatchesAppliedEpoch = false
|
||||||
|
updateAllStatuses()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
destinationFile.Close()
|
||||||
|
|
||||||
|
if filepath.Base(destPath) == "rosettax87" {
|
||||||
|
log.Debugf("Setting execute permission for %s", destPath)
|
||||||
|
if err := os.Chmod(destPath, 0755); err != nil {
|
||||||
|
errMsg := fmt.Sprintf("failed to set execute permission for %s: %v", destPath, err)
|
||||||
|
dialog.ShowError(errors.New(errMsg), myWindow)
|
||||||
|
log.Debug(errMsg)
|
||||||
|
paths.PatchesAppliedEpoch = false
|
||||||
|
updateAllStatuses()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Debugf("Successfully copied %s to %s", resourceName, destPath)
|
||||||
}
|
}
|
||||||
log.Debugf("Successfully copied %s to %s", resourceName, destPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Checking dlls.txt file at: %s", dllsTextFile)
|
log.Debugf("Checking dlls.txt file at: %s", dllsTextFile)
|
||||||
@@ -266,7 +276,7 @@ func PatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) {
|
|||||||
if strings.Contains(err.Error(), "operation not permitted") {
|
if strings.Contains(err.Error(), "operation not permitted") {
|
||||||
errMsg += "\n\nSolution: Open System Settings, go to Privacy & Security > App Management, and enable EpochSilicon."
|
errMsg += "\n\nSolution: Open System Settings, go to Privacy & Security > App Management, and enable EpochSilicon."
|
||||||
}
|
}
|
||||||
dialog.ShowError(fmt.Errorf(errMsg), myWindow)
|
dialog.ShowError(fmt.Errorf("%s", errMsg), myWindow)
|
||||||
paths.PatchesAppliedCrossOver = false
|
paths.PatchesAppliedCrossOver = false
|
||||||
updateAllStatuses()
|
updateAllStatuses()
|
||||||
return
|
return
|
||||||
@@ -462,3 +472,42 @@ func isConfigSettingCorrect(configText, setting, expectedValue string) bool {
|
|||||||
currentValue := matches[1]
|
currentValue := matches[1]
|
||||||
return currentValue == expectedValue
|
return currentValue == expectedValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BuildRosetta() (string, string, error) {
|
||||||
|
tmpDir, err := os.MkdirTemp("", "rosettax87")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("failed to create temporary directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedDir := filepath.Join(tmpDir, "rosettax87")
|
||||||
|
|
||||||
|
_, err = git.PlainClone(clonedDir, &git.CloneOptions{
|
||||||
|
URL: "https://github.com/fputs/rosettax87",
|
||||||
|
Progress: os.Stdout,
|
||||||
|
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
|
||||||
|
SingleBranch: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("failed to clone repository: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(CmakePath, "-B", "build")
|
||||||
|
cmd.Dir = clonedDir
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("failed to create build files: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command(CmakePath, "--build", "build")
|
||||||
|
cmd.Dir = clonedDir
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("failed to build rosettax87: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildDir := filepath.Join(clonedDir, "build")
|
||||||
|
rosettax87Path := filepath.Join(buildDir, "rosettax87")
|
||||||
|
librosettaPath := filepath.Join(buildDir, "libRuntimeRosettax87")
|
||||||
|
|
||||||
|
return rosettax87Path, librosettaPath, nil
|
||||||
|
}
|
||||||
|
15
pkg/patching/patching_test.go
Normal file
15
pkg/patching/patching_test.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package patching
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuildRosetta(t *testing.T) {
|
||||||
|
rp, lp, err := BuildRosetta()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
fmt.Println("exe path:", rp)
|
||||||
|
fmt.Println("lib path:", lp)
|
||||||
|
}
|
@@ -137,7 +137,7 @@ func createBottomBar(myWindow fyne.Window) fyne.CanvasObject {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Git button
|
// Git button
|
||||||
gitButton := widget.NewButton("Source Code", func() {
|
gitButton := widget.NewButton("Website", func() {
|
||||||
githubURL := "https://git.burkey.co/eburk/epochsilicon"
|
githubURL := "https://git.burkey.co/eburk/epochsilicon"
|
||||||
parsedURL, err := url.Parse(githubURL)
|
parsedURL, err := url.Parse(githubURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -1,15 +1,18 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"epochsilicon/pkg/log"
|
||||||
|
"epochsilicon/pkg/patching"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/container"
|
"fyne.io/fyne/v2/container"
|
||||||
"fyne.io/fyne/v2/dialog"
|
"fyne.io/fyne/v2/dialog"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"howett.net/plist"
|
"howett.net/plist"
|
||||||
|
|
||||||
@@ -198,12 +201,84 @@ func showTroubleshootingPopup() {
|
|||||||
}, currentWindow).Show()
|
}, currentWindow).Show()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// --- Build Rosettax87 Locally ---
|
||||||
|
buildRosettaButton = widget.NewButton("Build", func() {
|
||||||
|
msg := "Building rosettax87 on your computer may speed up launch times. This requires xcode-commandline-tools and Cmake to be installed. See the instructions at https://git.burkey.co/eburk/epochsilicon/README.md\n\n"
|
||||||
|
msg += "Click YES to start the build process. This could take up to a minute depending on the the speed of your Mac. A popup will let you know when the files have been built and copied to the right place."
|
||||||
|
dialog.NewConfirm("Build rosettax87", msg, func(confirm bool) {
|
||||||
|
if confirm {
|
||||||
|
// Check for dependencies
|
||||||
|
if err := exec.Command(patching.ClangPath, "--version").Run(); err != nil {
|
||||||
|
m := fmt.Errorf("xcode command line tools are not installed on your computer. Click the Website button in the app and read the instructions on building rosettax87 before trying again. Error: %v", err)
|
||||||
|
log.Error(m.Error())
|
||||||
|
dialog.ShowError(m, currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := exec.Command(patching.CmakePath, "--version").Run(); err != nil {
|
||||||
|
m := fmt.Errorf("Cmake is not installed on your computer. Click the Website button in the app and read the instructions on building rosettax87 before trying again. Error: %v", err)
|
||||||
|
log.Error(m.Error())
|
||||||
|
dialog.ShowError(m, currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
xPath, lPath, err := patching.BuildRosetta()
|
||||||
|
if err != nil {
|
||||||
|
m := fmt.Errorf("Error building rosettax87: %v\nClick Website for information on getting help", err)
|
||||||
|
log.Error(m.Error())
|
||||||
|
dialog.ShowError(m, currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d := filepath.Join(paths.EpochPath, "rosettax87")
|
||||||
|
if err = os.RemoveAll(d); err != nil {
|
||||||
|
m := fmt.Errorf("Error removing existing rosettax87 directory: %v", err)
|
||||||
|
log.Error(m.Error())
|
||||||
|
dialog.ShowError(m, currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = os.MkdirAll(d, 0755); err != nil {
|
||||||
|
m := fmt.Errorf("Error creating existing rosettax87 directory: %v", err)
|
||||||
|
log.Error(m.Error())
|
||||||
|
dialog.ShowError(m, currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pathMap := map[string]string{
|
||||||
|
xPath: filepath.Join(paths.EpochPath, "rosettax87", "rosettax87"),
|
||||||
|
lPath: filepath.Join(paths.EpochPath, "rosettax87", "libRuntimeRosettax87"),
|
||||||
|
}
|
||||||
|
|
||||||
|
for srcPath, destPath := range pathMap {
|
||||||
|
fBytes, err := os.ReadFile(srcPath)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Sprintf("failed to read source file %s: %v", srcPath, err)
|
||||||
|
dialog.ShowError(errors.New(errMsg), currentWindow)
|
||||||
|
log.Debug(errMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(destPath, fBytes, 0755)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Sprintf("failed to write file %s: %v", destPath, err)
|
||||||
|
dialog.ShowError(errors.New(errMsg), currentWindow)
|
||||||
|
log.Debug(errMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debugf("Successfully copied %s to %s", srcPath, destPath)
|
||||||
|
}
|
||||||
|
dialog.ShowInformation("Build Successful", "Rosettax87 installed successfully.", currentWindow)
|
||||||
|
}
|
||||||
|
}, currentWindow).Show()
|
||||||
|
})
|
||||||
|
|
||||||
troubleshootingTitle := widget.NewLabel("Troubleshooting")
|
troubleshootingTitle := widget.NewLabel("Troubleshooting")
|
||||||
troubleshootingTitle.TextStyle = fyne.TextStyle{Bold: true}
|
troubleshootingTitle.TextStyle = fyne.TextStyle{Bold: true}
|
||||||
|
|
||||||
rowCrossover := container.NewBorder(nil, nil, widget.NewLabel("CrossOver version:"), crossoverStatusShort, nil)
|
rowCrossover := container.NewBorder(nil, nil, widget.NewLabel("CrossOver version:"), crossoverStatusShort, nil)
|
||||||
rowWDB := container.NewBorder(nil, nil, widget.NewLabel("Delete WDB directory (cache):"), wdbDeleteButton, nil)
|
rowWDB := container.NewBorder(nil, nil, widget.NewLabel("Delete WDB directory (cache):"), wdbDeleteButton, nil)
|
||||||
rowWine := container.NewBorder(nil, nil, widget.NewLabel("Delete Wine prefixes (~/.wine & Epoch/.wine):"), wineDeleteButton, nil)
|
rowWine := container.NewBorder(nil, nil, widget.NewLabel("Delete Wine prefixes (~/.wine & Epoch/.wine):"), wineDeleteButton, nil)
|
||||||
|
rowBuildRosetta := container.NewBorder(nil, nil, widget.NewLabel("Build Rosettax87 locally:"), buildRosettaButton, nil)
|
||||||
appMgmtNote := widget.NewLabel("Please ensure EpochSilicon is enabled in System Settings > Privacy & Security > App Management.")
|
appMgmtNote := widget.NewLabel("Please ensure EpochSilicon is enabled in System Settings > Privacy & Security > App Management.")
|
||||||
appMgmtNote.Wrapping = fyne.TextWrapWord
|
appMgmtNote.Wrapping = fyne.TextWrapWord
|
||||||
appMgmtNote.TextStyle = fyne.TextStyle{Italic: true}
|
appMgmtNote.TextStyle = fyne.TextStyle{Italic: true}
|
||||||
@@ -215,6 +290,7 @@ func showTroubleshootingPopup() {
|
|||||||
crossoverStatusDetail,
|
crossoverStatusDetail,
|
||||||
rowWDB,
|
rowWDB,
|
||||||
rowWine,
|
rowWine,
|
||||||
|
rowBuildRosetta,
|
||||||
appMgmtNote,
|
appMgmtNote,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -120,14 +120,12 @@ func updateEpochStatus() {
|
|||||||
// Check if patched files have the correct size (matches bundled versions)
|
// Check if patched files have the correct size (matches bundled versions)
|
||||||
winerosettaDllCorrectSize := utils.CompareFileWithBundledResource(winerosettaDllPath, "winerosetta/winerosetta.dll")
|
winerosettaDllCorrectSize := utils.CompareFileWithBundledResource(winerosettaDllPath, "winerosetta/winerosetta.dll")
|
||||||
d3d9DllCorrectSize := utils.CompareFileWithBundledResource(d3d9DllPath, "winerosetta/d3d9.dll")
|
d3d9DllCorrectSize := utils.CompareFileWithBundledResource(d3d9DllPath, "winerosetta/d3d9.dll")
|
||||||
rosettaX87CorrectSize := utils.CompareFileWithBundledResource(rosettaX87ExePath, "rosettax87/rosettax87")
|
|
||||||
libRuntimeRosettaX87CorrectSize := utils.CompareFileWithBundledResource(libRuntimeRosettaX87Path, "rosettax87/libRuntimeRosettax87")
|
|
||||||
|
|
||||||
if utils.PathExists(winerosettaDllPath) && utils.PathExists(d3d9DllPath) &&
|
if utils.PathExists(winerosettaDllPath) && utils.PathExists(d3d9DllPath) &&
|
||||||
utils.DirExists(rosettaX87DirPath) && utils.PathExists(rosettaX87ExePath) &&
|
utils.DirExists(rosettaX87DirPath) && utils.PathExists(rosettaX87ExePath) &&
|
||||||
utils.PathExists(libRuntimeRosettaX87Path) && dllsFileValid &&
|
utils.PathExists(libRuntimeRosettaX87Path) && dllsFileValid &&
|
||||||
winerosettaDllCorrectSize && d3d9DllCorrectSize &&
|
winerosettaDllCorrectSize && d3d9DllCorrectSize &&
|
||||||
rosettaX87CorrectSize && libRuntimeRosettaX87CorrectSize && epochPatchesApplied {
|
epochPatchesApplied {
|
||||||
paths.PatchesAppliedEpoch = true
|
paths.PatchesAppliedEpoch = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -61,6 +61,7 @@ var (
|
|||||||
crossoverVersionStatusLabel *widget.RichText
|
crossoverVersionStatusLabel *widget.RichText
|
||||||
wdbDeleteButton *widget.Button
|
wdbDeleteButton *widget.Button
|
||||||
wineDeleteButton *widget.Button
|
wineDeleteButton *widget.Button
|
||||||
|
buildRosettaButton *widget.Button
|
||||||
appMgmtPermissionButton *widget.Button
|
appMgmtPermissionButton *widget.Button
|
||||||
troubleshootingCloseButton *widget.Button
|
troubleshootingCloseButton *widget.Button
|
||||||
)
|
)
|
||||||
|
@@ -129,25 +129,6 @@ func QuotePathForShell(path string) string {
|
|||||||
return fmt.Sprintf(`"%s"`, path)
|
return fmt.Sprintf(`"%s"`, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckForUpdate(currentVersion string) (latestVersion, releaseNotes string, updateAvailable bool, err error) {
|
|
||||||
resp, err := http.Get("https://api.github.com/repos/tairasu/EpochSilicon/releases/latest")
|
|
||||||
if err != nil {
|
|
||||||
return "", "", false, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var data struct {
|
|
||||||
TagName string `json:"tag_name"`
|
|
||||||
Body string `json:"body"`
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
|
|
||||||
return "", "", false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
latest := strings.TrimPrefix(data.TagName, "v")
|
|
||||||
return latest, data.Body, latest != currentVersion, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateInfo contains information about the latest release
|
// UpdateInfo contains information about the latest release
|
||||||
type UpdateInfo struct {
|
type UpdateInfo struct {
|
||||||
TagName string `json:"tag_name"`
|
TagName string `json:"tag_name"`
|
||||||
|
Reference in New Issue
Block a user