fixing behavior pack textures

This commit is contained in:
olebeck 2023-01-24 12:50:27 +01:00
parent 3dba4525b5
commit 56ac765b1d
10 changed files with 134 additions and 41 deletions

2
.gitattributes vendored
View File

@ -1 +1 @@
utils/resourcepack-ace.go.ignore filter=git-crypt diff=git-crypt
utils/resourcepack-ace.go filter=git-crypt diff=git-crypt

View File

@ -8,12 +8,12 @@ GC = go build -ldflags "-s -w -X github.com/bedrock-tool/bedrocktool/utils.Versi
# check if packs are supported
HAVE_PACKS = false
ifeq ($(shell head -c 7 ./utils/resourcepack-ace.go.ignore),package)
ifeq ($(shell head -c 7 ./utils/resourcepack-ace.go),package)
HAVE_PACKS = true
endif
$(info pack support: ${HAVE_PACKS})
ifeq ($(HAVE_PACKS),true)
ifneq ($(HAVE_PACKS),true)
GC += -overlay overlay.json
endif
@ -46,7 +46,6 @@ $(DISTS): dist builds $(SRCS)
GOOS=$(OS) GOARCH=$(ARCH) $(GC) -o $(BUILD) ./cmd/bedrocktool
cp $(BUILD) $@
UPDATES=$(BUILDS)
$(UPDATES): OS = $(word 1,$(subst _, ,$@))
$(UPDATES): ARCH = $(word 1,$(subst ., ,$(word 2,$(subst _, ,$@))))

View File

@ -1,5 +1,5 @@
{
"Replace": {
"utils/resourcepack.go": "utils/resourcepack-ace.go.ignore"
"utils/resourcepack-ace.go": "utils/dummy"
}
}

View File

