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

233 lines
5.8 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(0)
}
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, "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 minecraft's version \n"+
" directory a path to where Minecraft will be installed\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 are 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 len(args[i]) > 2 && args[i][0] == '-' && args[i][1] == '-' {
switch args[i][2:] {
case "version":
parsed.ShowVersion = true
case "help":
parsed.ShowHelp = true
case "demand-press-enter":
parsed.DemandPressEnter = true
case "username":
if len(args) == i+1 || args[i+1][0] == '-' {
err = errNoOptArg{ArgName: args[i]}
return
}
parsed.Username = args[i+1]
i++
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
}
} else if args[i][0] == '-' && len(args[i]) > 1 {
for _, option := range args[i][1:] {
switch option {
case 'v':
parsed.ShowVersion = true
case 'h':
parsed.ShowHelp = true
case 'u':
if len(args) == i+1 || args[i+1][0] == '-' {
err = errNoOptArg{ArgName: args[i]}
return
}
parsed.Username = args[i+1]
i++
case 'U':
if len(args) == i+1 || args[i+1][0] == '-' {
err = errNoOptArg{ArgName: args[i]}
return
}
parsed.Uuid = args[i+1]
i++
default:
err = fmt.Errorf("an unknown option %c was provided", option)
return
}
}
} else {
if parsed.Command != "" {
err = fmt.Errorf("only one command should present")
return
}
switch parsed.Command = args[i]; parsed.Command {
case "i":
fallthrough
case "install":
fallthrough
case "r":
fallthrough
case "run":
if len(args) <= i+3 || args[i+1][0] == '-' || args[i+2][0] == '-' {
err = fmt.Errorf("not enough arguments was provided")
return
}
parsed.GameVersion = args[i+1]
parsed.Directory = args[i+2]
i += 2
case "l":
fallthrough
case "list":
if len(args) <= i+2 || args[i+1][0] == '-' {
err = fmt.Errorf("not enough arguments was provided")
return
}
parsed.Directory = args[i+1]
i++
default:
err = fmt.Errorf("an unknown command %s was provided", parsed.Command)
return
}
}
}
return
}