multiserver/nodedef.go

179 lines
3.1 KiB
Go
Raw Permalink Normal View History

2021-02-09 23:35:14 -08:00
package main
import (
"bytes"
"compress/zlib"
"encoding/binary"
"io"
2021-03-14 01:54:17 -08:00
"sync"
2021-02-09 23:35:14 -08:00
)
var nodedef []byte
const (
ContentUnknown = 125
ContentAir = 126
ContentIgnore = 127
)
type NodeDef struct {
id uint16
name string
data []byte
}
2021-03-14 01:54:17 -08:00
var nodeDefsMu sync.RWMutex
2021-02-09 23:35:14 -08:00
var nodeDefs map[string]map[uint16]*NodeDef
2021-03-14 01:37:07 -08:00
// NodeDefByName returns the NodeDef that has the specified name on a
2021-03-06 07:54:46 -08:00
// minetest server
func NodeDefByName(srv, name string) *NodeDef {
for _, def := range nodeDefs[srv] {
if def.Name() == name {
return def
}
}
return nil
}
2021-02-09 23:35:14 -08:00
// ID returns the content ID of a NodeDef
2021-02-28 02:47:30 -08:00
func (n *NodeDef) ID() uint16 {
if n == nil {
return ContentUnknown
}
return n.id
}
2021-02-09 23:35:14 -08:00
// Name returns the name of a NodeDef
2021-02-28 02:47:30 -08:00
func (n *NodeDef) Name() string {
if n == nil {
return ""
}
return n.name
}
2021-02-09 23:35:14 -08:00
// Data returns the actual definition
2021-02-28 02:47:30 -08:00
func (n *NodeDef) Data() []byte {
if n == nil {
return []byte{}
}
return n.data
}
2021-02-09 23:35:14 -08:00
2021-03-14 01:54:17 -08:00
// NodeDefs returns all node definitions
func NodeDefs() map[string]map[uint16]*NodeDef {
nodeDefsMu.RLock()
defer nodeDefsMu.RUnlock()
return nodeDefs
}
2021-02-09 23:35:14 -08:00
func mergeNodedefs(mgrs map[string][]byte) error {
var total uint16
2021-03-14 01:54:17 -08:00
nodeDefsMu.Lock()
defer nodeDefsMu.Unlock()
if nodeDefs == nil {
nodeDefs = make(map[string]map[uint16]*NodeDef)
}
2021-02-09 23:35:14 -08:00
var nextID uint16
2021-02-10 22:40:42 -08:00
// Extract definitions from NodeDefManagers
2021-02-09 23:35:14 -08:00
for srv, compressedMgr := range mgrs {
if nodeDefs[srv] == nil {
nodeDefs[srv] = make(map[uint16]*NodeDef)
}
zr, err := zlib.NewReader(bytes.NewReader(compressedMgr))
if err != nil {
return err
}
buf := &bytes.Buffer{}
_, err = io.Copy(buf, zr)
if err != nil {
return err
}
zr.Close()
2021-04-01 10:43:29 -07:00
r := bytes.NewReader(buf.Bytes())
r.Seek(1, io.SeekStart)
2021-02-09 23:35:14 -08:00
2021-04-01 10:43:29 -07:00
count := ReadUint16(r)
r.Seek(4, io.SeekCurrent)
2021-02-09 23:35:14 -08:00
NodeLoop:
for i := uint16(0); i < count; i++ {
2021-04-01 10:43:29 -07:00
id := ReadUint16(r)
defb := ReadBytes16(r)
2021-02-09 23:35:14 -08:00
2021-04-01 10:43:29 -07:00
dr := bytes.NewReader(defb)
dr.Seek(1, io.SeekStart)
nodeName := string(ReadBytes16(dr))
2021-02-09 23:35:14 -08:00
for _, srvdefs := range nodeDefs {
for _, def := range srvdefs {
if def.Name() == nodeName {
nodeDefs[srv][id] = &NodeDef{id: def.ID()}
continue NodeLoop
}
}
}
2021-03-06 07:54:46 -08:00
if def := NodeDefByName(srv, nodeName); def != nil {
nodeDefs[srv][id] = &NodeDef{
id: def.ID(),
name: nodeName,
2021-04-01 10:43:29 -07:00
data: defb,
2021-03-06 07:54:46 -08:00
}
}
2021-02-09 23:35:14 -08:00
nodeDefs[srv][id] = &NodeDef{
id: nextID,
name: nodeName,
2021-04-01 10:43:29 -07:00
data: defb,
2021-02-09 23:35:14 -08:00
}
total++
nextID++
if nextID == ContentUnknown {
nextID = ContentIgnore + 1
}
}
}
2021-02-10 22:40:42 -08:00
// Merge definitions into new NodeDefManager
2021-04-01 10:43:29 -07:00
mgr := &bytes.Buffer{}
mgr.WriteByte(1)
WriteUint16(mgr, total)
2021-02-09 23:35:14 -08:00
var allDefs []byte
for _, srvdefs := range nodeDefs {
for _, def := range srvdefs {
if len(def.Data()) > 0 {
defData := make([]byte, 4+len(def.Data()))
2021-02-09 23:35:14 -08:00
binary.BigEndian.PutUint16(defData[0:2], def.ID())
binary.BigEndian.PutUint16(defData[2:4], uint16(len(def.Data())))
copy(defData[4:], def.Data())
2021-02-09 23:35:14 -08:00
allDefs = append(allDefs, defData...)
}
}
}
2021-04-01 10:43:29 -07:00
WriteBytes32(mgr, allDefs)
2021-02-09 23:35:14 -08:00
var compressedMgr bytes.Buffer
zw := zlib.NewWriter(&compressedMgr)
2021-04-01 10:43:29 -07:00
zw.Write(mgr.Bytes())
2021-02-09 23:35:14 -08:00
zw.Close()
nodedef = compressedMgr.Bytes()
return nil
}