From 9237ae8fbc63154ff4eb634445cff0349b6354d6 Mon Sep 17 00:00:00 2001 From: mircearoata Date: Sun, 17 Dec 2023 21:44:57 +0100 Subject: [PATCH] Add support for remote servers --- backend/bindings/ficsitcli/installs.go | 18 ++++ backend/bindings/ficsitcli/process.go | 9 +- backend/bindings/ficsitcli/remote_servers.go | 93 ++++++++++++++++ backend/installfinders/epic_windows.go | 2 + .../installfinders/heroic_flatpak_linux.go | 2 + backend/installfinders/heroic_linux.go | 2 + backend/installfinders/heroic_windows.go | 2 + backend/installfinders/legendary_linux.go | 2 + backend/installfinders/legendary_windows.go | 2 + backend/installfinders/steam.go | 2 + backend/installfinders/types.go | 27 ++++- backend/installfinders/wine_linux.go | 2 + .../lib/components/left-bar/LeftBar.svelte | 2 + .../components/left-bar/ServerManager.svelte | 102 ++++++++++++++++++ .../lib/components/mods-list/ModsList.svelte | 2 +- frontend/src/lib/store/ficsitCLIStore.ts | 6 +- frontend/src/theme/_smui-theme.scss | 4 +- frontend/tailwind.config.cjs | 4 +- 18 files changed, 264 insertions(+), 19 deletions(-) create mode 100644 backend/bindings/ficsitcli/remote_servers.go create mode 100644 frontend/src/lib/components/left-bar/ServerManager.svelte diff --git a/backend/bindings/ficsitcli/installs.go b/backend/bindings/ficsitcli/installs.go index c6a52420..9bf4eaba 100644 --- a/backend/bindings/ficsitcli/installs.go +++ b/backend/bindings/ficsitcli/installs.go @@ -1,6 +1,7 @@ package ficsitcli import ( + "os" "os/exec" "sort" @@ -17,6 +18,11 @@ func (f *FicsitCLI) initInstallations() error { return errors.Wrap(err, "failed to initialize found installations") } + err = f.initRemoteServerInstallations() + if err != nil { + return errors.Wrap(err, "failed to initialize remote server installations") + } + sort.Slice(f.installations, func(i, j int) bool { if f.installations[i].Info.Launcher != f.installations[j].Info.Launcher { return f.installations[i].Info.Launcher < f.installations[j].Info.Launcher @@ -81,6 +87,18 @@ func (f *FicsitCLI) initLocalInstallations() error { return nil } +func (f *FicsitCLI) initRemoteServerInstallations() error { + for _, installation := range f.ficsitCli.Installations.Installations { + if _, err := os.Stat(installation.Path); errors.Is(err, os.ErrNotExist) { + // It is not a local installation + if err := f.AddRemoteServer(installation.Path); err != nil { + return errors.Wrap(err, "failed to add remote server") + } + } + } + return nil +} + func (f *FicsitCLI) GetInstallations() []*InstallationInfo { return f.installations } diff --git a/backend/bindings/ficsitcli/process.go b/backend/bindings/ficsitcli/process.go index defdd5a5..5ae5f06b 100644 --- a/backend/bindings/ficsitcli/process.go +++ b/backend/bindings/ficsitcli/process.go @@ -10,8 +10,6 @@ import ( "github.com/satisfactorymodding/ficsit-cli/cli" "github.com/satisfactorymodding/ficsit-cli/utils" wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime" - - "github.com/satisfactorymodding/SatisfactoryModManager/backend/installfinders" ) func (f *FicsitCLI) validateInstall(installation *InstallationInfo, progressItem string) error { @@ -134,11 +132,8 @@ func (f *FicsitCLI) EmitModsChange() { } func (f *FicsitCLI) EmitGlobals() { - installInfos := make([]*installfinders.Installation, 0, len(f.installations)) - for _, install := range f.installations { - installInfos = append(installInfos, install.Info) - } - wailsRuntime.EventsEmit(f.ctx, "installations", installInfos) + wailsRuntime.EventsEmit(f.ctx, "installations", f.GetInstallationsInfo()) + wailsRuntime.EventsEmit(f.ctx, "remoteServers", f.GetRemoteInstallations()) profileNames := make([]string, 0, len(f.ficsitCli.Profiles.Profiles)) for k := range f.ficsitCli.Profiles.Profiles { profileNames = append(profileNames, k) diff --git a/backend/bindings/ficsitcli/remote_servers.go b/backend/bindings/ficsitcli/remote_servers.go new file mode 100644 index 00000000..c9d362a0 --- /dev/null +++ b/backend/bindings/ficsitcli/remote_servers.go @@ -0,0 +1,93 @@ +package ficsitcli + +import ( + "github.com/pkg/errors" + + "github.com/satisfactorymodding/SatisfactoryModManager/backend/installfinders" +) + +func (f *FicsitCLI) GetRemoteInstallations() []*installfinders.Installation { + remoteInstallations := []*installfinders.Installation{} + for _, install := range f.installations { + if install.Info.Location == installfinders.LocationTypeRemote { + remoteInstallations = append(remoteInstallations, install.Info) + } + } + return remoteInstallations +} + +func (f *FicsitCLI) AddRemoteServer(path string) error { + installation := f.ficsitCli.Installations.GetInstallation(path) + if installation == nil { + fallbackProfile := "Default" + if f.ficsitCli.Profiles.GetProfile(fallbackProfile) == nil { + // Pick first profile found + for name := range f.ficsitCli.Profiles.Profiles { + fallbackProfile = name + break + } + } + + var err error + installation, err = f.ficsitCli.Installations.AddInstallation(f.ficsitCli, path, fallbackProfile) + if err != nil { + return errors.Wrap(err, "failed to add installation") + } + } + gameVersion, err := installation.GetGameVersion(f.ficsitCli) + if err != nil { + return errors.Wrap(err, "failed to get game version") + } + + platform, err := installation.GetPlatform(f.ficsitCli) + if err != nil { + return errors.Wrap(err, "failed to get platform") + } + var installType installfinders.InstallType + switch platform.TargetName { + case "Windows": + installType = installfinders.InstallTypeWindowsClient + case "WindowsServer": + installType = installfinders.InstallTypeWindowsServer + case "LinuxServer": + installType = installfinders.InstallTypeLinuxServer + } + + branch := installfinders.BranchEarlyAccess // TODO: Do we have a way to detect this for remote installs? + + f.installations = append(f.installations, &InstallationInfo{ + Installation: installation, + Info: &installfinders.Installation{ + Path: installation.Path, + Type: installType, + Location: installfinders.LocationTypeRemote, + Branch: branch, + Version: gameVersion, + Launcher: "Remote", + }, + }) + + f.EmitGlobals() + + return nil +} + +func (f *FicsitCLI) RemoveRemoteServer(path string) error { + for _, install := range f.installations { + if install.Info.Path == path && install.Info.Location != installfinders.LocationTypeRemote { + return errors.New("installation is not remote") + } + } + err := f.ficsitCli.Installations.DeleteInstallation(path) + if err != nil { + return errors.Wrap(err, "failed to delete installation") + } + for i, install := range f.installations { + if install.Info.Path == path { + f.installations = append(f.installations[:i], f.installations[i+1:]...) + break + } + } + f.EmitGlobals() + return nil +} diff --git a/backend/installfinders/epic_windows.go b/backend/installfinders/epic_windows.go index 8f1b1cf5..5dede9c2 100644 --- a/backend/installfinders/epic_windows.go +++ b/backend/installfinders/epic_windows.go @@ -121,6 +121,8 @@ func FindInstallationsWindowsEpic() ([]*Installation, []error) { installs = append(installs, &Installation{ Path: epicManifest.InstallLocation, Version: versionData.Changelist, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: "Epic Games", LaunchPath: []string{ diff --git a/backend/installfinders/heroic_flatpak_linux.go b/backend/installfinders/heroic_flatpak_linux.go index a42a5ef4..95f39bfe 100644 --- a/backend/installfinders/heroic_flatpak_linux.go +++ b/backend/installfinders/heroic_flatpak_linux.go @@ -59,6 +59,8 @@ func FindInstallationsLinuxHeroicFlatpak() ([]*Installation, []error) { installs = append(installs, &Installation{ Path: legendaryGame.InstallPath, Version: version, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: "Heroic", LaunchPath: nil, // Heroic doesn't support launching from command line diff --git a/backend/installfinders/heroic_linux.go b/backend/installfinders/heroic_linux.go index 29678feb..179074a9 100644 --- a/backend/installfinders/heroic_linux.go +++ b/backend/installfinders/heroic_linux.go @@ -59,6 +59,8 @@ func FindInstallationsLinuxHeroic() ([]*Installation, []error) { installs = append(installs, &Installation{ Path: legendaryGame.InstallPath, Version: version, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: "Heroic", LaunchPath: nil, // Heroic doesn't support launching from command line diff --git a/backend/installfinders/heroic_windows.go b/backend/installfinders/heroic_windows.go index f4d75d5f..26661bd1 100644 --- a/backend/installfinders/heroic_windows.go +++ b/backend/installfinders/heroic_windows.go @@ -65,6 +65,8 @@ func FindInstallationsWindowsHeroic() ([]*Installation, []error) { installs = append(installs, &Installation{ Path: legendaryGame.InstallPath, Version: version, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: "Heroic", LaunchPath: nil, // Heroic doesn't support launching from command line diff --git a/backend/installfinders/legendary_linux.go b/backend/installfinders/legendary_linux.go index 8a94d0cd..b5c327b7 100644 --- a/backend/installfinders/legendary_linux.go +++ b/backend/installfinders/legendary_linux.go @@ -58,6 +58,8 @@ func FindInstallationsLinuxLegendary() ([]*Installation, []error) { installs = append(installs, &Installation{ Path: legendaryGame.InstallPath, Version: version, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: "Legendary", LaunchPath: launchPath, diff --git a/backend/installfinders/legendary_windows.go b/backend/installfinders/legendary_windows.go index 50b393ef..e4861417 100644 --- a/backend/installfinders/legendary_windows.go +++ b/backend/installfinders/legendary_windows.go @@ -59,6 +59,8 @@ func FindInstallationsWindowsLegendary() ([]*Installation, []error) { installs = append(installs, &Installation{ Path: legendaryGame.InstallPath, Version: version, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: "Legendary", LaunchPath: launchPath, diff --git a/backend/installfinders/steam.go b/backend/installfinders/steam.go index a78eadfa..7a560571 100644 --- a/backend/installfinders/steam.go +++ b/backend/installfinders/steam.go @@ -136,6 +136,8 @@ func findInstallationsSteam(steamPath string, launcher string, executable []stri installs = append(installs, &Installation{ Path: fullInstallationPath, Version: versionData.Changelist, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: launcher, LaunchPath: append( diff --git a/backend/installfinders/types.go b/backend/installfinders/types.go index b0f3e12b..3d19d64e 100644 --- a/backend/installfinders/types.go +++ b/backend/installfinders/types.go @@ -13,12 +13,29 @@ var ( BranchExperimental GameBranch = "Experimental" ) +type InstallType string + +var ( + InstallTypeWindowsClient InstallType = "WindowsClient" + InstallTypeWindowsServer InstallType = "WindowsServer" + InstallTypeLinuxServer InstallType = "LinuxServer" +) + +type LocationType string + +var ( + LocationTypeLocal LocationType = "Local" + LocationTypeRemote LocationType = "Remote" +) + type Installation struct { - Path string `json:"path"` - Version int `json:"version"` - Branch GameBranch `json:"branch"` - Launcher string `json:"launcher"` - LaunchPath []string `json:"launchPath"` + Path string `json:"path"` + Version int `json:"version"` + Type InstallType `json:"type"` + Location LocationType `json:"location"` + Branch GameBranch `json:"branch"` + Launcher string `json:"launcher"` + LaunchPath []string `json:"launchPath"` } type InstallFindError struct { diff --git a/backend/installfinders/wine_linux.go b/backend/installfinders/wine_linux.go index b908da21..5afe0b40 100644 --- a/backend/installfinders/wine_linux.go +++ b/backend/installfinders/wine_linux.go @@ -129,6 +129,8 @@ func findInstallationsWineEpic(winePrefix string, launcher string, launchPath [] installs = append(installs, &Installation{ Path: wineInstallLocation, Version: versionData.Changelist, + Type: InstallTypeWindowsClient, + Location: LocationTypeLocal, Branch: branch, Launcher: launcher, LaunchPath: launchPath, diff --git a/frontend/src/lib/components/left-bar/LeftBar.svelte b/frontend/src/lib/components/left-bar/LeftBar.svelte index 1baed406..c9e6266d 100644 --- a/frontend/src/lib/components/left-bar/LeftBar.svelte +++ b/frontend/src/lib/components/left-bar/LeftBar.svelte @@ -12,6 +12,7 @@ import Settings from './Settings.svelte'; import Updates from './Updates.svelte'; import LaunchButton from './LaunchButton.svelte'; + import ServerManager from './ServerManager.svelte'; import SvgIcon from '$lib/components/SVGIcon.svelte'; import { installs, profiles, canModify, selectedInstall, selectedInstallPath, selectedProfile, modsEnabled, progress } from '$lib/store/ficsitCLIStore'; @@ -307,6 +308,7 @@
Other + + + + Dedicated Servers + + + + {#each $remoteServers as remoteServer} + + {remoteServer.path} + {remoteServer.type} + {remoteServer.version} + + + + + {/each} + + +
+
+ + + +
+

{err}

+
+
+ + + +
diff --git a/frontend/src/lib/components/mods-list/ModsList.svelte b/frontend/src/lib/components/mods-list/ModsList.svelte index 1f4e07b7..03f2e887 100644 --- a/frontend/src/lib/components/mods-list/ModsList.svelte +++ b/frontend/src/lib/components/mods-list/ModsList.svelte @@ -143,7 +143,7 @@
-
+
diff --git a/frontend/src/lib/store/ficsitCLIStore.ts b/frontend/src/lib/store/ficsitCLIStore.ts index 5deb0055..9a4f40b3 100644 --- a/frontend/src/lib/store/ficsitCLIStore.ts +++ b/frontend/src/lib/store/ficsitCLIStore.ts @@ -4,17 +4,19 @@ import { binding, bindingTwoWay } from './wailsStoreBindings'; import { isLaunchingGame } from './generalStore'; import type { cli, ficsitcli } from '$wailsjs/go/models'; -import { CheckForUpdates, GetInstallationsInfo, GetInvalidInstalls, GetProfiles, GetSelectedInstall, GetSelectedProfile, SelectInstall, SetProfile, GetModsEnabled, SetModsEnabled, GetSelectedInstallProfileMods, GetSelectedInstallLockfileMods } from '$wailsjs/go/ficsitcli/FicsitCLI'; +import { CheckForUpdates, GetInstallationsInfo, GetInvalidInstalls, GetProfiles, GetSelectedInstall, GetSelectedProfile, SelectInstall, SetProfile, GetModsEnabled, SetModsEnabled, GetSelectedInstallProfileMods, GetSelectedInstallLockfileMods, GetRemoteInstallations } from '$wailsjs/go/ficsitcli/FicsitCLI'; import { GetFavoriteMods } from '$wailsjs/go/bindings/Settings'; export const invalidInstalls = binding([], { initialGet: GetInvalidInstalls }); -export const installs = binding([], { initialGet: GetInstallationsInfo, updateEvent: 'installs' }); +export const installs = binding([], { initialGet: GetInstallationsInfo, updateEvent: 'installs', allowNull: false }); export const selectedInstallPath = bindingTwoWay(null, { initialGet: () => GetSelectedInstall().then((i) => i?.path ?? null), updateEvent: 'selectedInstall' }, { updateFunction: SelectInstall }); export const selectedInstall = derived([installs, selectedInstallPath], ([$installs, $selectedInstallPath]) => { return $installs.find((i) => i.path === $selectedInstallPath) ?? null; }); +export const remoteServers = binding([], { initialGet: () => GetRemoteInstallations(), updateEvent: 'remoteServers', allowNull: false }); + export const profiles = binding([], { initialGet: GetProfiles, updateEvent: 'profiles' }); export const selectedProfile = bindingTwoWay(null, { initialGet: GetSelectedProfile, updateEvent: 'selectedProfile', allowNull: false }, { updateFunction: SetProfile }); diff --git a/frontend/src/theme/_smui-theme.scss b/frontend/src/theme/_smui-theme.scss index 0094c624..a031f66e 100644 --- a/frontend/src/theme/_smui-theme.scss +++ b/frontend/src/theme/_smui-theme.scss @@ -50,8 +50,8 @@ $white-darker: #d5d5d5; @include linear-progress.buffer-color($grey-darker); } -$md: 825px; -$lg: 900px; +$md: 875px; +$lg: 950px; $left-bar-controls-background: $grey-darker; $left-bar-controls-height-sm: 30px; diff --git a/frontend/tailwind.config.cjs b/frontend/tailwind.config.cjs index be0571cb..54994c24 100644 --- a/frontend/tailwind.config.cjs +++ b/frontend/tailwind.config.cjs @@ -6,8 +6,8 @@ module.exports = { theme: { extend: { screens: { - 'h-md': { raw: '(min-height: 825px)' }, - 'h-lg': { raw: '(min-height: 900px)' }, + 'h-md': { raw: '(min-height: 875px)' }, + 'h-lg': { raw: '(min-height: 950px)' }, }, }, },