Skip to content

Commit

Permalink
initial ui split, introduction of cancel and viewlog buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
apprehensions committed Oct 6, 2023
1 parent a2f6e5a commit 9d640cb
Show file tree
Hide file tree
Showing 34 changed files with 666 additions and 454 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,15 @@ uninstall:
rm -f $(DESTDIR)$(ICONPREFIX)/128x128/apps/$(FLATPAK).player.png
rm -f $(DESTDIR)$(ICONPREFIX)/128x128/apps/$(FLATPAK).studio.png

icons: icons/roblox-player.svg icons/roblox-studio.svg icons/vinegar.svg
icons: icons/roblox-player.svg icons/roblox-studio.svg
rm -rf icons/16 icons/32 icons/48 icons/64 icons/128
mkdir icons/16 icons/32 icons/48 icons/64 icons/128
convert -density 384 -background none $^ -resize 16x16 -set filename:f '%w/%t' 'icons/%[filename:f].png'
convert -density 384 -background none $^ -resize 32x32 -set filename:f '%w/%t' 'icons/%[filename:f].png'
convert -density 384 -background none $^ -resize 48x48 -set filename:f '%w/%t' 'icons/%[filename:f].png'
convert -density 384 -background none $^ -resize 64x64 -set filename:f '%w/%t' 'icons/%[filename:f].png'
convert -density 384 -background none $^ -resize 128x128 -set filename:f '%w/%t' 'icons/%[filename:f].png'
convert -density 384 -background none icons/vinegar.svg -resize 64x64 internal/ui/vinegar.png

mime:
xdg-mime default $(FLATPAK).player.desktop x-scheme-handler/roblox-player
Expand Down
304 changes: 263 additions & 41 deletions cmd/vinegar/binary.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
package main

import (
"fmt"
"log"
"os/exec"
"path/filepath"
"strings"
"time"

"github.com/vinegarhq/vinegar/internal/config"
"github.com/vinegarhq/vinegar/internal/config/state"
"github.com/vinegarhq/vinegar/internal/dirs"
"github.com/vinegarhq/vinegar/internal/gui"
"github.com/vinegarhq/vinegar/roblox"
"github.com/vinegarhq/vinegar/roblox/bootstrapper"
"github.com/vinegarhq/vinegar/wine"
"github.com/vinegarhq/vinegar/wine/dxvk"
)

type Binary struct {
name string
log chan string
progress chan float32
UI *gui.UI

dir string
pfx *wine.Prefix
GlobalConfig *config.Config
Config *config.Application

cfg *config.Config
bcfg *config.Application

btype roblox.BinaryType
ver roblox.Version
Alias string
Name string
Dir string
Prefix *wine.Prefix
Type roblox.BinaryType
Version roblox.Version
}

func NewBinary(bt roblox.BinaryType, cfg *config.Config, pfx *wine.Prefix) Binary {
Expand All @@ -35,55 +43,269 @@ func NewBinary(bt roblox.BinaryType, cfg *config.Config, pfx *wine.Prefix) Binar
}

return Binary{
name: bt.String(),
log: make(chan string),
progress: make(chan float32),
UI: gui.New(&cfg.UI),

GlobalConfig: cfg,
Config: &bcfg,

Alias: bt.String(),
Name: bt.BinaryName(),
Type: bt,
Prefix: pfx,
}
}

func (b *Binary) Run(args ...string) error {
b.UI.Desc(b.Config.Channel)

if err := b.Setup(); err != nil {
return err
}

cmd, err := b.Command(args...)
if err != nil {
return err
}

btype: bt,
pfx: pfx,
cfg: cfg,
bcfg: &bcfg,
log.Printf("Launching %s", b.Name)
b.UI.Message("Launching " + b.Alias)

if err := cmd.Start(); err != nil {
return err
}

time.Sleep(1 * time.Second)
b.UI.Close()

if err := cmd.Wait(); err != nil {
return err
}

if b.Config.AutoKillPrefix {
b.Prefix.Kill()
}

return nil
}

