Skip to content

Commit

Permalink
feat: Introduce action urls and launch-only action
Browse files Browse the repository at this point in the history
implements #3
  • Loading branch information
cetteup committed Jul 30, 2022
1 parent 737dfed commit 70f2377
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 41 deletions.
2 changes: 1 addition & 1 deletion cmd/joinme.click-launcher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func main() {
Msg("Checked status for")
}
} else if len(args) == 1 {
err := gameRouter.StartGame(args[0])
err := gameRouter.RunURL(args[0])
if err != nil {
log.Error().
Err(err).
Expand Down
69 changes: 60 additions & 9 deletions internal/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/url"
"os"
"path/filepath"
"strings"

"github.com/cetteup/joinme.click-launcher/internal"
"github.com/cetteup/joinme.click-launcher/internal/domain"
Expand All @@ -14,6 +15,9 @@ import (
"golang.org/x/sys/windows/registry"
)

type Action int
type ActionPathKey string

const (
RegPathSoftware = "SOFTWARE"
RegPathClasses = "Classes"
Expand All @@ -22,6 +26,13 @@ const (
RegPathCommand = "command"
RegKeyDefault = ""
RegKeyURLProtocol = "URL Protocol"

ActionUrlHostname = "act"

ActionLaunchAndJoin Action = iota
ActionLaunchOnly

ActionPathKeyLaunch ActionPathKey = "launch"
)

type RegistryRepository interface {
Expand Down Expand Up @@ -194,7 +205,7 @@ func (r GameRouter) getHandlerCommand() (string, error) {
return fmt.Sprintf("\"%s\" \"%%1\"", launcherPath), nil
}

func (r GameRouter) StartGame(commandLineUrl string) error {
func (r GameRouter) RunURL(commandLineUrl string) error {
u, err := url.Parse(commandLineUrl)
if err != nil {
return err
Expand All @@ -205,30 +216,70 @@ func (r GameRouter) StartGame(commandLineUrl string) error {
return fmt.Errorf("game not supported: %s", u.Scheme)
}

if err = gameTitle.URLValidator(u); err != nil {
action, err := r.getActionFromURL(u)
if err != nil {
return err
}

switch action {
case ActionLaunchOnly:
return r.startGame(gameTitle, u, game_launcher.LaunchTypeLaunchOnly)
default:
return r.startGame(gameTitle, u, game_launcher.LaunchTypeLaunchAndJoin)
}
}

func (r GameRouter) startGame(gameTitle domain.GameTitle, u *url.URL, launchType game_launcher.LaunchType) error {
// Only join url use/require URL parameters, so only validate those
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
err := gameTitle.URLValidator(u)
if err != nil {
return err
}
}

// Build final launcher config
launcherConfig := gameTitle.LauncherConfig
if gameTitle.RequiresPlatformClient() {
launcherConfig.ExecutableName = gameTitle.PlatformClient.LauncherConfig.ExecutableName
launcherConfig.ExecutablePath = gameTitle.PlatformClient.LauncherConfig.ExecutablePath
launcherConfig.InstallPath, err = r.finder.GetInstallDir(gameTitle.PlatformClient.FinderConfig)
installPath, err := r.finder.GetInstallDir(gameTitle.PlatformClient.FinderConfig)
if err != nil {
return err
}
launcherConfig.InstallPath = installPath
} else {
launcherConfig.InstallPath, err = r.finder.GetInstallDirFromSomewhere(gameTitle.FinderConfigs)
}
if err != nil {
return err
installPath, err := r.finder.GetInstallDirFromSomewhere(gameTitle.FinderConfigs)
if err != nil {
return err
}
launcherConfig.InstallPath = installPath
}

// Always use the game launcher.Config for preparation, since we need to (for example) kill the game, not the platform client before launch
if err = game_launcher.PrepareLaunch(gameTitle.LauncherConfig); err != nil {
if err := game_launcher.PrepareLaunch(gameTitle.LauncherConfig); err != nil {
return err
}
if err = game_launcher.StartGame(u, launcherConfig, gameTitle.CmdBuilder); err != nil {
if err := game_launcher.StartGame(u, launcherConfig, launchType, gameTitle.CmdBuilder); err != nil {
return err
}

return nil
}

func (r GameRouter) getActionFromURL(u *url.URL) (Action, error) {
if !r.isActionURL(u) {
return ActionLaunchAndJoin, nil
}

switch strings.TrimPrefix(u.Path, "/") {
case string(ActionPathKeyLaunch):
return ActionLaunchOnly, nil
default:
return 0, fmt.Errorf("action not supported: %s", u.Path)
}
}

func (r GameRouter) isActionURL(u *url.URL) bool {
return u.Hostname() == ActionUrlHostname
}
8 changes: 6 additions & 2 deletions internal/titles/bf1.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ var Bf1 = domain.GameTitle{
CloseBeforeLaunch: true,
},
URLValidator: internal.Frostbite3GameIdURLValidator,
CmdBuilder: func(u *url.URL, config game_launcher.Config) ([]string, error) {
args := append(internal.Frostbite3DefaultArgs, "-gameId", u.Hostname())
CmdBuilder: func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
var args []string
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
args = append(args, internal.Frostbite3DefaultArgs...)
args = append(args, "-gameId", u.Hostname())
}

offerIDs := []string{"1026023"}
originURL := internal.BuildOriginURL(offerIDs, args)
Expand Down
8 changes: 4 additions & 4 deletions internal/titles/bf1942.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ var Bf1942 = domain.GameTitle{
CmdBuilder: bf1942CmdBuilder,
}

var bf1942CmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config) ([]string, error) {
args := []string{
"+joinServer", u.Hostname(),
"+port", u.Port(),
var bf1942CmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
var args []string
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
args = append(args, "+joinServer", u.Hostname(), "+port", u.Port())
}

query := u.Query()
Expand Down
10 changes: 4 additions & 6 deletions internal/titles/bf2.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var Bf2 = domain.GameTitle{
CmdBuilder: bf2CmdBuilder,
}

var bf2CmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config) ([]string, error) {
var bf2CmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
profileCon, err := internal.GetDefaultUserProfileCon(bf2ProfileFolder)
if err != nil {
return nil, err
Expand All @@ -57,11 +57,9 @@ var bf2CmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_la
return nil, err
}

args := []string{
"+joinServer", u.Hostname(),
"+port", u.Port(),
"+playerName", playerName,
"+playerPassword", password,
args := []string{"+playerName", playerName, "+playerPassword", password}
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
args = append(args, "+joinServer", u.Hostname(), "+port", u.Port())
}

query := u.Query()
Expand Down
8 changes: 6 additions & 2 deletions internal/titles/bf4.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ var Bf4 = domain.GameTitle{
CloseBeforeLaunch: true,
},
URLValidator: internal.Frostbite3GameIdURLValidator,
CmdBuilder: func(u *url.URL, config game_launcher.Config) ([]string, error) {
args := append(internal.Frostbite3DefaultArgs, "-gameId", u.Hostname())
CmdBuilder: func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
var args []string
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
args = append(args, internal.Frostbite3DefaultArgs...)
args = append(args, "-gameId", u.Hostname())
}

offerIDs := []string{"1007968", "1011575", "1011576", "1011577", "1010268", "1010269", "1010270", "1010271", "1010958", "1010959", "1010960", "1010961", "1007077", "1016751", "1016757", "1016754", "1015365", "1015364", "1015363", "1015362"}
originURL := internal.BuildOriginURL(offerIDs, args)
Expand Down
8 changes: 4 additions & 4 deletions internal/titles/bfvietnam.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ var BfVietnam = domain.GameTitle{
CloseBeforeLaunch: true,
},
URLValidator: internal.IPPortURLValidator,
CmdBuilder: func(u *url.URL, config game_launcher.Config) ([]string, error) {
args := []string{
"+joinServer", u.Hostname(),
"+port", u.Port(),
CmdBuilder: func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
var args []string
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
args = append(args, "+joinServer", u.Hostname(), "+port", u.Port())
}

query := u.Query()
Expand Down
7 changes: 5 additions & 2 deletions internal/titles/fear_sec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ var FearSec2 = domain.GameTitle{
CloseBeforeLaunch: true,
},
URLValidator: internal.IPPortURLValidator,
CmdBuilder: func(u *url.URL, config game_launcher.Config) ([]string, error) {
return []string{"+join", fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, nil
CmdBuilder: func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
return []string{"+join", fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, nil
}
return nil, nil
},
}
7 changes: 5 additions & 2 deletions internal/titles/internal/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ var Frostbite3DefaultArgs = []string{
"-joinWithParty", "false",
}

var PlusConnectCmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config) ([]string, error) {
return []string{"+connect", fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, nil
var PlusConnectCmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
return []string{"+connect", fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, nil
}
return nil, nil
}
7 changes: 5 additions & 2 deletions internal/titles/paraworld.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ var Paraworld = domain.GameTitle{
},
},
URLValidator: internal.IPPortURLValidator,
CmdBuilder: func(u *url.URL, config game_launcher.Config) ([]string, error) {
args := []string{"-autoconnect", fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}
CmdBuilder: func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
var args []string
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
args = append(args, "-autoconnect", fmt.Sprintf("%s:%s", u.Hostname(), u.Port()))
}

query := u.Query()
if internal.QueryHasMod(query) {
Expand Down
7 changes: 5 additions & 2 deletions internal/titles/swat4.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ var Swat4 = domain.GameTitle{
CmdBuilder: swat4CmdBuilder,
}

var swat4CmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config) ([]string, error) {
return []string{fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, nil
var swat4CmdBuilder game_launcher.CommandBuilder = func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
return []string{fmt.Sprintf("%s:%s", u.Hostname(), u.Port())}, nil
}
return nil, nil
}

var Swat4X = domain.GameTitle{
Expand Down
7 changes: 5 additions & 2 deletions internal/titles/vietcong.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ var Vietcong = domain.GameTitle{
CloseBeforeLaunch: true,
},
URLValidator: internal.IPPortURLValidator,
CmdBuilder: func(u *url.URL, config game_launcher.Config) ([]string, error) {
return []string{"-ip", u.Hostname(), "-port", u.Port()}, nil
CmdBuilder: func(u *url.URL, config game_launcher.Config, launchType game_launcher.LaunchType) ([]string, error) {
if launchType == game_launcher.LaunchTypeLaunchAndJoin {
return []string{"-ip", u.Hostname(), "-port", u.Port()}, nil
}
return nil, nil
},
}
10 changes: 7 additions & 3 deletions pkg/game_launcher/game_launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ import (
)

type LaunchDir int
type LaunchType int

const (
LaunchDirInstallDir LaunchDir = iota
LaunchDirBinaryDir

LaunchTypeLaunchAndJoin LaunchType = iota
LaunchTypeLaunchOnly
)

type Config struct {
Expand All @@ -35,7 +39,7 @@ type Config struct {

type URLValidator func(u *url.URL) error

type CommandBuilder func(u *url.URL, config Config) ([]string, error)
type CommandBuilder func(u *url.URL, config Config, launchType LaunchType) ([]string, error)

func PrepareLaunch(config Config) error {
if !config.CloseBeforeLaunch {
Expand Down Expand Up @@ -69,8 +73,8 @@ func PrepareLaunch(config Config) error {
return nil
}

func StartGame(u *url.URL, config Config, cmdBuilder CommandBuilder) error {
args, err := cmdBuilder(u, config)
func StartGame(u *url.URL, config Config, launchType LaunchType, cmdBuilder CommandBuilder) error {
args, err := cmdBuilder(u, config, launchType)
if err != nil {
return err
}
Expand Down

0 comments on commit 70f2377

Please sign in to comment.