package core import ( "errors" "os" "github.com/BurntSushi/toml" ) // Mod stores metadata about a mod. This is written to a TOML file for each mod. type Mod struct { metaFile string // The file for the metadata file, used as an ID Name string `toml:"name"` FileName string `toml:"filename"` Side string `toml:"side,omitempty"` Optional bool `toml:"optional,omitempty"` Download ModDownload `toml:"download"` // Update is a map of map of stuff, so you can store arbitrary values on string keys to define updating Update map[string]map[string]interface{} `toml:"update"` updaters map[string]Updater } // ModDownload specifies how to download the mod file type ModDownload struct { URL string `toml:"url"` HashFormat string `toml:"hash-format"` Hash string `toml:"hash"` } // The three possible values of Side (the side that the mod is on) are "server", "client", and "both". const ( ServerSide = "server" ClientSide = "client" UniversalSide = "both" ) // LoadMod attempts to load a mod file from a path func LoadMod(modFile string) (Mod, error) { var mod Mod if _, err := toml.DecodeFile(modFile, &mod); err != nil { return Mod{}, err } mod.updaters = make(map[string]Updater) // Horrible reflection library to convert to Updaters for k, v := range mod.Update { updateParser, ok := UpdateParsers[k] if ok { updater, err := updateParser.ParseUpdate(v) if err != nil { return mod, err } mod.updaters[k] = updater } else { return mod, errors.New("Update plugin " + k + " not found!") } } mod.metaFile = modFile return mod, nil } // SetMetaName sets the mod metadata file from a given file name (to be put in the mods folder) func (m *Mod) SetMetaName(metaName string, flags Flags) { m.metaFile = ResolveMod(metaName, flags) } // Write saves the mod file func (m Mod) Write() error { f, err := os.Create(m.metaFile) if err != nil { return err } defer f.Close() enc := toml.NewEncoder(f) // Disable indentation enc.Indent = "" return enc.Encode(m) }