multiserver/media.go

339 lines
7.7 KiB
Go
Raw Normal View History

2021-01-16 10:14:31 -08:00
package multiserver
import (
"encoding/binary"
"log"
"net"
"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 {
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
}
_, 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)
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)
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)
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)
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)
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)
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)
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)
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)
}
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
}
}