Compare commits
1 Commits
master
...
alacritty-
Author | SHA1 | Date |
---|---|---|
Preston Baxter | 3750daebab |
20
go.mod
20
go.mod
|
@ -1,3 +1,23 @@
|
|||
module hnl
|
||||
|
||||
go 1.21.5
|
||||
|
||||
require github.com/charmbracelet/bubbletea v0.25.0
|
||||
|
||||
require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.15.2 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/term v0.6.0 // indirect
|
||||
golang.org/x/text v0.3.8 // indirect
|
||||
)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
|
||||
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
345
main.go
345
main.go
|
@ -13,82 +13,144 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
const (
|
||||
battleNetInstaller = "https://downloader.battle.net/download/getInstallerForGame?os=win&gameProgram=BATTLENET_APP&version=Live"
|
||||
hdtInstaller = "https://github.com/HearthSim/Hearthstone-Deck-Tracker/releases/download/v1.23.15/Hearthstone.Deck.Tracker-v1.23.15.zip"
|
||||
hdtInstaller = "https://github.com/HearthSim/Hearthstone-Deck-Tracker/releases/download/v1.23.15/Hearthstone.Deck.Tracker-v1.23.15.zip"
|
||||
alacrittyInstaller = "https://github.com/alacritty/alacritty/releases/download/v0.13.1/Alacritty-v0.13.1-portable.exe"
|
||||
programDir = "C:\\Program Files (x86)"
|
||||
)
|
||||
|
||||
func main(){
|
||||
//check app data
|
||||
init, err := checkInit()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s", err)
|
||||
time.Sleep(15 * time.Second)
|
||||
os.Exit(1)
|
||||
}
|
||||
var (
|
||||
hdtBin = filepath.Join("C:", "Program Files (x86)", "hln", "Hearthstone Deck Tracker", "Hearthstone Deck Tracker.exe")
|
||||
battleNetBin = filepath.Join("C:", "Program Files (x86)", "Battle.net", "Battle.net.exe")
|
||||
)
|
||||
|
||||
//If not installed - installed
|
||||
if !init {
|
||||
fmt.Printf("Games not isntalled. Installing...\n")
|
||||
err := installBins()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s", err)
|
||||
time.Sleep(15 * time.Second)
|
||||
func main() {
|
||||
|
||||
if len(os.Args) == 1 {
|
||||
fmt.Printf("Boot strapping...\n")
|
||||
//check allacritty installed.
|
||||
if !isAlaccrittyInstalled() {
|
||||
//intstall if not present.
|
||||
if err := installAlacritty(); err != nil {
|
||||
fmt.Printf("Failed to run program. Error Below:\n\n%v\n", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if err := forkBubbleTea(); err != nil {
|
||||
fmt.Printf("Failed to run program. Error Below:\n\n%v\n", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
err := launchBins()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s", err)
|
||||
time.Sleep(15 * time.Second)
|
||||
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
}
|
||||
|
||||
switch os.Args[1] {
|
||||
//we are inside alacritty, run the bubble tea program
|
||||
case "launch":
|
||||
p := tea.NewProgram(initHlnModel())
|
||||
if _, err := p.Run(); err != nil {
|
||||
fmt.Printf("Failed to run program. Error Below:\n\n%v\n", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
//if installed. Launch battlenet and hdt
|
||||
|
||||
}
|
||||
|
||||
//Check if installed file is in the user config directory
|
||||
func checkInit() (bool, error) {
|
||||
// func main(){
|
||||
// //check app data
|
||||
// init, err := checkInit()
|
||||
// if err != nil {
|
||||
// fmt.Printf("Error: %s", err)
|
||||
// time.Sleep(15 * time.Second)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
//
|
||||
// //If not installed - installed
|
||||
// if !init {
|
||||
// fmt.Printf("Games not isntalled. Installing...\n")
|
||||
// err := installBins()
|
||||
// if err != nil {
|
||||
// fmt.Printf("Error: %s", err)
|
||||
// time.Sleep(15 * time.Second)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// //if installed. Launch battlenet and hdt
|
||||
// } else {
|
||||
// err := launchBins()
|
||||
// if err != nil {
|
||||
// fmt.Printf("Error: %s", err)
|
||||
// time.Sleep(15 * time.Second)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
func isAlaccrittyInstalled() bool {
|
||||
path := filepath.Join(programDir, "alacritty", "alacritty.exe")
|
||||
|
||||
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
|
||||
return false
|
||||
} else if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func forkBubbleTea() error {
|
||||
file := filepath.Join(programDir, "alacritty", "alacritty.exe")
|
||||
// cmd := exec.Command(file, "--command", fmt.Sprintf("%s launch", filepath.Join(programDir, "hln", "hln.exe")))
|
||||
cmd := exec.Command(file)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// Check if installed file is in the user config directory
|
||||
func checkInstalled() tea.Msg {
|
||||
configDir, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
return false, err
|
||||
return errMsg{err: err}
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s%c%s%cinstalled", configDir, os.PathSeparator, "HearthstoneNerdLinux", os.PathSeparator)
|
||||
path := filepath.Join(configDir, "HearthstoneLinuxNerd", "installed")
|
||||
|
||||
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist){
|
||||
return false, nil
|
||||
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
|
||||
return NOT_INSTALLED
|
||||
} else if err != nil {
|
||||
return false, err
|
||||
return errMsg{err: err}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return INSTALLED
|
||||
}
|
||||
|
||||
//download and loaunch battlenet installer and install HDT
|
||||
func installBins() error {
|
||||
// download and loaunch battlenet installer and install HDT
|
||||
func installBins() tea.Msg {
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(2)
|
||||
errs := make([]error, 2)
|
||||
|
||||
cacheDir, err := os.UserCacheDir()
|
||||
if err != nil {
|
||||
return err
|
||||
return errMsg{err: err}
|
||||
}
|
||||
|
||||
configDir, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
return err
|
||||
return errMsg{err: err}
|
||||
}
|
||||
|
||||
go func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
fmt.Printf("Installing batlle.net\n")
|
||||
file := fmt.Sprintf("%s%cbattlenet.exe", cacheDir, os.PathSeparator)
|
||||
// fmt.Printf("Installing batlle.net\n")
|
||||
file := filepath.Join(cacheDir, "battlenet.exe")
|
||||
errs[0] = downloadBin(battleNetInstaller, file)
|
||||
if errs[0] != nil {
|
||||
return
|
||||
|
@ -100,15 +162,15 @@ func installBins() error {
|
|||
|
||||
go func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
fmt.Printf("Installing hdt\n")
|
||||
file := fmt.Sprintf("%s%chdt.zip", cacheDir, os.PathSeparator)
|
||||
// fmt.Printf("Installing hdt\n")
|
||||
file := filepath.Join(cacheDir, "hdt.zip")
|
||||
errs[1] = downloadBin(hdtInstaller, file)
|
||||
if errs[1] != nil {
|
||||
return
|
||||
}
|
||||
|
||||
programDir := "C:\\Program Files (x86)\\hnl"
|
||||
errs[1] = unzip(file, programDir)
|
||||
dir := filepath.Join(programDir, "hln")
|
||||
errs[1] = unzip(file, dir)
|
||||
if errs[1] != nil {
|
||||
return
|
||||
}
|
||||
|
@ -117,148 +179,153 @@ func installBins() error {
|
|||
wg.Wait()
|
||||
|
||||
if err := errors.Join(errs...); err != nil {
|
||||
return err
|
||||
return errMsg{err: err}
|
||||
}
|
||||
|
||||
err = os.MkdirAll(filepath.Join(configDir, "HearthstoneLinuxNerd"), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
return errMsg{err: err}
|
||||
}
|
||||
|
||||
_, err = os.Create(filepath.Join(configDir, "HearthstoneLinuxNerd", "installed"))
|
||||
if err != nil {
|
||||
return errMsg{err: err}
|
||||
}
|
||||
|
||||
return INSTALLED
|
||||
}
|
||||
|
||||
func installAlacritty() error {
|
||||
err := os.MkdirAll(filepath.Join(programDir, "alacritty"), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
dir := filepath.Join(programDir, "alacritty", "alacritty.exe")
|
||||
return downloadBin(alacrittyInstaller, dir)
|
||||
}
|
||||
|
||||
func launchBins() error {
|
||||
battleNetBin := filepath.Join("C:", "Program Files (x86)", "Battle.net", "Battle.net.exe")
|
||||
hdtBin := filepath.Join("C:", "Program Files (x86)", "hnl", "Hearthstone Deck Tracker", "Hearthstone Deck Tracker.exe")
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(2)
|
||||
errs := make([]error, 2)
|
||||
|
||||
go func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
func (m *HlnModel) launchBattleNet() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
cmd := exec.Command(battleNetBin)
|
||||
errs[0] = cmd.Run()
|
||||
}(wg)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return ApplicationEvent{app: BATTLE_NET_ID, state: STATE_STOPPED, err: err}
|
||||
}
|
||||
|
||||
go func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
return ApplicationEvent{app: BATTLE_NET_ID, state: STATE_STOPPED, err: nil}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *HlnModel) launchHdt() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
cmd := exec.Command(hdtBin)
|
||||
errs[1] = cmd.Run()
|
||||
}(wg)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return ApplicationEvent{app: HDT_ID, state: STATE_STOPPED, err: err}
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return ApplicationEvent{app: HDT_ID, state: STATE_STOPPED, err: nil}
|
||||
}
|
||||
}
|
||||
|
||||
if err := errors.Join(errs...); err != nil {
|
||||
func downloadBin(uri, filepath string) error { // Build fileName from fullPath
|
||||
fileURL, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func downloadBin(uri, filepath string) error {// Build fileName from fullPath
|
||||
fileURL, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create blank file
|
||||
// Create blank file
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := http.Client{
|
||||
CheckRedirect: func(r *http.Request, via []*http.Request) error {
|
||||
r.URL.Opaque = r.URL.Path
|
||||
return nil
|
||||
},
|
||||
}
|
||||
// Put content on file
|
||||
resp, err := client.Get(fileURL.String())
|
||||
if err != nil {
|
||||
}
|
||||
client := http.Client{
|
||||
CheckRedirect: func(r *http.Request, via []*http.Request) error {
|
||||
r.URL.Opaque = r.URL.Path
|
||||
return nil
|
||||
},
|
||||
}
|
||||
// Put content on file
|
||||
resp, err := client.Get(fileURL.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
|
||||
defer file.Close()
|
||||
defer file.Close()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func unzip(src, dest string) error {
|
||||
r, err := zip.OpenReader(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := r.Close(); err != nil {
|
||||
r, err := zip.OpenReader(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := r.Close(); err != nil {
|
||||
fmt.Printf("stuff...\n")
|
||||
time.Sleep(10)
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
os.MkdirAll(dest, 0755)
|
||||
os.MkdirAll(dest, 0755)
|
||||
|
||||
// Closure to address file descriptors issue with all the deferred .Close() methods
|
||||
extractAndWriteFile := func(f *zip.File) error {
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := rc.Close(); err != nil {
|
||||
// Closure to address file descriptors issue with all the deferred .Close() methods
|
||||
extractAndWriteFile := func(f *zip.File) error {
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := rc.Close(); err != nil {
|
||||
fmt.Printf("stuff...\n")
|
||||
time.Sleep(10)
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}()
|
||||
|
||||
path := filepath.Join(dest, f.Name)
|
||||
path := filepath.Join(dest, f.Name)
|
||||
|
||||
// Check for ZipSlip (Directory traversal)
|
||||
if !strings.HasPrefix(path, filepath.Clean(dest) + string(os.PathSeparator)) {
|
||||
return fmt.Errorf("illegal file path: %s", path)
|
||||
}
|
||||
// Check for ZipSlip (Directory traversal)
|
||||
if !strings.HasPrefix(path, filepath.Clean(dest)+string(os.PathSeparator)) {
|
||||
return fmt.Errorf("illegal file path: %s", path)
|
||||
}
|
||||
|
||||
if f.FileInfo().IsDir() {
|
||||
os.MkdirAll(path, f.Mode())
|
||||
} else {
|
||||
os.MkdirAll(filepath.Dir(path), f.Mode())
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
if f.FileInfo().IsDir() {
|
||||
os.MkdirAll(path, f.Mode())
|
||||
} else {
|
||||
os.MkdirAll(filepath.Dir(path), f.Mode())
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
fmt.Printf("stuff...\n")
|
||||
time.Sleep(10)
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = io.Copy(f, rc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
_, err = io.Copy(f, rc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, f := range r.File {
|
||||
err := extractAndWriteFile(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, f := range r.File {
|
||||
err := extractAndWriteFile(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
type (
|
||||
InstallState int
|
||||
appState int
|
||||
appId int
|
||||
|
||||
ApplicationEvent struct {
|
||||
app appId
|
||||
state appState
|
||||
err error
|
||||
}
|
||||
|
||||
errMsg struct{ err error }
|
||||
)
|
||||
|
||||
const (
|
||||
INSTALLED InstallState = 0
|
||||
NOT_INSTALLED InstallState = 1
|
||||
UNKOWN_INSTALL_STATE InstallState = 2
|
||||
|
||||
BATTLE_NET_ID appId = 1
|
||||
HDT_ID appId = 2
|
||||
|
||||
STATE_RUNNING appState = 0
|
||||
STATE_STOPPED appState = 1
|
||||
)
|
||||
|
||||
func (m errMsg) Error() string {
|
||||
return m.err.Error()
|
||||
}
|
||||
|
||||
type HlnModel struct {
|
||||
battlenetRunning bool
|
||||
hdtRunning bool
|
||||
installed InstallState
|
||||
err error
|
||||
}
|
||||
|
||||
func initHlnModel() *HlnModel {
|
||||
return &HlnModel{
|
||||
battlenetRunning: false,
|
||||
hdtRunning: false,
|
||||
installed: UNKOWN_INSTALL_STATE,
|
||||
err: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *HlnModel) Init() tea.Cmd {
|
||||
return checkInstalled
|
||||
}
|
||||
|
||||
func (m *HlnModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
//Check install state
|
||||
case InstallState:
|
||||
switch msg {
|
||||
case NOT_INSTALLED:
|
||||
m.installed = NOT_INSTALLED
|
||||
return m, installBins
|
||||
case INSTALLED:
|
||||
m.battlenetRunning = true
|
||||
m.hdtRunning = true
|
||||
m.installed = INSTALLED
|
||||
|
||||
return m, tea.Batch(
|
||||
m.launchHdt(),
|
||||
m.launchBattleNet(),
|
||||
)
|
||||
}
|
||||
|
||||
//Hanlde appliaction events
|
||||
case ApplicationEvent:
|
||||
//Check app error
|
||||
if msg.err != nil {
|
||||
m.err = errors.Join(msg.err, fmt.Errorf("Failed to do something on app_id: %d", msg.app))
|
||||
return m, tea.Quit
|
||||
}
|
||||
|
||||
//Set state of app
|
||||
switch msg.app {
|
||||
case BATTLE_NET_ID:
|
||||
m.battlenetRunning = false
|
||||
return m, nil
|
||||
case HDT_ID:
|
||||
m.hdtRunning = false
|
||||
return m, nil
|
||||
}
|
||||
|
||||
//Check error mssg
|
||||
case errMsg:
|
||||
m.err = msg
|
||||
return m, tea.Quit
|
||||
|
||||
//Check key press
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "q":
|
||||
return m, tea.Quit
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *HlnModel) View() string {
|
||||
|
||||
if m.err != nil {
|
||||
return fmt.Sprintf("Error occured: %v\n", m.err)
|
||||
}
|
||||
|
||||
s := "----- Welcome to Hearthston Linux Nerd Launcher -----\n\n"
|
||||
|
||||
switch m.installed {
|
||||
case INSTALLED:
|
||||
s += fmt.Sprintf("\tInstalled: Yes\n")
|
||||
case NOT_INSTALLED:
|
||||
s += fmt.Sprintf("\tInstalled: No. Installing...\n")
|
||||
case UNKOWN_INSTALL_STATE:
|
||||
s += fmt.Sprintf("\tInstalled: checking\n")
|
||||
}
|
||||
s += "\n"
|
||||
|
||||
//Battle net display
|
||||
s += fmt.Sprintf("\tBattlenet Running: %t\n", m.battlenetRunning)
|
||||
|
||||
//hdt display
|
||||
s += fmt.Sprintf("\tHdt Running: %t\n", m.hdtRunning)
|
||||
|
||||
s += "\n"
|
||||
|
||||
s += "-----------------------------------------------------\n"
|
||||
|
||||
return s
|
||||
}
|
Loading…
Reference in New Issue