initial commit
This commit is contained in:
110
internal/item/registry.go
Normal file
110
internal/item/registry.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"github.com/df-mc/worldupgrader/blockupgrader"
|
||||
"github.com/sandertv/gophertunnel/minecraft/nbt"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed schemas/*.json
|
||||
schemasFS embed.FS
|
||||
//go:embed 1.12.0_item_id_to_block_id_map.json
|
||||
rawItemToBlockIdMap []byte
|
||||
//go:embed 1.12.0_to_1.18.10_blockstate_map.bin
|
||||
rawblockStateMap []byte
|
||||
// schemaIDs is a list of ids from all registered schemas.
|
||||
schemaIDs []int
|
||||
// schemas is a map of all registered item upgrade schemas.
|
||||
schemas map[uint16]schema
|
||||
// itemToBlockIdMap is a list of all registered item upgrade schemas.
|
||||
itemToBlockIdMap map[string]string
|
||||
// blockStateMap is a list of all legacy block states mapped to an upgraded version of it.
|
||||
blockStateMap map[stateHash]blockupgrader.BlockState
|
||||
|
||||
filenameRegex = regexp.MustCompile(`(\d{4})_[\w.]+\.json`)
|
||||
)
|
||||
|
||||
// stateHash is a struct that may be used as a map key for block states.
|
||||
type stateHash struct {
|
||||
// Name is the name of the block. It looks like 'minecraft:stone'.
|
||||
Name string
|
||||
// Metadata is the metadata value of the block. A lot of blocks only have 0 as data value, but some blocks
|
||||
// carry specific variants or properties encoded in the metadata.
|
||||
Metadata uint32
|
||||
}
|
||||
|
||||
// init ...
|
||||
func init() {
|
||||
schemas = make(map[uint16]schema)
|
||||
files, err := schemasFS.ReadDir("schemas")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
subMatches := filenameRegex.FindStringSubmatch(f.Name())
|
||||
if subMatches == nil {
|
||||
continue
|
||||
}
|
||||
id, err := strconv.Atoi(subMatches[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
buf, err := schemasFS.ReadFile("schemas/" + f.Name())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var s schema
|
||||
if err = json.Unmarshal(buf, &s); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
schemas[uint16(id)] = s
|
||||
}
|
||||
schemaIDs = make([]int, 0, len(schemas))
|
||||
for k := range schemas {
|
||||
schemaIDs = append(schemaIDs, int(k))
|
||||
}
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(schemaIDs)))
|
||||
|
||||
if err = json.Unmarshal(rawItemToBlockIdMap, &itemToBlockIdMap); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
blockStateMap = make(map[stateHash]blockupgrader.BlockState)
|
||||
buf := protocol.NewReader(bytes.NewBuffer(rawblockStateMap), 0, false)
|
||||
var length uint32
|
||||
buf.Varuint32(&length)
|
||||
for i := uint32(0); i < length; i++ {
|
||||
var legacyStringId string
|
||||
buf.String(&legacyStringId)
|
||||
|
||||
var pairs uint32
|
||||
buf.Varuint32(&pairs)
|
||||
for y := uint32(0); y < pairs; y++ {
|
||||
var meta uint32
|
||||
buf.Varuint32(&meta)
|
||||
|
||||
var blockStateRaw map[string]any
|
||||
buf.NBT(&blockStateRaw, nbt.LittleEndian)
|
||||
latestBlockState := blockupgrader.Upgrade(blockupgrader.BlockState{
|
||||
Name: blockStateRaw["name"].(string),
|
||||
Properties: blockStateRaw["states"].(map[string]any),
|
||||
Version: blockStateRaw["version"].(int32),
|
||||
})
|
||||
blockStateMap[stateHash{
|
||||
Name: legacyStringId,
|
||||
Metadata: meta,
|
||||
}] = latestBlockState
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user