diff --git a/command.go b/command.go index 69cf86f..52a4ad3 100644 --- a/command.go +++ b/command.go @@ -187,6 +187,9 @@ func processPktCommand(src, dst *Peer, pkt *rudp.Pkt) bool { id = dst.currentPlayerCao } binary.BigEndian.PutUint16(pkt.Data[107+texturelen : 109+texturelen], id) + case ToClientInventory: + processInventory(dst, pkt.Data[2:]) + return false default: return false } diff --git a/inventory.go b/inventory.go new file mode 100644 index 0000000..320c6dc --- /dev/null +++ b/inventory.go @@ -0,0 +1,54 @@ +package main + +import ( + "strings" + + "github.com/anon55555/mt/rudp" +) + +func processInventory(p *Peer, data []byte) { + lists := make(map[string]bool) + + inv := string(data) + lines := strings.Split(inv, "\n") + for _, line := range lines { + list := strings.Split(line, " ") + name := list[0] + if name == "EndInventory" || name == "end" { + return + } + if name == "List" { + listname := list[1] + lists[listname] = true + } + if name == "KeepList" { + listname := list[1] + lists[listname] = true + } + } + + p.invlists = lists +} + +func updateHandList(p *Peer, t *ToolCapabs) error { + item := " 1 0 " + t.String() + + list := "Width 1\n" + list += "Item " + item + "\n" + list += "EndInventoryList\n" + + inv := "List hand 1\n" + inv += list + for invlist := range p.invlists { + inv += "KeepList " + invlist + "\n" + } + inv += "EndInventory\n" + + p.invlists = make(map[string]bool) + + _, err := p.Send(rudp.Pkt{Data: []byte(inv)}) + if err != nil { + return err + } + return nil +} diff --git a/itemdef.go b/itemdef.go index db9fa08..9905f89 100644 --- a/itemdef.go +++ b/itemdef.go @@ -5,8 +5,14 @@ import ( "compress/zlib" "encoding/binary" "io" - "log" "math" + "strconv" +) + +const ( + MetaBegin = "\x01" + MetaKVDelim = "\x02" + MetaPairDelim = "\x03" ) var itemdef []byte @@ -104,6 +110,55 @@ func (t *ToolCapabs) SetPunchAttackUses(uses uint16) { t.punchAttackUses = uses } +// String returns a minetest meta string with the tool capabilities +func (t *ToolCapabs) String() string { + r := MetaBegin + + r += "tool_capabilities" + r += MetaKVDelim + r += "{\n" + r += "\t" + + r += "\"damage_groups\" : \n" + r += "\t{\n" + for group, value := range t.DamageGroups() { + r += "\t\t\"" + group + "\" : " + r += strconv.Itoa(int(value)) + ",\n" + } + r += "\t},\n" + + r += "\t\"full_punch_interval\" : " + r += strconv.FormatFloat(float64(t.PunchInt()), byte('e'), -1, 32) + r += ",\n" + + r += "\t\"groupcaps\" : \n" + r += "\t{\n" + for name, cap := range t.GroupCaps() { + r += "\t\t\"" + name + "\" : \n" + r += "\t\t{\n" + r += "\t\t\t\"name\" : " + cap.Name() + ",\n" + r += "\t\t\t\"uses\" : " + strconv.Itoa(int(cap.Uses())) + ",\n" + r += "\t\t\t\"max_level\" : " + strconv.Itoa(int(cap.MaxLevel())) + ",\n" + r += "\t\t\t\"times\" : \n" + r += "\t\t\t{\n" + for k, v := range cap.Times() { + r += "\t\t\t\t\"" + strconv.Itoa(int(k)) + "\" : " + r += strconv.FormatFloat(float64(v), byte('e'), -1, 32) + r += ",\n" + } + r += "\t\t\t},\n" + r += "\t\t},\n" + } + r += "\t},\n" + + r += "\t\"max_drop_level\" : " + strconv.Itoa(int(t.MaxDropLevel())) + ",\n" + + r += "\t\"punch_attack_uses\" : " + strconv.Itoa(int(t.PunchAttackUses())) + "\n" + r += MetaPairDelim + + return r +} + func rmToolCapabs(def []byte) []byte { itemNameLen := binary.BigEndian.Uint16(def[2:4]) desclen := binary.BigEndian.Uint16(def[4+itemNameLen : 6+itemNameLen]) @@ -252,7 +307,6 @@ func mergeItemdefs(mgrs map[string][]byte) error { } handdata := rmToolCapabs(handDef) - log.Print(handdata) var compHanddata bytes.Buffer handZw := zlib.NewWriter(&compHanddata) diff --git a/listen.go b/listen.go index 9599d6b..2058ab5 100644 --- a/listen.go +++ b/listen.go @@ -51,6 +51,7 @@ func (l *Listener) Accept() (*Peer, error) { clt.modChs = make(map[string]bool) clt.huds = make(map[uint32]bool) clt.sounds = make(map[int32]bool) + clt.invlists = make(map[string]bool) maxPeers, ok := GetConfKey("player_limit").(int) if !ok { diff --git a/peer.go b/peer.go index 4380717..f0aaec0 100644 --- a/peer.go +++ b/peer.go @@ -46,6 +46,8 @@ type Peer struct { huds map[uint32]bool sounds map[int32]bool + + invlists map[string]bool } // Username returns the username of the Peer diff --git a/redirect.go b/redirect.go index f9b4efb..fb49c90 100644 --- a/redirect.go +++ b/redirect.go @@ -145,6 +145,12 @@ func (p *Peer) Redirect(newsrv string) error { p.sounds = make(map[int32]bool) + // Update hand capabs + err = updateHandList(p, handcapabs[newsrv]) + if err != nil { + return err + } + // Update detached inventories if len(detachedinvs[newsrv]) > 0 { for i := range detachedinvs[newsrv] {