func (b *Binary) Run(args ...string) {
exitChan := make(chan bool)
func (b *Binary) FetchVersion() (roblox.Version, error) {
b.UI.Message("Fetching " + b.Alias)

if b.Config.ForcedVersion != "" {
log.Printf("WARNING: using forced version: %s", b.Config.ForcedVersion)

return roblox.NewVersion(b.Type, b.Config.Channel, b.Config.ForcedVersion)
}

return roblox.LatestVersion(b.Type, b.Config.Channel)
}

go func() {
if b.cfg.UI.Enabled {
b.Glass(exitChan)
} else {
b.EmptyGlass(exitChan)
func (b *Binary) Setup() error {
ver, err := b.FetchVersion()
if err != nil {
return err
}

b.UI.Desc(fmt.Sprintf("%s %s", ver.GUID, ver.Channel))
b.Version = ver
b.Dir = filepath.Join(dirs.Versions, ver.GUID)

stateVer, err := state.Version(b.Type)
if err != nil {
log.Printf("Failed to retrieve stored %s version: %s", b.Name, err)
}

if stateVer != ver.GUID {
log.Printf("Installing %s (%s -> %s)", b.Name, stateVer, ver)

if err := b.Install(); err != nil {
return err
}
}()
} else {
log.Printf("%s is up to date (%s)", b.Name, ver.GUID)
}

b.Config.Env.Setenv()

fatal := func(err error) {
b.log <- err.Error()
log.Fatal(err)
if err := b.Config.FFlags.SetRenderer(b.Config.Renderer); err != nil {
return err
}

if err := b.Setup(); err != nil {
fatal(err)
if err := b.Config.FFlags.Apply(b.Dir); err != nil {
return err
}

cmd, err := b.Command(args...)
if err := dirs.OverlayDir(b.Dir); err != nil {
return err
}

if err := b.SetupDxvk(); err != nil {
return err
}

b.UI.Progress(1.0)
return nil
}

func (b *Binary) Install() error {
b.UI.Message("Installing " + b.Alias)

manifest, err := bootstrapper.Fetch(b.Version, dirs.Downloads)
if err != nil {
fatal(err)
return err
}

log.Printf("Launching %s", b.name)
b.log <- "Launching Roblox"
if err := dirs.Mkdirs(dirs.Downloads); err != nil {
return err
}

time.Sleep(time.Second * 2)
b.UI.Message("Downloading " + b.Alias)
if err := b.DownloadPackages(&manifest); err != nil {
return err
}

if err := cmd.Start(); err != nil {
fatal(err)
b.UI.Message("Extracting " + b.Alias)
if err := b.ExtractPackages(&manifest); err != nil {
return err
}

if err := bootstrapper.WriteAppSettings(b.Dir); err != nil {
return err
}

if err := state.SaveManifest(&manifest); err != nil {
return err
}

if err := state.CleanPackages(); err != nil {
return err
}

return state.CleanVersions()
}

func (b *Binary) DownloadPackages(m *bootstrapper.Manifest) error {
donePkgs := 0
pkgs := len(m.Packages)

log.Printf("Downloading %d Packages", pkgs)

return m.Packages.Perform(func(pkg bootstrapper.Package) error {
err := pkg.Fetch(filepath.Join(dirs.Downloads, pkg.Checksum), m.DeployURL)
if err != nil {
return err
}

donePkgs++
b.UI.Progress(float32(donePkgs) / float32(pkgs))

return nil
})
}

func (b *Binary) ExtractPackages(m *bootstrapper.Manifest) error {
donePkgs := 0
pkgs := len(m.Packages)
pkgDirs := bootstrapper.Directories(b.Type)

log.Printf("Extracting %d Packages", pkgs)

return m.Packages.Perform(func(pkg bootstrapper.Package) error {
dest, ok := pkgDirs[pkg.Name]

if !ok {
return fmt.Errorf("unhandled package: %s", pkg.Name)
}

err := pkg.Extract(
filepath.Join(dirs.Downloads, pkg.Checksum),
filepath.Join(b.Dir, dest),
)
if err != nil {
return err
}

donePkgs++
b.UI.Progress(float32(donePkgs) / float32(pkgs))

return nil
})
}

func (b *Binary) SetupDxvk() error {
ver, err := state.DxvkVersion()
if err != nil {
return err
}
installed := ver != ""

exitChan <- true
cmd.Wait()
if installed && !b.GlobalConfig.Player.Dxvk && !b.GlobalConfig.Studio.Dxvk {
b.UI.Message("Uninstalling DXVK")
if err := dxvk.Remove(b.Prefix); err != nil {
return err
}

if b.bcfg.AutoKillPrefix {
b.pfx.Kill()
return state.SaveDxvk("")
}

if !b.Config.Dxvk {
return nil
}

b.UI.Progress(0.0)
dxvk.Setenv()

if installed || b.GlobalConfig.DxvkVersion == ver {
return nil
}

if err := dirs.Mkdirs(dirs.Cache); err != nil {
return err
}
path := filepath.Join(dirs.Cache, "dxvk-"+b.GlobalConfig.DxvkVersion+".tar.gz")

b.UI.Progress(0.3)
b.UI.Message("Downloading DXVK")
if err := dxvk.Fetch(path, b.GlobalConfig.DxvkVersion); err != nil {
return err
}

b.UI.Progress(0.7)
b.UI.Message("Extracting DXVK")
if err := dxvk.Extract(path, b.Prefix); err != nil {
return err
}
b.UI.Progress(1.0)

return state.SaveDxvk(b.GlobalConfig.DxvkVersion)
}

func (b *Binary) Command(args ...string) (*wine.Cmd, error) {
if strings.HasPrefix(strings.Join(args, " "), "roblox-studio:1") {
args = []string{"-protocolString", args[0]}
}

if b.GlobalConfig.MultipleInstances {
mutexer := b.Prefix.Command("wine", filepath.Join(BinPrefix, "robloxmutexer.exe"))
err := mutexer.Start()
if err != nil {
return &wine.Cmd{}, err
}
}

cmd := b.Prefix.Wine(filepath.Join(b.Dir, b.Type.Executable()), args...)

launcher := strings.Fields(b.Config.Launcher)
if len(launcher) >= 1 {
cmd.Args = append(launcher, cmd.Args...)

launcherPath, err := exec.LookPath(launcher[0])
if err != nil {
return &wine.Cmd{}, err
}

cmd.Path = launcherPath
}

return cmd, nil
}
Loading

0 comments on commit 9d640cb

Please sign in to comment.