Files
legacy-version/internal/block_states.go
2025-08-13 21:37:46 +07:00

55 lines
1.3 KiB
Go

package internal
import (
"fmt"
"sort"
"strings"
"unsafe"
"github.com/df-mc/worldupgrader/blockupgrader"
)
// StateHash is a struct that may be used as a map key for block states. It contains the name of the block state
// and an encoded version of the properties.
type StateHash struct {
Name, Properties string
}
// HashState produces a hash for the block properties held by the blockState.
func HashState(state blockupgrader.BlockState) StateHash {
if state.Properties == nil {
return StateHash{Name: state.Name}
}
keys := make([]string, 0, len(state.Properties))
for k := range state.Properties {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return keys[i] < keys[j]
})
var b strings.Builder
for _, k := range keys {
switch v := state.Properties[k].(type) {
case bool:
if v {
b.WriteByte(1)
} else {
b.WriteByte(0)
}
case uint8:
b.WriteByte(v)
case int32:
a := *(*[4]byte)(unsafe.Pointer(&v))
b.Write(a[:])
case string:
b.WriteString(v)
default:
// If block encoding is broken, we want to find out as soon as possible. This saves a lot of time
// debugging in-game.
panic(fmt.Sprintf("invalid block property type %T for property %v", v, k))
}
}
return StateHash{Name: state.Name, Properties: b.String()}
}