@ -161,6 +161,7 @@ func (c *WorldCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{
w.ctx = ctx
proxy := utils.NewProxy()
proxy.AlwaysGetPacks = true
proxy.ConnectCB = w.OnConnect
proxy.PacketCB = func(pk packet.Packet, proxy *utils.ProxyContext, toServer bool) (packet.Packet, error) {
var forward bool
@ -442,38 +443,55 @@ func (w *WorldState) SaveAndReset() {
provider.Close()
w.worldCounter += 1
for k, p := range w.packs {
logrus.Infof(locale.Loc("adding_pack", locale.Strmap{"Name": k}))
pack_folder := path.Join(folder, "resource_packs", k)
os.MkdirAll(pack_folder, 0o755)
data := make([]byte, p.Len())
p.ReadAt(data, 0)
utils.UnpackZip(bytes.NewReader(data), int64(len(data)), pack_folder)
type dep struct {
PackId string `json:"pack_id"`
Version [3]int `json:"version"`
}
add_packs_json := func(name string, deps []dep) {
f, err := os.Create(path.Join(folder, name))
if err != nil {
logrus.Error(err)
return
}
defer f.Close()
if err := json.NewEncoder(f).Encode(deps); err != nil {
logrus.Error(err)
return
}
}
{
var rdeps []dep
for k, p := range w.packs {
logrus.Infof(locale.Loc("adding_pack", locale.Strmap{"Name": k}))
pack_folder := path.Join(folder, "resource_packs", k)
os.MkdirAll(pack_folder, 0o755)
data := make([]byte, p.Len())
p.ReadAt(data, 0)
utils.UnpackZip(bytes.NewReader(data), int64(len(data)), pack_folder)
rdeps = append(rdeps, dep{
PackId: p.Manifest().Header.Name,
Version: p.Manifest().Header.Version,
})
}
add_packs_json("world_resource_packs.json", rdeps)
}
if w.bp != nil {
name := w.ServerName + "_blocks"
pack_folder := path.Join(folder, "behavior_packs", name)
os.MkdirAll(pack_folder, 0o755)
w.bp.Save(pack_folder)
{ // save file saying to load the behavior pack
f, err := os.Create(path.Join(folder, "world_behavior_packs.json"))
if err != nil {
logrus.Error(err)
} else {
defer f.Close()
type dep struct {
PackId string `json:"pack_id"`
Version [3]int `json:"version"`
}
if err := json.NewEncoder(f).Encode([]dep{{
PackId: w.bp.Manifest.Header.UUID,
Version: w.bp.Manifest.Header.Version,
}}); err != nil {
logrus.Error(err)
}
}
for _, p := range w.proxy.Server.ResourcePacks() {
p := utils.PackFromBase(p)
w.bp.CheckAddLink(p)
}
w.bp.Save(pack_folder)
add_packs_json("world_behavior_packs.json", []dep{{
PackId: w.bp.Manifest.Header.UUID,
Version: w.bp.Manifest.Header.Version,
}})
}
if w.saveImage {

View File

@ -1,6 +1,7 @@
package behaviourpack
import (
"archive/zip"
"bytes"
"crypto/sha256"
"encoding/json"
@ -8,6 +9,7 @@ import (
"path"
"strings"
"github.com/bedrock-tool/bedrocktool/utils"
"github.com/google/uuid"
"github.com/sandertv/gophertunnel/minecraft/protocol"
"github.com/sandertv/gophertunnel/minecraft/resource"
@ -157,11 +159,7 @@ func (bp *BehaviourPack) AddBlock(block protocol.BlockEntry) {
}
// fix missing * instance
if k == "minecraft:material_instances" {
if mats, ok := v["materials"].(map[string]any); ok {
if _, has_star := mats["*"]; !has_star {
mats["*"] = mats["east"]
}
}
comps[k] = v["materials"].(map[string]any)
}
}
}
@ -184,6 +182,19 @@ func (bp *BehaviourPack) AddBlock(block protocol.BlockEntry) {
bp.blocks = append(bp.blocks, entry)
}
func (bp *BehaviourPack) CheckAddLink(pack utils.Pack) {
z, err := zip.NewReader(pack, int64(pack.Len()))
if err != nil {
logrus.Error(err)
}
_, err = z.Open("blocks.json")
if err != nil {
return
}
h := pack.Manifest().Header
bp.AddDependency(h.UUID, h.Version)
}
func (bp *BehaviourPack) Save(fpath string) error {
{ // write manifest
w, err := os.Create(path.Join(fpath, "manifest.json"))

1
utils/dummy Normal file
View File

@ -0,0 +1 @@
package utils

View File

@ -35,10 +35,11 @@ func (p dummyProto) ConvertFromLatest(pk packet.Packet, _ *minecraft.Conn) []pac
}
type ProxyContext struct {
Server *minecraft.Conn
Client *minecraft.Conn
Listener *minecraft.Listener
commands map[string]IngameCommand
Server *minecraft.Conn
Client *minecraft.Conn
Listener *minecraft.Listener
commands map[string]IngameCommand
AlwaysGetPacks bool
// called for every packet
PacketFunc PacketFunc
@ -197,7 +198,7 @@ func (p *ProxyContext) Run(ctx context.Context, server_address string) (err erro
p.Client = c.(*minecraft.Conn)
cd := p.Client.ClientData()
p.Server, err = ConnectServer(ctx, server_address, &cd, false, p.PacketFunc)
p.Server, err = ConnectServer(ctx, server_address, &cd, p.AlwaysGetPacks, p.PacketFunc)
if err != nil {
err = fmt.Errorf(locale.Loc("failed_to_connect", locale.Strmap{"Address": server_address, "Err": err}))
return

BIN
utils/resourcepack-ace.go Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,14 +1,77 @@
package utils
import (
"errors"
"io"
"github.com/sandertv/gophertunnel/minecraft"
"github.com/sandertv/gophertunnel/minecraft/resource"
)
type Pack interface {
io.ReaderAt
ReadAll() ([]byte, error)
Decrypt() ([]byte, error)
Encrypted() bool
UUID() string
Name() string
Version() string
ContentKey() string
Len() int
Manifest() resource.Manifest
Base() *resource.Pack
}
type Packb struct {
*resource.Pack
}
func (p *Packb) ReadAll() ([]byte, error) {
buf := make([]byte, p.Len())
off := 0
for {
n, err := p.ReadAt(buf[off:], int64(off))
if err != nil {
if err == io.EOF {
break
}
return nil, err
}
off += n
}
return buf, nil
}
func (p *Packb) Decrypt() ([]byte, error) {
return nil, errors.New("no_decrypt")
}
func (p *Packb) Base() *resource.Pack {
return p.Pack
}
var PackFromBase = func(pack *resource.Pack) Pack {
b := &Packb{pack}
return b
}
func GetPacks(server *minecraft.Conn) (packs map[string]*resource.Pack, err error) {
packs = make(map[string]*resource.Pack)
for _, pack := range server.ResourcePacks() {
packs[pack.Name()] = pack
pack := PackFromBase(pack)
if pack.Encrypted() {
data, err := pack.Decrypt()
if err != nil {
return nil, err
}
pack2, err := resource.FromBytes(data)
if err != nil {
return nil, err
}
packs[pack.Name()] = pack2
} else {
packs[pack.Name()] = pack.Base()
}
}
return
}