170 lines
3.9 KiB
Go
170 lines
3.9 KiB
Go
package behaviourpack
|
|
|
|
import (
|
|
"archive/zip"
|
|
"encoding/json"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/bedrock-tool/bedrocktool/utils"
|
|
"github.com/repeale/fp-go"
|
|
"github.com/sandertv/gophertunnel/minecraft/resource"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type BehaviourPack struct {
|
|
formatVersion string
|
|
Manifest *resource.Manifest
|
|
blocks []blockBehaviour
|
|
items map[string]itemBehaviour
|
|
entities map[string]entityBehaviour
|
|
}
|
|
|
|
func New(name string) *BehaviourPack {
|
|
return &BehaviourPack{
|
|
formatVersion: "1.16.0",
|
|
Manifest: &resource.Manifest{
|
|
FormatVersion: 2,
|
|
Header: resource.Header{
|
|
Name: name,
|
|
Description: "Adds Blocks, Items and Entities from the server to this world",
|
|
UUID: utils.RandSeededUUID(name + "_datapack"),
|
|
Version: [3]int{1, 0, 0},
|
|
MinimumGameVersion: [3]int{1, 19, 50},
|
|
},
|
|
Modules: []resource.Module{
|
|
{
|
|
Type: "data",
|
|
UUID: utils.RandSeededUUID(name + "_data_module"),
|
|
Description: "Datapack",
|
|
Version: [3]int{1, 0, 0},
|
|
},
|
|
},
|
|
Dependencies: []resource.Dependency{},
|
|
Capabilities: []resource.Capability{},
|
|
},
|
|
blocks: []blockBehaviour{},
|
|
items: make(map[string]itemBehaviour),
|
|
entities: make(map[string]entityBehaviour),
|
|
}
|
|
}
|
|
|
|
func (bp *BehaviourPack) AddDependency(id string, ver [3]int) {
|
|
bp.Manifest.Dependencies = append(bp.Manifest.Dependencies, resource.Dependency{
|
|
UUID: id,
|
|
Version: ver,
|
|
})
|
|
}
|
|
|
|
func (bp *BehaviourPack) CheckAddLink(pack utils.Pack) {
|
|
z, err := zip.NewReader(pack, int64(pack.Len()))
|
|
if err != nil {
|
|
logrus.Error(err)
|
|
return
|
|
}
|
|
|
|
hasBlocksJson := false
|
|
if bp.HasBlocks() {
|
|
_, err = z.Open("blocks.json")
|
|
if err == nil {
|
|
hasBlocksJson = true
|
|
}
|
|
}
|
|
|
|
hasEntitiesFolder := false
|
|
if bp.HasEntities() {
|
|
hasEntitiesFolder = fp.Some(func(f *zip.File) bool {
|
|
return f.Name == "entity" && f.FileInfo().IsDir()
|
|
})(z.File)
|
|
}
|
|
|
|
hasItemsFolder := false
|
|
if bp.HasItems() {
|
|
hasItemsFolder = fp.Some(func(f *zip.File) bool {
|
|
return f.Name == "items" && f.FileInfo().IsDir()
|
|
})(z.File)
|
|
}
|
|
|
|
// has no assets needed
|
|
if !(hasBlocksJson || hasEntitiesFolder || hasItemsFolder) {
|
|
return
|
|
}
|
|
|
|
h := pack.Manifest().Header
|
|
bp.AddDependency(h.UUID, h.Version)
|
|
}
|
|
|
|
func (bp *BehaviourPack) HasBlocks() bool {
|
|
return len(bp.blocks) > 0
|
|
}
|
|
|
|
func (bp *BehaviourPack) HasItems() bool {
|
|
return len(bp.items) > 0
|
|
}
|
|
|
|
func (bp *BehaviourPack) HasEntities() bool {
|
|
return len(bp.entities) > 0
|
|
}
|
|
|
|
func (bp *BehaviourPack) HasContent() bool {
|
|
return bp.HasBlocks() || bp.HasItems()
|
|
}
|
|
|
|
func ns_name_split(identifier string) (ns, name string) {
|
|
ns_name := strings.Split(identifier, ":")
|
|
return ns_name[0], ns_name[len(ns_name)-1]
|
|
}
|
|
|
|
func (bp *BehaviourPack) Save(fpath string) error {
|
|
if err := utils.WriteManifest(bp.Manifest, fpath); err != nil {
|
|
return err
|
|
}
|
|
|
|
_add_thing := func(base, identifier string, thing any) error {
|
|
ns, name := ns_name_split(identifier)
|
|
thing_dir := path.Join(base, ns)
|
|
os.Mkdir(thing_dir, 0o755)
|
|
w, err := os.Create(path.Join(thing_dir, name+".json"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
e := json.NewEncoder(w)
|
|
e.SetIndent("", "\t")
|
|
return e.Encode(thing)
|
|
}
|
|
|
|
if bp.HasBlocks() { // blocks
|
|
blocks_dir := path.Join(fpath, "blocks")
|
|
os.Mkdir(blocks_dir, 0o755)
|
|
for _, be := range bp.blocks {
|
|
err := _add_thing(blocks_dir, be.MinecraftBlock.Description.Identifier, be)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
if bp.HasItems() { // items
|
|
items_dir := path.Join(fpath, "items")
|
|
os.Mkdir(items_dir, 0o755)
|
|
for _, ib := range bp.items {
|
|
err := _add_thing(items_dir, ib.MinecraftItem.Description.Identifier, ib)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
if bp.HasEntities() { // entities
|
|
items_dir := path.Join(fpath, "entities")
|
|
os.Mkdir(items_dir, 0o755)
|
|
for _, eb := range bp.entities {
|
|
err := _add_thing(items_dir, eb.MinecraftEntity.Description.Identifier, eb)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|