1
0
Fork 0
mccl/cmd/mccl/main.go

215 lines
5.4 KiB
Go
Executable File

package main
import (
"fmt"
"mccl/cmd/mccl/commands"
mcclprofile "mccl/internal/mccl_profile"
"os"
)
var programVersion string
func main() {
args, err := parseArguments(os.Args[1:])
if err != nil {
fmt.Fprintln(os.Stderr, err)
usage()
os.Exit(1)
}
if args.ShowVersion {
version()
}
if args.ShowHelp {
usage()
}
if args.ShowHelp || args.ShowVersion {
os.Exit(0)
}
if len(os.Args) < 2 {
usage()
os.Exit(1)
}
var cmd commands.Command
switch args.Command {
case "install":
fallthrough
case "i":
cmd = commands.NewInstallCommand(args.GameVersion, args.Directory)
case "run":
fallthrough
case "r":
cmd = commands.NewRunCommand(args.GameVersion, args.Directory,
args.Username, args.Uuid, args.JavaXmx, args.UseProfile)
case "list":
fallthrough
case "l":
cmd = commands.NewListCommand(args.Directory)
default:
usage()
os.Exit(0)
}
exitCode := 0
if err := cmd.Run(); err != nil {
fmt.Println(err)
exitCode = 1
}
if args.DemandPressEnter {
fmt.Fprint(os.Stderr, "Press the enter key to continue...")
fmt.Scanln()
}
os.Exit(exitCode)
}
func version() {
fmt.Fprintf(os.Stderr, "mccl ver. %s\nCopyright (c) 2023 Alexander \"Arav\" Andreev <me@arav.su>\n", programVersion)
fmt.Fprintln(os.Stderr, "URL: https://git.arav.su/Arav/mccl")
fmt.Fprintln(os.Stderr, "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.")
}
func usage() {
fmt.Fprintln(os.Stderr, "Usage: mccl [<common options>]... command arguments... [options]...")
fmt.Fprintln(os.Stderr, "Common options:\n"+
" -h,--help show help\n"+
" -v,--version show version\n"+
" --demand-press-enter\n"+
" ask to press the enter key before closing\n"+
"Commands:\n"+
" \033[1minstall|i\033[0m version directory\n"+
" Install any vanilla version (for mod loaders use theirs installers)\n"+
" \033[1mrun|r\033[0m version directory [-u username] [-U UUID] [-java-Xmx memory] [--profile]\n"+
" Run vanilla, forge, fabric, quilt, the others aren't tested\n"+
" \033[1mlist|l\033[0m directory\n"+
" List all installed versions in directory\n"+
"Explanation of arguments and options for commands:\n"+
" version version of a game (name of a dir inside versions dir)\n"+
" directory a path to where Minecraft will be installed / or will be runned from\n"+
" -u,--username username\n"+
" player's username (Anonymous by default)\n"+
" -U,--uuid UUID\n"+
" player's account UUID (all zeroes by default)\n"+
" --java-Xmx memory\n"+
" java's -Xmx param, e.g. 4G\n"+
" --profile\n"+
" load/save username, UUID, and -Xmx from/to a file.\n"+
" Once saved, you can ommit -u,-U and --java-Xmx,\n"+
" since they will be stored in", mcclprofile.ProfileFileName)
}
type arguments struct {
ShowVersion bool
ShowHelp bool
DemandPressEnter bool
Command string
GameVersion string
Directory string
Username string
Uuid string
JavaXmx string
UseProfile bool
}
type errNoOptArg struct {
ArgName string
}
func (e errNoOptArg) Error() string {
return fmt.Sprintf("%s option demands an argument, but it wasn't provided", e.ArgName)
}
func parseArguments(args []string) (parsed arguments, err error) {
parsed.Username = "Anonymous"
parsed.Directory = "."
parsed.Uuid = "00000000-0000-0000-0000-000000000000"
for i := 0; i < len(args); i++ {
if args[i][0] != '-' {
if parsed.Command != "" {
return parsed, fmt.Errorf("there is already a command %s, but a second one (%s) was provided",
parsed.Command, args[i])
}
parsed.Command = args[i]
switch parsed.Command {
case "i":
fallthrough
case "install":
fallthrough
case "r":
fallthrough
case "run":
if i+3 > len(args) || args[i+1][0] == '-' {
return parsed, fmt.Errorf("a command %s is missing its version and directory arguments",
parsed.Command)
}
parsed.GameVersion = args[i+1]
parsed.Directory = args[i+2]
i += 2
case "l":
fallthrough
case "list":
if i+1 >= len(args) || args[i+1][0] == '-' {
return parsed, fmt.Errorf("a command list is missing its directory argument")
}
parsed.Directory = args[i+1]
i++
}
continue
}
switch args[i] {
case "-v":
fallthrough
case "--version":
parsed.ShowVersion = true
case "-h":
fallthrough
case "--help":
parsed.ShowHelp = true
case "--demand-press-enter":
parsed.DemandPressEnter = true
case "-u":
fallthrough
case "--username":
if len(args) == i+1 || args[i+1][0] == '-' {
err = errNoOptArg{ArgName: args[i]}
return
}
parsed.Username = args[i+1]
i++
case "-U":
fallthrough
case "--uuid":
if len(args) == i+1 || args[i+1][0] == '-' {
err = errNoOptArg{ArgName: args[i]}
return
}
parsed.Uuid = args[i+1]
i++
case "--java-Xmx":
if len(args) == i+1 || args[i+1][0] == '-' {
err = errNoOptArg{ArgName: args[i]}
return
}
parsed.JavaXmx = args[i+1]
i++
case "--profile":
parsed.UseProfile = true
default:
err = fmt.Errorf("an unknown option %s was provided", args[i])
return
}
}
return
}