1
0
Fork 0
mccl/cmd/mccl/commands/run_command.go

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
}