-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 70d9c33
Showing
22 changed files
with
2,631 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Folders | ||
.idea/ | ||
Pipsi Installations/ | ||
workspace/ | ||
dist/ | ||
|
||
# Files | ||
cheat_catalog.yaml | ||
installation_data.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json | ||
# vim: set ts=2 sw=2 tw=0 fo=jcroql | ||
version: 2 | ||
|
||
before: | ||
hooks: | ||
- go mod tidy | ||
|
||
builds: | ||
- id: windows | ||
goos: | ||
- windows | ||
goarch: | ||
# - "386" | ||
- amd64 | ||
# - arm64 | ||
mod_timestamp: "{{ .CommitTimestamp }}" | ||
flags: | ||
- -trimpath | ||
ldflags: | ||
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X main.builtBy=goreleaser -X main.treeState={{ .IsGitDirty }} | ||
env: | ||
- CGO_ENABLED=0 | ||
|
||
archives: | ||
- name_template: >- | ||
{{- .ProjectName }}_ | ||
{{- title .Os }}_ | ||
{{- if eq .Arch "amd64" }}x86_64 | ||
{{- else if eq .Arch "386" }}i386 | ||
{{- else }}{{ .Arch }}{{ end }} | ||
{{- if .Arm }}v{{ .Arm }}{{ end -}} | ||
release: | ||
disable: true | ||
|
||
changelog: | ||
disable: true | ||
|
||
checksum: | ||
disable: true |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
<a id="readme-top"></a> | ||
<!--suppress HtmlDeprecatedAttribute --> | ||
<h1 align="center"> | ||
<b>Pipsi Utilities</b> | ||
</h1> | ||
|
||
<p align="center"> | ||
<a href="https://www.codefactor.io/repository/github/SpoilerRules/pipsi-utils"> | ||
<img src="https://www.codefactor.io/repository/github/SpoilerRules/pipsi-utils/badge" alt="CodeFactor"> | ||
</a> | ||
<a href="https://github.com/SpoilerRules/pipsi-utils/releases"> | ||
<img src="https://img.shields.io/github/downloads/SpoilerRules/pipsi-utils/total" alt="GitHub Downloads"> | ||
</a> | ||
<a href="LICENSE"> | ||
<img src="https://img.shields.io/badge/license-GPL--3.0-blue.svg" alt="GPL-3.0 License"> | ||
</a> | ||
</p> | ||
|
||
<!--suppress HtmlDeprecatedAttribute --> | ||
<p align="center"> | ||
Pipsi Utils is a command-line app that automates Pipsi installations and updates with an interactive interface. | ||
</p> | ||
|
||
<p align="center"> | ||
<img src="https://i.imgur.com/6XMGQqN.gif" alt="Pipsi Utilities Showcase" style="max-width: 100%; height: auto;"> | ||
</p> | ||
|
||
<details> | ||
<summary>Table of Contents</summary> | ||
<ul> | ||
<li><a href="#getting-started">Getting Started</a></li> | ||
<li><a href="#building-from-source">Building from Source</a> | ||
<ul> | ||
<li><a href="#prerequisites">Prerequisites</a></li> | ||
<li><a href="#build-instructions">Build Instructions</a></li> | ||
<li><a href="#notes">Notes</a></li> | ||
</ul> | ||
</li> | ||
<li><a href="#contributing">Contributing</a></li> | ||
<li><a href="#license">License</a></li> | ||
</ul> | ||
</details> | ||
|
||
## Getting Started | ||
|
||
1. **Download the Latest Binary** | ||
Visit the [releases page](https://github.com/SpoilerRules/pipsi-utils/releases/latest) and download the latest binary for your system. | ||
|
||
2. **Install the Binary** | ||
Move the executable to your desired installation directory (e.g., `C:\Desktop\Favorite Apps\pipsi-utils`). | ||
**Note**: The tool will create supporting files/folders (e.g., Pipsi installations) in this directory. Ensure it has write permissions. | ||
|
||
3. **Run the Tool** | ||
You can run the tool in one of the following ways: | ||
- **Via Terminal/Powershell**: | ||
Open a terminal or PowerShell window and execute: | ||
```powershell | ||
.\pipsi-utils.exe | ||
``` | ||
- **Via Right-Click**: | ||
Right-click on the executable and select **Open** from the context menu. | ||
- **Via Double-Click**: | ||
Double-click the executable file to run it directly. | ||
<p align="right">(<a href="#readme-top">back to top</a>)</p> | ||
## Building from Source | ||
### Prerequisites | ||
- **Go 1.24 (64-bit)** installed on Windows ([download](https://go.dev/dl/)) | ||
- **Git** for repository cloning | ||
### Build Instructions | ||
1. **Clone the Repository** | ||
```powershell | ||
git clone https://github.com/SpoilerRules/pipsi-utils.git | ||
cd pipsi-utils | ||
``` | ||
2. **Build the Binary** | ||
|
||
Dependencies will be automatically fetched by Go Modules. Run: | ||
```powershell | ||
go build -o pipsi-utils.exe | ||
``` | ||
This generates `pipsi-utils.exe` in the project root. | ||
|
||
3. **Run the Application** | ||
Launch the application to verify the build: | ||
```powershell | ||
.\pipsi-utils.exe | ||
``` | ||
|
||
<p align="right">(<a href="#readme-top">back to top</a>)</p> | ||
|
||
### Notes | ||
Ensure your Go environment is properly configured (`GOPATH`, `GOROOT`, etc.). | ||
|
||
If you encounter issues, check your Go version (`go version`) and ensure it matches the prerequisite (Go 1.24). | ||
|
||
<p align="right">(<a href="#readme-top">back to top</a>)</p> | ||
|
||
## Contributing | ||
|
||
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. | ||
|
||
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". | ||
Don't forget to give the project a star! Thanks again! | ||
|
||
1. Fork the Project | ||
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) | ||
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) | ||
4. Push to the Branch (`git push origin feature/AmazingFeature`) | ||
5. Open a Pull Request | ||
|
||
<p align="right">(<a href="#readme-top">back to top</a>)</p> | ||
|
||
### Top contributors: | ||
|
||
<a href="https://github.com/SpoilerRules/pipsi-utils/graphs/contributors"> | ||
<img src="https://contrib.rocks/image?repo=SpoilerRules/pipsi-utils" alt="contrib.rocks image" /> | ||
</a> | ||
|
||
## License | ||
|
||
Distributed under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html). See the [LICENSE](LICENSE) file for more information. | ||
|
||
<p align="right">(<a href="#readme-top">back to top</a>)</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"strconv" | ||
) | ||
|
||
func IsAccessible() bool { | ||
accessible, err := strconv.ParseBool(os.Getenv("ACCESSIBLE")) | ||
if err != nil { | ||
return false | ||
} | ||
return accessible | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"gopkg.in/yaml.v3" | ||
"io" | ||
"net/http" | ||
) | ||
|
||
type GameCheat struct { | ||
GameTitle string `yaml:"game_title"` | ||
CheatInstallationLink string `yaml:"cheat_installation_link"` | ||
InstallationFolder string `yaml:"installation_folder"` | ||
IsDiscontinued bool `yaml:"is_discontinued"` | ||
} | ||
|
||
type Config struct { | ||
Cheats []GameCheat `yaml:"cheat_catalog"` | ||
} | ||
|
||
var config Config | ||
|
||
func loadCheatCatalogFromURL(url string) error { | ||
response, err := http.Get(url) | ||
if err != nil { | ||
return fmt.Errorf("failed to fetch configuration from URL %s: %w", url, err) | ||
} | ||
defer func() { | ||
if closeErr := response.Body.Close(); closeErr != nil { | ||
err = fmt.Errorf("failed to close response body: %w", closeErr) | ||
} | ||
}() | ||
|
||
if response.StatusCode != http.StatusOK { | ||
return fmt.Errorf("failed to fetch configuration: received status %d", response.StatusCode) | ||
} | ||
|
||
body, err := io.ReadAll(response.Body) | ||
if err != nil { | ||
return fmt.Errorf("failed to read response body: %w", err) | ||
} | ||
|
||
if err := yaml.Unmarshal(body, &config); err != nil { | ||
return fmt.Errorf("failed to decode YAML from URL: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (cfg *Config) getSupportedGameTitles() []string { | ||
var titles []string | ||
for _, cheat := range cfg.Cheats { | ||
if !cheat.IsDiscontinued { | ||
titles = append(titles, cheat.GameTitle) | ||
} | ||
} | ||
return titles | ||
} | ||
|
||
func (cfg *Config) getInstallationLink(title string) string { | ||
for _, cheat := range cfg.Cheats { | ||
if cheat.GameTitle == title { | ||
return cheat.CheatInstallationLink | ||
} | ||
} | ||
fmt.Printf("Error: InstallationData title '%s' not found. The installation link could not be retrieved.\n", title) | ||
return "" | ||
} | ||
|
||
func (cfg *Config) getInstallationFolder(title string) string { | ||
for _, cheat := range cfg.Cheats { | ||
if cheat.GameTitle == title { | ||
return cheat.InstallationFolder | ||
} | ||
} | ||
fmt.Printf("Error: InstallationData title '%s' not found. The installation folder could not be retrieved.\n", title) | ||
return "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package main | ||
|
||
import "github.com/charmbracelet/lipgloss" | ||
|
||
var ( | ||
WarningText = lipgloss.NewStyle().Foreground(lipgloss.Color("3")) // yellow | ||
HighlightText = lipgloss.NewStyle().Foreground(lipgloss.Color("11")) // bright yellow | ||
// NoticePrefix = lipgloss.NewStyle().Foreground(lipgloss.Color("3")) | ||
BoldCyan = lipgloss.NewStyle().Foreground(lipgloss.Color("6")) | ||
StatusText = lipgloss.NewStyle(). | ||
Bold(true). | ||
Foreground(lipgloss.Color("#00C853")) // bold green adhering to fluent 2 theme | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"github.com/charmbracelet/log" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
func manageDefenderExclusion() { | ||
if !isDefenderActive() { | ||
log.Warnf("Windows Defender is not active.\nExternal antivirus software may flag or delete Pipsi installations.\nWe are proceeding to add exclusions, but please ensure your antivirus software allows Pipsi by setting the necessary exclusions manually.") | ||
} | ||
|
||
currentDir, err := os.Getwd() | ||
if err != nil { | ||
log.Errorf("Unable to get current directory: %v", err) | ||
return | ||
} | ||
pipsiFolderPath := filepath.Join(currentDir, "Pipsi Installations") | ||
|
||
if _, err := os.Stat(pipsiFolderPath); os.IsNotExist(err) { | ||
if err := os.Mkdir(pipsiFolderPath, 0755); err != nil { | ||
log.Errorf("Unable to create Pipsi Installations folder: %v", err) | ||
return | ||
} | ||
} | ||
|
||
checkCmd := exec.Command( | ||
"powershell", "-Command", fmt.Sprintf( | ||
`$exclusions = Get-MpPreference | Select -ExpandProperty ExclusionPath; $exclusions -contains "%s"`, | ||
pipsiFolderPath, | ||
), | ||
) | ||
var checkOutput bytes.Buffer | ||
var checkStderr bytes.Buffer | ||
checkCmd.Stdout = &checkOutput | ||
checkCmd.Stderr = &checkStderr | ||
|
||
if err := checkCmd.Run(); err != nil { | ||
log.Errorf("Failed to check Windows Defender exclusions.\nError: %v", checkStderr.String()) | ||
return | ||
} | ||
|
||
if strings.TrimSpace(checkOutput.String()) == "True" { | ||
log.Debugf("'%s' is already in Windows Defender exclusions.", pipsiFolderPath) | ||
return | ||
} | ||
|
||
log.Debugf("Attempting to add '%s' to Windows Defender exclusions...", pipsiFolderPath) | ||
|
||
addCmd := exec.Command( | ||
"powershell", "-Command", fmt.Sprintf(`Add-MpPreference -ExclusionPath "%s"`, pipsiFolderPath), | ||
) | ||
var addStderr bytes.Buffer | ||
addCmd.Stderr = &addStderr | ||
|
||
if err := addCmd.Run(); err != nil { | ||
log.Errorf( | ||
"Failed to add folder to Windows Defender exclusions.\nConsider disabling real-time protection or manually adding the folder.\nError: %v", | ||
addStderr.String(), | ||
) | ||
return | ||
} | ||
|
||
log.Infof("Successfully added '%s' to Windows Defender exclusions.", pipsiFolderPath) | ||
} | ||
|
||
func isDefenderActive() bool { | ||
cmd := exec.Command( | ||
"powershell", "-Command", "Get-MpPreference | Select-Object -ExpandProperty DisableRealtimeMonitoring", | ||
) | ||
var output bytes.Buffer | ||
cmd.Stdout = &output | ||
|
||
if err := cmd.Run(); err != nil { | ||
log.Warnf("Error checking Windows Defender status: %v\n", err) | ||
pauseAndExit() | ||
} | ||
|
||
trimmedOutput := strings.TrimSpace(output.String()) | ||
|
||
return trimmedOutput == "False" | ||
} |
Oops, something went wrong.