2021-01-16 10:14:31 -08:00
|
|
|
package multiserver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"log"
|
|
|
|
"net"
|
2021-01-18 13:08:22 -08:00
|
|
|
|
|
|
|
"github.com/anon55555/mt/rudp"
|
2021-01-16 10:14:31 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
var media map[string]*mediaFile
|
|
|
|
var tooldefs [][]byte
|
|
|
|
var nodedefs [][]byte
|
|
|
|
var craftitemdefs [][]byte
|
|
|
|
var itemdefs [][]byte
|
2021-01-16 10:31:07 -08:00
|
|
|
var detachedinvs map[string][][]byte
|
2021-01-16 10:14:31 -08:00
|
|
|
var movement []byte
|
|
|
|
var timeofday []byte
|
|
|
|
|
|
|
|
type mediaFile struct {
|
|
|
|
digest []byte
|
|
|
|
data []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Peer) fetchMedia() {
|
|
|
|
if !p.IsSrv() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
pkt, err := p.Recv()
|
|
|
|
if err != nil {
|
2021-01-18 13:08:22 -08:00
|
|
|
if err == rudp.ErrClosed {
|
2021-01-16 10:14:31 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Print(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
switch cmd := binary.BigEndian.Uint16(pkt.Data[0:2]); cmd {
|
|
|
|
case ToClientTooldef:
|
|
|
|
tooldefs = append(tooldefs, pkt.Data[2:])
|
|
|
|
case ToClientNodedef:
|
|
|
|
nodedefs = append(nodedefs, pkt.Data[2:])
|
|
|
|
case ToClientCraftitemdef:
|
|
|
|
craftitemdefs = append(craftitemdefs, pkt.Data[2:])
|
|
|
|
case ToClientItemdef:
|
|
|
|
itemdefs = append(itemdefs, pkt.Data[2:])
|
|
|
|
case ToClientMovement:
|
|
|
|
movement = pkt.Data[2:]
|
|
|
|
case ToClientDetachedInventory:
|
2021-01-16 10:31:07 -08:00
|
|
|
servers := GetConfKey("servers").(map[interface{}]interface{})
|
|
|
|
var srvname string
|
|
|
|
for server := range servers {
|
|
|
|
if GetConfKey("servers:"+server.(string)+":address") == p.Addr().String() {
|
|
|
|
srvname = server.(string)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
detachedinvs[srvname] = append(detachedinvs[srvname], pkt.Data[2:])
|
2021-01-16 10:14:31 -08:00
|
|
|
case ToClientTimeOfDay:
|
|
|
|
timeofday = pkt.Data[2:]
|
|
|
|
case ToClientAnnounceMedia:
|
|
|
|
var rq []string
|
|
|
|
count := binary.BigEndian.Uint16(pkt.Data[2:4])
|
|
|
|
si := uint16(4)
|
|
|
|
for i := uint16(0); i < count; i++ {
|
2021-01-16 10:31:07 -08:00
|
|
|
namelen := binary.BigEndian.Uint16(pkt.Data[si : 2+si])
|
|
|
|
name := pkt.Data[2+si : 2+si+namelen]
|
|
|
|
diglen := binary.BigEndian.Uint16(pkt.Data[2+si+namelen : 4+si+namelen])
|
|
|
|
digest := pkt.Data[4+si+namelen : 4+si+namelen+diglen]
|
2021-01-16 10:14:31 -08:00
|
|
|
|
|
|
|
if media[string(name)] == nil {
|
|
|
|
rq = append(rq, string(name))
|
|
|
|
media[string(name)] = &mediaFile{digest: digest}
|
|
|
|
}
|
|
|
|
|
2021-01-16 10:31:07 -08:00
|
|
|
si += 4 + namelen + diglen
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Request the media
|
|
|
|
pktlen := 0
|
|
|
|
for f := range rq {
|
2021-01-16 10:31:07 -08:00
|
|
|
pktlen += 2 + len(rq[f])
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
data := make([]byte, 4+pktlen)
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToServerRequestMedia)
|
|
|
|
binary.BigEndian.PutUint16(data[2:4], uint16(len(rq)))
|
|
|
|
sj := 4
|
|
|
|
for f := range rq {
|
|
|
|
binary.BigEndian.PutUint16(data[sj:2+sj], uint16(len(rq[f])))
|
|
|
|
copy(data[2+sj:2+sj+len(rq[f])], []byte(rq[f]))
|
2021-01-16 10:31:07 -08:00
|
|
|
sj += 2 + len(rq[f])
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
_, err := p.Send(rudp.Pkt{Data: data, ChNo: 1})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
case ToClientMedia:
|
|
|
|
bunchcount := binary.BigEndian.Uint16(pkt.Data[2:4])
|
|
|
|
bunch := binary.BigEndian.Uint16(pkt.Data[4:6])
|
|
|
|
filecount := binary.BigEndian.Uint32(pkt.Data[6:10])
|
|
|
|
si := uint32(10)
|
|
|
|
for i := uint32(0); i < filecount; i++ {
|
2021-01-16 10:31:07 -08:00
|
|
|
namelen := binary.BigEndian.Uint16(pkt.Data[si : 2+si])
|
|
|
|
name := pkt.Data[2+si : 2+si+uint32(namelen)]
|
|
|
|
datalen := binary.BigEndian.Uint32(pkt.Data[2+si+uint32(namelen) : 6+si+uint32(namelen)])
|
|
|
|
data := pkt.Data[6+si+uint32(namelen) : 6+uint32(si)+uint32(namelen)+datalen]
|
2021-01-16 10:14:31 -08:00
|
|
|
|
|
|
|
if media[string(name)] != nil && len(media[string(name)].data) == 0 {
|
|
|
|
media[string(name)].data = data
|
|
|
|
}
|
|
|
|
|
2021-01-16 10:31:07 -08:00
|
|
|
si += 6 + uint32(namelen) + datalen
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if bunch >= bunchcount-1 {
|
|
|
|
p.SendDisco(0, true)
|
|
|
|
p.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-20 12:44:35 -08:00
|
|
|
func (p *Peer) updateDetachedInvs(srvname string) {
|
|
|
|
for i := range detachedinvs[srvname] {
|
|
|
|
data := make([]byte, 2+len(detachedinvs[srvname][i]))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientDetachedInventory)
|
|
|
|
copy(data[2:], detachedinvs[srvname][i])
|
|
|
|
|
|
|
|
ack, err := p.Send(rudp.Pkt{Data: data})
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-16 10:14:31 -08:00
|
|
|
func (p *Peer) announceMedia() {
|
2021-01-19 09:57:58 -08:00
|
|
|
srvname, ok := GetConfKey("default_server").(string)
|
|
|
|
if !ok {
|
2021-01-16 10:31:07 -08:00
|
|
|
log.Print("Default server name not set or not a string")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-01-16 10:14:31 -08:00
|
|
|
for _, def := range tooldefs {
|
|
|
|
data := make([]byte, 2+len(def))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientTooldef)
|
|
|
|
copy(data[2:], def)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err := p.Send(rudp.Pkt{Data: data})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, def := range nodedefs {
|
|
|
|
data := make([]byte, 2+len(def))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientNodedef)
|
|
|
|
copy(data[2:], def)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err := p.Send(rudp.Pkt{Data: data})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, def := range craftitemdefs {
|
|
|
|
data := make([]byte, 2+len(def))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientCraftitemdef)
|
|
|
|
copy(data[2:], def)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err := p.Send(rudp.Pkt{Data: data})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, def := range itemdefs {
|
|
|
|
data := make([]byte, 2+len(def))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientItemdef)
|
|
|
|
copy(data[2:], def)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err := p.Send(rudp.Pkt{Data: data})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
|
2021-01-20 12:44:35 -08:00
|
|
|
p.updateDetachedInvs(srvname)
|
2021-01-16 10:14:31 -08:00
|
|
|
|
|
|
|
data := make([]byte, 2+len(movement))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientMovement)
|
|
|
|
copy(data[2:], movement)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err := p.Send(rudp.Pkt{Data: data})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
|
|
|
|
data = make([]byte, 2+len(timeofday))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientTimeOfDay)
|
|
|
|
copy(data[2:], timeofday)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err = p.Send(rudp.Pkt{Data: data})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
|
|
|
|
pktlen := 0
|
|
|
|
for f := range media {
|
2021-01-16 10:31:07 -08:00
|
|
|
pktlen += 4 + len(f) + len(media[f].digest)
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
data = make([]byte, 6+pktlen)
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientAnnounceMedia)
|
|
|
|
binary.BigEndian.PutUint16(data[2:4], uint16(len(media)))
|
|
|
|
si := 4
|
|
|
|
for f := range media {
|
|
|
|
binary.BigEndian.PutUint16(data[si:2+si], uint16(len(f)))
|
|
|
|
copy(data[2+si:2+si+len(f)], []byte(f))
|
|
|
|
binary.BigEndian.PutUint16(data[2+si+len(f):4+si+len(f)], uint16(len(media[f].digest)))
|
|
|
|
copy(data[4+si+len(f):4+si+len(f)+len(media[f].digest)], media[f].digest)
|
2021-01-16 10:31:07 -08:00
|
|
|
si += 4 + len(f) + len(media[f].digest)
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
data[si] = uint8(0x00)
|
|
|
|
data[1+si] = uint8(0x00)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err = p.Send(rudp.Pkt{Data: data})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Peer) sendMedia(rqdata []byte) {
|
|
|
|
var rq []string
|
|
|
|
count := binary.BigEndian.Uint16(rqdata[0:2])
|
|
|
|
si := uint16(2)
|
|
|
|
for i := uint16(0); i < count; i++ {
|
2021-01-16 10:31:07 -08:00
|
|
|
namelen := binary.BigEndian.Uint16(rqdata[si : 2+si])
|
|
|
|
name := rqdata[2+si : 2+si+namelen]
|
2021-01-16 10:14:31 -08:00
|
|
|
rq = append(rq, string(name))
|
2021-01-16 10:31:07 -08:00
|
|
|
si += 2 + namelen
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
pktlen := 0
|
|
|
|
for f := range rq {
|
2021-01-16 10:31:07 -08:00
|
|
|
pktlen += 6 + len(rq[f]) + len(media[rq[f]].data)
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
data := make([]byte, 12+pktlen)
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientMedia)
|
|
|
|
data[2] = uint8(0x00)
|
|
|
|
data[3] = uint8(0x01)
|
|
|
|
data[4] = uint8(0x00)
|
|
|
|
data[5] = uint8(0x00)
|
|
|
|
binary.BigEndian.PutUint32(data[6:10], uint32(len(rq)))
|
|
|
|
sj := 10
|
|
|
|
for f := range rq {
|
|
|
|
binary.BigEndian.PutUint16(data[sj:2+sj], uint16(len(rq[f])))
|
|
|
|
copy(data[2+sj:2+sj+len(rq[f])], rq[f])
|
|
|
|
binary.BigEndian.PutUint32(data[2+sj+len(rq[f]):6+sj+len(rq[f])], uint32(len(media[rq[f]].data)))
|
|
|
|
copy(data[6+sj+len(rq[f]):6+sj+len(rq[f])+len(media[rq[f]].data)], media[rq[f]].data)
|
2021-01-16 10:31:07 -08:00
|
|
|
sj += 6 + len(rq[f]) + len(media[rq[f]].data)
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
data[sj] = uint8(0x00)
|
|
|
|
data[1+sj] = uint8(0x00)
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
ack, err := p.Send(rudp.Pkt{Data: data, ChNo: 2})
|
2021-01-16 10:14:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
log.Print("Fetching media")
|
|
|
|
|
|
|
|
media = make(map[string]*mediaFile)
|
2021-01-16 10:31:07 -08:00
|
|
|
detachedinvs = make(map[string][][]byte)
|
2021-01-16 10:14:31 -08:00
|
|
|
|
2021-01-16 10:35:28 -08:00
|
|
|
clt := &Peer{username: []byte("media")}
|
2021-01-16 10:14:31 -08:00
|
|
|
|
|
|
|
servers := GetConfKey("servers").(map[interface{}]interface{})
|
|
|
|
for server := range servers {
|
2021-01-16 10:31:07 -08:00
|
|
|
straddr := GetConfKey("servers:" + server.(string) + ":address")
|
2021-01-16 10:14:31 -08:00
|
|
|
|
|
|
|
srvaddr, err := net.ResolveUDPAddr("udp", straddr.(string))
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
conn, err := net.DialUDP("udp", nil, srvaddr)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2021-01-18 13:08:22 -08:00
|
|
|
srv, err := Connect(conn, conn.RemoteAddr())
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
2021-01-16 10:14:31 -08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-01-20 12:44:35 -08:00
|
|
|
fin := make(chan *Peer) // close-only
|
2021-01-16 10:14:31 -08:00
|
|
|
go Init(clt, srv, false, true, fin)
|
|
|
|
<-fin
|
|
|
|
|
2021-01-21 01:46:09 -08:00
|
|
|
srv.fetchMedia()
|
2021-01-16 10:14:31 -08:00
|
|
|
}
|
|
|
|
}
|