2023-10-30 02:18:41 +04:00
|
|
|
package manifest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"mccl/pkg/util"
|
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Manifest struct {
|
|
|
|
InheritsFrom string `json:"inheritsFrom"`
|
|
|
|
Arguments struct {
|
|
|
|
Game []Argument `json:"game"`
|
|
|
|
Jvm []Argument `json:"jvm"`
|
|
|
|
} `json:"arguments"`
|
|
|
|
AssetIndex struct {
|
|
|
|
util.File
|
|
|
|
TotalSize int `json:"totalSize"`
|
|
|
|
} `json:"assetIndex"`
|
|
|
|
Assets string `json:"assets"`
|
|
|
|
ComplianceLevel int `json:"complianceLevel"`
|
|
|
|
Downloads map[string]util.File `json:"downloads"`
|
|
|
|
Id string `json:"id"`
|
|
|
|
JavaVersion struct {
|
|
|
|
Component string `json:"component"`
|
|
|
|
MajorVersion int `json:"majorVersion"`
|
|
|
|
} `json:"javaVersion"`
|
|
|
|
Libraries []Library `json:"libraries"`
|
|
|
|
Logging struct {
|
|
|
|
Client struct {
|
|
|
|
Argument string `json:"argument"`
|
|
|
|
File util.File `json:"file"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
} `json:"client"`
|
|
|
|
} `json:"logging"`
|
|
|
|
MainClass string `json:"mainClass"`
|
|
|
|
MinecraftArguments string `json:"minecraftArguments"`
|
|
|
|
MinimumLauncherVersion int `json:"minimumLauncherVersion"`
|
|
|
|
ReleaseTime string `json:"releaseTime"`
|
|
|
|
Time string `json:"time"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// New returns a new Manifest for a specific Minecraft version.
|
|
|
|
func New(data []byte) (*Manifest, error) {
|
|
|
|
m := &Manifest{}
|
|
|
|
if err := json.Unmarshal(data, m); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Manifest) BuildCommandLine(properties map[string]string) (arguments []string) {
|
|
|
|
if m.MinecraftArguments != "" {
|
|
|
|
arguments = append(arguments, fmt.Sprintf("-Djava.library.path=%s", properties["natives_directory"]))
|
|
|
|
arguments = append(arguments, "-cp")
|
|
|
|
arguments = append(arguments, properties["classpath"])
|
|
|
|
arguments = append(arguments, m.MainClass)
|
|
|
|
args := strings.Split(m.MinecraftArguments, " ")
|
|
|
|
for _, arg := range args {
|
|
|
|
if strings.HasPrefix(arg, "${") {
|
|
|
|
propName := arg[2 : len(arg)-1]
|
|
|
|
arg = properties[propName]
|
|
|
|
}
|
|
|
|
arguments = append(arguments, arg)
|
|
|
|
}
|
|
|
|
return arguments
|
|
|
|
}
|
|
|
|
|
|
|
|
var allArgs []Argument
|
|
|
|
|
|
|
|
allArgs = append(allArgs, m.Arguments.Jvm...)
|
|
|
|
|
|
|
|
if m.Logging.Client.Argument != "" {
|
|
|
|
logConf := strings.Split(m.Logging.Client.Argument, "${")[0]
|
|
|
|
logConf += properties["logging_path"]
|
|
|
|
allArgs = append(allArgs, Argument{Value: []string{logConf}})
|
|
|
|
}
|
|
|
|
|
|
|
|
allArgs = append(allArgs, Argument{Value: []string{m.MainClass}})
|
|
|
|
allArgs = append(allArgs, m.Arguments.Game...)
|
|
|
|
|
|
|
|
for _, arg := range allArgs {
|
|
|
|
ok, feature := arg.CheckRules()
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
} else if feature != FeatureUnknown {
|
|
|
|
if _, ok := properties[feature.String()]; !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range arg.Value {
|
|
|
|
if strings.Contains(v, "${library_directory}") {
|
|
|
|
v = strings.ReplaceAll(v, "${library_directory}", properties["library_directory"])
|
|
|
|
v = strings.ReplaceAll(v, "${classpath_separator}", properties["classpath_separator"])
|
|
|
|
} else if i := strings.Index(v, "${"); i != -1 {
|
|
|
|
j := strings.Index(v, "}")
|
|
|
|
propName := v[i+2 : j]
|
|
|
|
switch propName {
|
|
|
|
case "version_name":
|
|
|
|
if strings.Contains(m.Id, "forge") {
|
|
|
|
v = strings.ReplaceAll(v, "${version_name}", m.InheritsFrom)
|
|
|
|
} else {
|
|
|
|
v = strings.ReplaceAll(v, "${version_name}", m.Id)
|
|
|
|
}
|
|
|
|
|
|
|
|
case "assets_index_name":
|
|
|
|
v = m.Assets
|
|
|
|
case "version_type":
|
|
|
|
v = m.Type
|
|
|
|
default:
|
|
|
|
v = strings.Replace(v, v[i:j+1], properties[propName], 1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
arguments = append(arguments, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return arguments
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Manifest) BuildClasspath(baseDir, clientPath string) string {
|
|
|
|
var sb []string = make([]string, 0, len(m.Libraries))
|
|
|
|
for _, lib := range m.Libraries {
|
|
|
|
if lib.CheckRules() {
|
|
|
|
sb = append(sb, path.Join(baseDir, "libraries", lib.Path()))
|
|
|
|
if natives := lib.Natives(); natives != nil {
|
|
|
|
sb = append(sb, path.Join(baseDir, "libraries", natives.Path))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.InheritsFrom != "" {
|
|
|
|
sb = append(sb, path.Join(clientPath, m.InheritsFrom, m.InheritsFrom+".jar"))
|
|
|
|
} else {
|
|
|
|
sb = append(sb, path.Join(clientPath, m.Id, m.Id+".jar"))
|
|
|
|
}
|
|
|
|
|
|
|
|
return strings.Join(sb, util.PathSeparator())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Manifest) InheritFrom(parent *Manifest) error {
|
|
|
|
if parent == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
m.Arguments.Game = append(parent.Arguments.Game, m.Arguments.Game...)
|
|
|
|
m.Arguments.Jvm = append(parent.Arguments.Jvm, m.Arguments.Jvm...)
|
|
|
|
|
|
|
|
if m.AssetIndex.TotalSize == 0 {
|
|
|
|
m.AssetIndex.File = parent.AssetIndex.File
|
|
|
|
m.AssetIndex.TotalSize = parent.AssetIndex.TotalSize
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.Assets == "" {
|
|
|
|
m.Assets = parent.Assets
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.ComplianceLevel == 0 {
|
|
|
|
m.ComplianceLevel = parent.ComplianceLevel
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.Downloads == nil {
|
|
|
|
m.Downloads = make(map[string]util.File)
|
|
|
|
}
|
|
|
|
|
|
|
|
for k, v := range parent.Downloads {
|
|
|
|
m.Downloads[k] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.Id == "" {
|
|
|
|
m.Id = parent.Id
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.JavaVersion.Component != "" {
|
|
|
|
m.JavaVersion.Component = parent.JavaVersion.Component
|
|
|
|
m.JavaVersion.MajorVersion = parent.JavaVersion.MajorVersion
|
|
|
|
}
|
|
|
|
|
2024-12-14 18:00:34 +04:00
|
|
|
merge_libs:
|
|
|
|
for _, plib := range parent.Libraries {
|
|
|
|
plname := strings.Split(plib.Name, ":")
|
|
|
|
for _, lib := range m.Libraries {
|
|
|
|
lname := strings.Split(lib.Name, ":")
|
|
|
|
if len(plname) == len(lname) {
|
|
|
|
if lname[0]+":"+lname[1] == plname[0]+":"+plname[1] {
|
|
|
|
continue merge_libs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m.Libraries = append(m.Libraries, plib)
|
|
|
|
}
|
2023-10-30 02:18:41 +04:00
|
|
|
|
|
|
|
if m.Logging.Client.Argument == "" {
|
|
|
|
m.Logging.Client.Argument = parent.Logging.Client.Argument
|
|
|
|
m.Logging.Client.Type = parent.Logging.Client.Type
|
|
|
|
m.Logging.Client.File = parent.Logging.Client.File
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.MainClass == "" {
|
|
|
|
m.MainClass = parent.MainClass
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.MinecraftArguments == "" {
|
|
|
|
m.MinecraftArguments = parent.MinecraftArguments
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|