164 lines
4.1 KiB
Go
Executable File
164 lines
4.1 KiB
Go
Executable File
package commands
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"mccl/internal/manifest"
|
|
mcclprofile "mccl/internal/mccl_profile"
|
|
"mccl/pkg/util"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
type RunCommand struct {
|
|
Id string
|
|
GameDir string
|
|
Username string
|
|
AuthUuid string
|
|
JavaXmx string
|
|
UseProfile bool
|
|
}
|
|
|
|
func NewRunCommand(id, gameDir, user, uuid, jxmx string, useProfile bool) *RunCommand {
|
|
return &RunCommand{Id: id, GameDir: gameDir, Username: user, AuthUuid: uuid, JavaXmx: jxmx, UseProfile: useProfile}
|
|
}
|
|
|
|
func (rc *RunCommand) Run() error {
|
|
if rc.Id == "" {
|
|
return errors.New("an empty Minecraft version was provided")
|
|
}
|
|
if err := os.Chdir(rc.GameDir); err != nil {
|
|
return err
|
|
}
|
|
if rc.UseProfile {
|
|
if util.IsFileExist(path.Join(rc.GameDir, mcclprofile.ProfileFileName)) {
|
|
p, err := mcclprofile.Load(rc.GameDir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rc.Username = p.Username
|
|
rc.AuthUuid = p.Uuid
|
|
rc.JavaXmx = p.JavaXmx
|
|
} else {
|
|
p := mcclprofile.Profile{
|
|
Username: rc.Username,
|
|
Uuid: rc.AuthUuid,
|
|
JavaXmx: rc.JavaXmx}
|
|
if err := p.Store(rc.GameDir); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return rc.run_client()
|
|
}
|
|
|
|
func (rc *RunCommand) run_client() error {
|
|
manifestPath := path.Join(rc.GameDir, "versions", rc.Id, rc.Id+".json")
|
|
|
|
data, err := util.ReadFile(manifestPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
manifst, err := manifest.New(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if manifst.InheritsFrom != "" {
|
|
manifestPath := path.Join(rc.GameDir, "versions", manifst.InheritsFrom, manifst.InheritsFrom+".json")
|
|
|
|
data, err := util.ReadFile(manifestPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
inherit, err := manifest.New(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := manifst.InheritFrom(inherit); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
p := make(map[string]string)
|
|
|
|
p["auth_player_name"] = rc.Username
|
|
p["version_name"] = manifst.Id
|
|
p["game_directory"] = rc.GameDir
|
|
p["assets_root"] = "assets"
|
|
p["game_assets"] = p["assets_root"]
|
|
p["assets_index_name"] = manifst.AssetIndex.Id
|
|
p["auth_uuid"] = rc.AuthUuid
|
|
p["auth_access_token"] = "null"
|
|
p["auth_session"] = p["auth_access_token"]
|
|
p["clientid"] = manifst.Id
|
|
p["auth_xuid"] = "null"
|
|
p["user_type"] = "legacy"
|
|
p["version_type"] = manifst.Type
|
|
p["natives_directory"] = path.Join("", "versions", manifst.Id, "natives")
|
|
p["launcher_name"] = "mccl"
|
|
p["launcher_version"] = "0.1.0"
|
|
p["classpath"] = manifst.BuildClasspath("", "versions")
|
|
if manifst.Logging.Client.File.Id != "" {
|
|
p["logging_path"] = path.Join("assets", "log_configs", manifst.Logging.Client.File.Id)
|
|
}
|
|
|
|
if strings.Contains(manifst.Id, "forge") {
|
|
p["library_directory"] = "libraries"
|
|
p["classpath_separator"] = util.PathSeparator()
|
|
}
|
|
|
|
cl := manifst.BuildCommandLine(p)
|
|
|
|
if rc.JavaXmx != "" {
|
|
ok, err := regexp.MatchString("^\\d+(K|k|M|m|G|g|T|t)$", rc.JavaXmx)
|
|
if ok && err == nil {
|
|
rc.JavaXmx = "-Xmx" + rc.JavaXmx
|
|
tcl := []string{}
|
|
tcl = append(tcl, rc.JavaXmx)
|
|
cl = append(tcl, cl...)
|
|
} else if err != nil || !ok {
|
|
if err != nil {
|
|
fmt.Printf("An error occured while parsing Java -Xmx parameter: %s. Game's default will be used. ", err)
|
|
} else {
|
|
fmt.Printf("Mismatch occured while parsing Java -Xmx parameter. Game's default will be used. ")
|
|
}
|
|
fmt.Printf("Right form is <number>Kk|Mm|Gg|Tt, e.g. 4G.")
|
|
}
|
|
}
|
|
|
|
javaHome, err := util.LocateJavaHome(manifst.JavaVersion.Component, manifst.JavaVersion.MajorVersion)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cmd := exec.Command(path.Join(javaHome, "bin", "java"), cl...)
|
|
// stdout, err := cmd.StdoutPipe()
|
|
// cmd.Stderr = cmd.Stdout
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// defer stdout.Close()
|
|
|
|
// scanner := bufio.NewScanner(stdout)
|
|
// go func() {
|
|
// for scanner.Scan() {
|
|
// fmt.Println(scanner.Text())
|
|
// }
|
|
// }()
|
|
|
|
fmt.Printf("Minecraft version %s is started with usename %s and player's UUID %s.\n",
|
|
manifst.Id, rc.Username, rc.AuthUuid)
|
|
if err := cmd.Run(); err != nil && (err.Error() != "exec: already started") {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|