Skip to content

Commit

Permalink
release 2.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
djohts committed May 7, 2024
1 parent 44b7a8a commit a867d0e
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 18 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 2.4.0 (2024-05-07)

- Added automatic download of `SII_Decrypt.exe`
- Added a progressbar for file downloads

**Full Changelog**: https://github.com/djohts/tpc-truckersmp/compare/v2.3.0...v2.4.0

## 2.3.0 (2024-05-07)

> [!WARNING]
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ ETS2 and ATS on Windows x64

## Download

> [!NOTE]
> Starting from version 2.4.0, the app will automatically download `SII_Decrypt.exe` for you.
> [!WARNING]
> You need to download both `SII_Decrypt.exe` and `tpc.exe` to use the app. Make sure they are in the same directory and that `SII_Decrypt.exe` is not renamed.
Expand Down
2 changes: 1 addition & 1 deletion constants/constants.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package constants

const (
APP_VERSION = `2.3.0`
APP_VERSION = `2.4.0`

ETS = `Euro Truck Simulator 2`
ATS = `American Truck Simulator`
Expand Down
28 changes: 28 additions & 0 deletions downloader/downloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package downloader

import (
"github.com/djohts/tpc-truckersmp/updater"
"github.com/djohts/tpc-truckersmp/utils"
"github.com/google/go-github/v61/github"
)

func DownloadSiiDecrypt() (bool, error) {
release, err := updater.GetLatestRelease()
if err != nil {
return false, err
}

asset := utils.FindOne(release.Assets, func(asset **github.ReleaseAsset) bool {
return *(*asset).Name == "SII_Decrypt.exe"
})
if asset == nil {
return false, nil
}

err = updater.DownloadFile(*(*asset).BrowserDownloadURL, "SII_Decrypt.exe")
if err != nil {
return false, err
}

return true, nil
}
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ go 1.22
require (
git.tcp.direct/kayos/sendkeys v0.0.0-20211216174833-565f782ccf21
github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea
github.com/charmbracelet/bubbles v0.18.0
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/huh v0.3.0
github.com/charmbracelet/lipgloss v0.10.0
github.com/charmbracelet/log v0.4.0
github.com/coreos/go-semver v0.3.1
github.com/creasty/defaults v1.7.0
Expand All @@ -21,9 +24,7 @@ require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/catppuccin/go v0.2.0 // indirect
github.com/charmbracelet/bubbles v0.17.2-0.20240108170749-ec883029c8e6 // indirect
github.com/charmbracelet/bubbletea v0.25.0 // indirect
github.com/charmbracelet/lipgloss v0.10.0 // indirect
github.com/charmbracelet/harmonica v0.2.0 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea h1:+GIgqdjrcKMHK1
github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea/go.mod h1:P/j2DSP/kCOakHBACzMqmOdrTEieqdSiB3U9fqk7qgc=
github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA=
github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
github.com/charmbracelet/bubbles v0.17.2-0.20240108170749-ec883029c8e6 h1:6nVCV8pqGaeyxetur3gpX3AAaiyKgzjIoCPV3NXKZBE=
github.com/charmbracelet/bubbles v0.17.2-0.20240108170749-ec883029c8e6/go.mod h1:9HxZWlkCqz2PRwsCbYl7a3KXvGzFaDHpYbSYMJ+nE3o=
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/huh v0.3.0 h1:CxPplWkgW2yUTDDG0Z4S5HH8SJOosWHd4LxCvi0XsKE=
github.com/charmbracelet/huh v0.3.0/go.mod h1:fujUdKX8tC45CCSaRQdw789O6uaCRwx8l2NDyKfC4jA=
github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s=
Expand All @@ -37,8 +39,6 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
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-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
Expand Down
11 changes: 10 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/charmbracelet/log"
"github.com/djohts/tpc-truckersmp/config"
"github.com/djohts/tpc-truckersmp/constants"
"github.com/djohts/tpc-truckersmp/downloader"
"github.com/djohts/tpc-truckersmp/updater"
"github.com/djohts/tpc-truckersmp/utils"
"github.com/djohts/tpc-truckersmp/watcher"
Expand All @@ -19,7 +20,15 @@ func main() {
fmt.Println("tpc-truckersmp", "v"+constants.APP_VERSION, "by djohts")

if !utils.IsFile("SII_Decrypt.exe") {
utils.HandleError(errors.New("SII_Decrypt.exe does not exist"))
log.Warn("SII_Decrypt.exe not found, downloading...")
success, err := downloader.DownloadSiiDecrypt()
if err != nil {
utils.HandleError(err)
} else if success {
log.Info("SII_Decrypt.exe downloaded successfully")
} else {
utils.HandleError(errors.New("failed to download SII_Decrypt.exe"))
}
}

log.Info("================= TPC For TruckersMP =================")
Expand Down
85 changes: 85 additions & 0 deletions updater/tui.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package updater

import (
"strings"
"time"

"github.com/charmbracelet/bubbles/progress"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)

var helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#626262")).Render

const (
padding = 2
maxWidth = 80
)

type progressMsg float64

type progressErrMsg struct{ err error }

func finalPause() tea.Cmd {
return tea.Tick(time.Millisecond*750, func(_ time.Time) tea.Msg {
return nil
})
}

type model struct {
pw *progressWriter
progress progress.Model
err error
}

func (m model) Init() tea.Cmd {
return nil
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
return m, tea.Quit

case tea.WindowSizeMsg:
m.progress.Width = msg.Width - padding*2 - 4
if m.progress.Width > maxWidth {
m.progress.Width = maxWidth
}
return m, nil

case progressErrMsg:
m.err = msg.err
return m, tea.Quit

case progressMsg:
var cmds []tea.Cmd

if msg >= 1.0 {
cmds = append(cmds, tea.Sequence(finalPause(), tea.Quit))
}

cmds = append(cmds, m.progress.SetPercent(float64(msg)))
return m, tea.Batch(cmds...)

// FrameMsg is sent when the progress bar wants to animate itself
case progress.FrameMsg:
progressModel, cmd := m.progress.Update(msg)
m.progress = progressModel.(progress.Model)
return m, cmd

default:
return m, nil
}
}

func (m model) View() string {
if m.err != nil {
return "Error downloading: " + m.err.Error() + "\n"
}

pad := strings.Repeat(" ", padding)
return "\n" +
pad + m.progress.View() + "\n\n" +
pad + helpStyle("Press any key to quit")
}
96 changes: 87 additions & 9 deletions updater/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ package updater

import (
"context"
"fmt"
"io"
"net/http"
"os"

"github.com/charmbracelet/bubbles/progress"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/log"
"github.com/coreos/go-semver/semver"
"github.com/djohts/tpc-truckersmp/constants"
Expand All @@ -12,47 +17,96 @@ import (
"github.com/minio/selfupdate"
)

var p *tea.Program

func CheckUpdates() (bool, string, error) {
latestRelease, err := getLatestRelease()
release, err := GetLatestRelease()
if err != nil {
return false, "", err
}

needsUpdate := semver.New(constants.APP_VERSION).LessThan(*semver.New((*latestRelease.TagName)[1:]))
needsUpdate := semver.New(constants.APP_VERSION).LessThan(*semver.New((*release.TagName)[1:]))

return needsUpdate, *latestRelease.TagName, nil
return needsUpdate, *release.TagName, nil
}

func UpdateSelf() (bool, error) {
latestRelease, err := getLatestRelease()
release, err := GetLatestRelease()
if err != nil {
return false, err
}

asset := utils.FindOne(latestRelease.Assets, func(asset **github.ReleaseAsset) bool {
asset := utils.FindOne(release.Assets, func(asset **github.ReleaseAsset) bool {
return *(*asset).Name == "tpc.exe"
})
if asset == nil {
return false, nil
}

log.Info("Downloading latest version...")
res, err := http.Get(*(*asset).BrowserDownloadURL)
filename := "tpc.exe.tmp"
err = DownloadFile(*(*asset).BrowserDownloadURL, filename)
if err != nil {
return false, err
}
defer res.Body.Close()

log.Info("Applying update...")
err = selfupdate.Apply(res.Body, selfupdate.Options{})
file, err := os.Open(filename)
if err != nil {
return false, err
}
err = selfupdate.Apply(file, selfupdate.Options{})
file.Close()
os.Remove(filename)
if err != nil {
return false, err
}

return true, nil
}

func getLatestRelease() (*github.RepositoryRelease, error) {
func DownloadFile(url, filename string) error {
res, err := http.Get(url)
if err != nil {
return err
}
defer res.Body.Close()

file, err := os.Create(filename)
if err != nil {
fmt.Println("could not create file:", err)
os.Exit(1)
}
defer file.Close()

pw := &progressWriter{
total: int(res.ContentLength),
file: file,
reader: res.Body,
onProgress: func(ratio float64) {
p.Send(progressMsg(ratio))
},
}

m := model{
pw: pw,
progress: progress.New(progress.WithDefaultGradient()),
}
// Start Bubble Tea
p = tea.NewProgram(m)

// Start the download
go pw.Start()

if _, err := p.Run(); err != nil {
fmt.Println("error running program:", err)
os.Exit(1)
}

return nil
}

func GetLatestRelease() (*github.RepositoryRelease, error) {
client := github.NewClient(nil)
releases, _, err := client.Repositories.ListReleases(context.Background(), "djohts", "tpc-truckersmp", nil)
if err != nil {
Expand All @@ -65,3 +119,27 @@ func getLatestRelease() (*github.RepositoryRelease, error) {

return releases[0], nil
}

type progressWriter struct {
total int
downloaded int
file *os.File
reader io.Reader
onProgress func(float64)
}

func (pw *progressWriter) Start() {
// TeeReader calls pw.Write() each time a new response is received
_, err := io.Copy(pw.file, io.TeeReader(pw.reader, pw))
if err != nil {
p.Send(progressErrMsg{err})
}
}

func (pw *progressWriter) Write(p []byte) (int, error) {
pw.downloaded += len(p)
if pw.total > 0 && pw.onProgress != nil {
pw.onProgress(float64(pw.downloaded) / float64(pw.total))
}
return len(p), nil
}

0 comments on commit a867d0e

Please sign in to comment.