Handle ADDNODE packet

master
HimbeerserverDE 2021-02-11 07:40:42 +01:00
parent 622e5c3889
commit 8a219bb04b
5 changed files with 162 additions and 44 deletions

View File

@ -14,22 +14,9 @@ const NodeCount = 16 * 16 * 16
func processBlockdata(p *Peer, pkt *rudp.Pkt) bool {
srv := p.ServerName()
var zc uint32
si := len(pkt.Data) - 1
for ; si > 0; si-- {
// Check for zlib header
if pkt.Data[si] == 120 && (pkt.Data[1+si] == 0x01 || pkt.Data[1+si] == 0x9C || pkt.Data[1+si] == 0xDA) {
zc++
}
}
if zc == 2 {
si = 14
// Check for zlib header
for ; !(pkt.Data[si] == 120 && (pkt.Data[1+si] == 0x01 || pkt.Data[1+si] == 0x9C || pkt.Data[1+si] == 0xDA)); si++ {
}
} else {
si = len(pkt.Data)
si := 14
// Check for zlib header
for ; !(pkt.Data[si] == 120 && (pkt.Data[1+si] == 0x01 || pkt.Data[1+si] == 0x9C || pkt.Data[1+si] == 0xDA)); si++ {
}
compressedNodes := pkt.Data[13:si]
@ -64,20 +51,22 @@ func processBlockdata(p *Peer, pkt *rudp.Pkt) bool {
recompNodes := recompBuf.Bytes()
if zc == 2 {
data := make([]byte, 13+len(recompNodes)+len(pkt.Data[si:]))
copy(data[:13], pkt.Data[:13])
copy(data[13:13+len(recompNodes)], recompNodes)
copy(data[13+len(recompNodes):], pkt.Data[si:])
data := make([]byte, 13+len(recompNodes)+len(pkt.Data[si:]))
copy(data[:13], pkt.Data[:13])
copy(data[13:13+len(recompNodes)], recompNodes)
copy(data[13+len(recompNodes):], pkt.Data[si:])
pkt.Data = data
} else {
data := make([]byte, 13+len(recompNodes))
copy(data[:13], pkt.Data[:13])
copy(data[13:], recompNodes)
pkt.Data = data
}
pkt.Data = data
return false
}
func processAddnode(p *Peer, pkt *rudp.Pkt) bool {
srv := p.ServerName()
contentID := binary.BigEndian.Uint16(pkt.Data[8:10])
newID := nodeDefs[srv][contentID].ID()
binary.BigEndian.PutUint16(pkt.Data[8:10], newID)
return false
}

View File

@ -149,6 +149,8 @@ func processPktCommand(src, dst *Peer, pkt *rudp.Pkt) bool {
return processRpc(src, *pkt)
case ToClientBlockdata:
return processBlockdata(dst, pkt)
case ToClientAddNode:
return processAddnode(dst, pkt)
default:
return false
}

125
itemdef.go Normal file
View File

@ -0,0 +1,125 @@
package main
import (
"bytes"
"compress/zlib"
"encoding/binary"
"io"
)
var itemdef []byte
type ItemDef struct {
name string
data []byte
}
// Name returns the name of an ItemDef
func (i *ItemDef) Name() string { return i.name }
// Data returns the actual definition
func (i *ItemDef) Data() []byte { return i.data }
func mergeItemdefs(mgrs [][]byte) error {
var itemDefs []*ItemDef
aliases := make(map[string]string)
// Extract definitions from CItemDefManager
for _, compressedMgr := range mgrs {
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()
mgr := buf.Bytes()
count := binary.BigEndian.Uint16(mgr[1:3])
si := uint32(3)
ItemLoop:
for i := uint16(0); i < count; i++ {
deflen := binary.BigEndian.Uint16(mgr[si : 2+si])
def := mgr[2+si : 2+si+uint32(deflen)]
itemNameLen := binary.BigEndian.Uint16(def[2:4])
itemName := string(def[4 : 4+itemNameLen])
for _, idef := range itemDefs {
if idef.Name() == itemName {
si += 2 + uint32(deflen)
continue ItemLoop
}
}
itemDefs = append(itemDefs, &ItemDef{name: itemName, data: def})
si += 2 + uint32(deflen)
}
aliasCount := binary.BigEndian.Uint16(mgr[si : 2+si])
si += 2
for i := uint16(0); i < aliasCount; i++ {
namelen := binary.BigEndian.Uint16(mgr[si : 2+si])
name := string(mgr[2+si : 2+si+uint32(namelen)])
convertlen := binary.BigEndian.Uint16(mgr[2+si+uint32(namelen) : 4+si+uint32(namelen)])
convert := string(mgr[4+si+uint32(namelen) : 4+si+uint32(namelen)+uint32(convertlen)])
if aliases[name] == "" {
aliases[name] = convert
}
si += 4 + uint32(namelen) + uint32(convertlen)
}
}
// Merge definitions into new CItemDefManager
mgr := make([]byte, 3)
mgr[0] = uint8(0x00)
binary.BigEndian.PutUint16(mgr[1:3], uint16(len(itemDefs)))
var allDefs []byte
for _, def := range itemDefs {
defData := make([]byte, 2+len(def.Data()))
binary.BigEndian.PutUint16(defData[0:2], uint16(len(def.Data())))
copy(defData[2:], def.Data())
allDefs = append(allDefs, defData...)
}
mgr = append(mgr, allDefs...)
aliasCount := make([]byte, 2)
binary.BigEndian.PutUint16(aliasCount, uint16(len(aliases)))
mgr = append(mgr, aliasCount...)
for name, convert := range aliases {
namelen := make([]byte, 2)
binary.BigEndian.PutUint16(namelen, uint16(len(name)))
convertlen := make([]byte, 2)
binary.BigEndian.PutUint16(convertlen, uint16(len(convert)))
mgr = append(mgr, namelen...)
mgr = append(mgr, []byte(name)...)
mgr = append(mgr, convertlen...)
mgr = append(mgr, []byte(convert)...)
}
var compressedMgr bytes.Buffer
zw := zlib.NewWriter(&compressedMgr)
zw.Write(mgr)
zw.Close()
itemdef = compressedMgr.Bytes()
return nil
}

View File

@ -14,7 +14,7 @@ import (
)
// MediaRefetchInterval is the amount of time between media downloads
const MediaRefetchInterval = 30 * time.Second
const MediaRefetchInterval = 10 * time.Minute
var media map[string]*mediaFile
var tooldefs [][]byte
@ -61,7 +61,7 @@ func (p *Peer) fetchMedia() {
case ToClientCraftitemdef:
craftitemdefs = append(craftitemdefs, pkt.Data[2:])
case ToClientItemdef:
itemdefs = append(itemdefs, pkt.Data[2:])
itemdefs = append(itemdefs, pkt.Data[6:])
case ToClientMovement:
movement = pkt.Data[2:]
case ToClientDetachedInventory:
@ -205,19 +205,17 @@ func (p *Peer) announceMedia() {
<-ack
}
for _, def := range itemdefs {
data := make([]byte, 2+len(def))
data[0] = uint8(0x00)
data[1] = uint8(ToClientItemdef)
copy(data[2:], def)
data = make([]byte, 6+len(itemdef))
data[0] = uint8(0x00)
data[1] = uint8(ToClientItemdef)
binary.BigEndian.PutUint32(data[2:6], uint32(len(itemdef)))
copy(data[6:], itemdef)
ack, err := p.Send(rudp.Pkt{Data: data})
if err != nil {
log.Print(err)
continue
}
<-ack
ack, err = p.Send(rudp.Pkt{Data: data})
if err != nil {
log.Print(err)
}
<-ack
p.updateDetachedInvs(srvname)
@ -438,6 +436,10 @@ func loadMedia() {
}
}
if err := mergeItemdefs(itemdefs); err != nil {
log.Fatal(err)
}
updateMediaCache()
}

View File

@ -38,7 +38,7 @@ func mergeNodedefs(mgrs map[string][]byte) error {
var nextID uint16
// Extract definitions from NodeDefMgrs
// Extract definitions from NodeDefManagers
for srv, compressedMgr := range mgrs {
if nodeDefs[srv] == nil {
nodeDefs[srv] = make(map[uint16]*NodeDef)
@ -96,7 +96,7 @@ func mergeNodedefs(mgrs map[string][]byte) error {
}
}
// Merge definitions into new NodeDefMgr
// Merge definitions into new NodeDefManager
mgr := make([]byte, 7)
mgr[0] = uint8(1)
binary.BigEndian.PutUint16(mgr[1:3], total)