up3
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/segmentio/fasthash/fnv1a"
|
||||
)
|
||||
|
||||
// networkBlockHash produces the canonical "network block hash" for a (name, properties) block state.
|
||||
// This hash is used for mapping network palette entries back to runtime IDs.
|
||||
//
|
||||
// The scratch slice is used to reduce allocations. The returned slice should be passed back in on subsequent calls to
|
||||
// reuse the same backing array.
|
||||
func networkBlockHash(name string, properties map[string]any, scratch []byte) (uint32, []byte) {
|
||||
if name == "minecraft:unknown" {
|
||||
return 0xfffffffe, scratch // -2
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(properties))
|
||||
for k := range properties {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
data := scratch[:0]
|
||||
writeString := func(str string) {
|
||||
data = binary.LittleEndian.AppendUint16(data, uint16(len(str)))
|
||||
data = append(data, []byte(str)...)
|
||||
}
|
||||
|
||||
data = append(data, 10) // compound
|
||||
data = append(data, 0)
|
||||
data = append(data, 0)
|
||||
|
||||
data = append(data, 8) // string
|
||||
writeString("name")
|
||||
writeString(name)
|
||||
|
||||
data = append(data, 10) // compound
|
||||
writeString("states")
|
||||
for _, k := range keys {
|
||||
v := properties[k]
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
data = append(data, 8) // string
|
||||
writeString(k)
|
||||
writeString(v)
|
||||
|
||||
case uint8:
|
||||
data = append(data, 1) // tagByte
|
||||
writeString(k)
|
||||
data = append(data, byte(v))
|
||||
case int8:
|
||||
data = append(data, 1) // tagByte
|
||||
writeString(k)
|
||||
data = append(data, byte(v))
|
||||
case bool:
|
||||
b := 0
|
||||
if v {
|
||||
b = 1
|
||||
}
|
||||
data = append(data, 1) // tagByte
|
||||
writeString(k)
|
||||
data = append(data, byte(b))
|
||||
|
||||
case uint16:
|
||||
data = append(data, 2) // tagInt16
|
||||
writeString(k)
|
||||
data = binary.LittleEndian.AppendUint16(data, uint16(v))
|
||||
case int16:
|
||||
data = append(data, 2) // tagInt16
|
||||
writeString(k)
|
||||
data = binary.LittleEndian.AppendUint16(data, uint16(v))
|
||||
|
||||
case uint32:
|
||||
data = append(data, 3) // tagInt32
|
||||
writeString(k)
|
||||
data = binary.LittleEndian.AppendUint32(data, uint32(v))
|
||||
case int32:
|
||||
data = append(data, 3) // tagInt32
|
||||
writeString(k)
|
||||
data = binary.LittleEndian.AppendUint32(data, uint32(v))
|
||||
default:
|
||||
panic(fmt.Sprintf("unhandled nbt type: %T", v))
|
||||
}
|
||||
}
|
||||
data = append(data, 0) // end
|
||||
data = append(data, 0) // end
|
||||
|
||||
return fnv1a.HashBytes32(data), data
|
||||
}
|
||||
Reference in New Issue
Block a user