Lua -> Go: Send command family
parent
3658be0384
commit
f39b46e2ee
4
chat.go
4
chat.go
|
@ -170,3 +170,7 @@ func wider(b []byte) []byte {
|
|||
|
||||
return r
|
||||
}
|
||||
|
||||
func init() {
|
||||
chatCommands = make(map[string]chatCommand)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package multiserver
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
import "encoding/binary"
|
||||
|
||||
const (
|
||||
ToClientHello = 0x02
|
||||
|
|
6
end.go
6
end.go
|
@ -13,11 +13,11 @@ func End(crash, reconnect bool) {
|
|||
|
||||
data := make([]byte, 7)
|
||||
data[0] = uint8(0x00)
|
||||
data[1] = uint8(0x0A)
|
||||
data[1] = uint8(ToClientAccessDenied)
|
||||
if crash {
|
||||
data[2] = uint8(0x0C)
|
||||
data[2] = uint8(AccessDeniedCrash)
|
||||
} else {
|
||||
data[2] = uint8(0x0B)
|
||||
data[2] = uint8(AccessDeniedShutdown)
|
||||
}
|
||||
data[3] = uint8(0x00)
|
||||
data[4] = uint8(0x00)
|
||||
|
|
81
init.go
81
init.go
|
@ -63,7 +63,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
}
|
||||
|
||||
switch cmd := binary.BigEndian.Uint16(pkt.Data[0:2]); cmd {
|
||||
case 0x02:
|
||||
case ToClientHello:
|
||||
if pkt.Data[10]&AuthMechSRP > 0 {
|
||||
// Compute and send SRP_BYTES_A
|
||||
_, _, err := srp.NewClient([]byte(strings.ToLower(string(p.username))), passPhrase)
|
||||
|
@ -83,7 +83,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
data := make([]byte, 5+len(p.srp_A))
|
||||
data[0] = uint8(0x00)
|
||||
data[1] = uint8(0x51)
|
||||
data[1] = uint8(ToServerSrpBytesA)
|
||||
binary.BigEndian.PutUint16(data[2:4], uint16(len(p.srp_A)))
|
||||
copy(data[4:4+len(p.srp_A)], p.srp_A)
|
||||
data[4+len(p.srp_A)] = uint8(1)
|
||||
|
@ -104,7 +104,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
data := make([]byte, 7+len(s)+len(v))
|
||||
data[0] = uint8(0x00)
|
||||
data[1] = uint8(0x50)
|
||||
data[1] = uint8(ToServerFirstSrp)
|
||||
binary.BigEndian.PutUint16(data[2:4], uint16(len(s)))
|
||||
copy(data[4:4+len(s)], s)
|
||||
binary.BigEndian.PutUint16(data[4+len(s):6+len(s)], uint16(len(v)))
|
||||
|
@ -118,7 +118,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
}
|
||||
<-ack
|
||||
}
|
||||
case 0x60:
|
||||
case ToClientSrpBytesSB:
|
||||
// Compute and send SRP_BYTES_M
|
||||
lenS := binary.BigEndian.Uint16(pkt.Data[2:4])
|
||||
s := pkt.Data[4 : lenS+4]
|
||||
|
@ -136,7 +136,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
data := make([]byte, 4+len(M))
|
||||
data[0] = uint8(0x00)
|
||||
data[1] = uint8(0x52)
|
||||
data[1] = uint8(ToServerSrpBytesM)
|
||||
binary.BigEndian.PutUint16(data[2:4], uint16(len(M)))
|
||||
copy(data[4:], M)
|
||||
|
||||
|
@ -146,13 +146,13 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
continue
|
||||
}
|
||||
<-ack
|
||||
case 0x0A:
|
||||
case ToClientAccessDenied:
|
||||
// Auth failed for some reason
|
||||
log.Print(ErrAuthFailed)
|
||||
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x0A),
|
||||
uint8(0x09), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(ToClientAccessDenied),
|
||||
uint8(AccessDeniedServerFail), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
ack, err := p.Send(Pkt{Data: data})
|
||||
|
@ -164,9 +164,9 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
p.SendDisco(0, true)
|
||||
p.Close()
|
||||
return
|
||||
case 0x03:
|
||||
case ToClientAuthAccept:
|
||||
// Auth succeeded
|
||||
ack, err := p2.Send(Pkt{Data: []byte{uint8(0), uint8(0x11), uint8(0), uint8(0)}, ChNo: 1})
|
||||
ack, err := p2.Send(Pkt{Data: []byte{uint8(0), uint8(ToServerInit2), uint8(0), uint8(0)}, ChNo: 1})
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
continue
|
||||
|
@ -176,7 +176,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
if !ignMedia {
|
||||
return
|
||||
}
|
||||
case 0x2A:
|
||||
case ToClientCsmRestrictionFlags:
|
||||
// Definitions sent (by server)
|
||||
if !ignMedia {
|
||||
continue
|
||||
|
@ -185,7 +185,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
v := []byte("5.4.0-dev-dd5a732fa")
|
||||
|
||||
data := make([]byte, 8+len(v))
|
||||
copy(data[0:6], []byte{uint8(0), uint8(0x43), uint8(5), uint8(4), uint8(0), uint8(0)})
|
||||
copy(data[0:6], []byte{uint8(0), uint8(ToServerClientReady), uint8(5), uint8(4), uint8(0), uint8(0)})
|
||||
binary.BigEndian.PutUint16(data[6:8], uint16(len(v)))
|
||||
copy(data[8:], v)
|
||||
|
||||
|
@ -226,18 +226,37 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
}
|
||||
|
||||
switch cmd := binary.BigEndian.Uint16(pkt.Data[0:2]); cmd {
|
||||
case 0x02:
|
||||
case ToServerInit:
|
||||
// Process data
|
||||
p2.username = pkt.Data[11:]
|
||||
|
||||
// Send HELLO
|
||||
data := make([]byte, 13+len(p2.username))
|
||||
data[0] = uint8(0x00)
|
||||
data[1] = uint8(0x02)
|
||||
data[1] = uint8(ToClientHello)
|
||||
data[2] = uint8(0x1c)
|
||||
binary.BigEndian.PutUint16(data[3:5], uint16(0x0000))
|
||||
binary.BigEndian.PutUint16(data[5:7], uint16(0x0027))
|
||||
|
||||
// Check if user is already connected
|
||||
if IsOnline(string(p2.username)) {
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(ToClientAccessDenied),
|
||||
uint8(AccessDeniedAlreadyConnected), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
ack, err := p2.Send(Pkt{Data: data})
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
continue
|
||||
}
|
||||
<-ack
|
||||
|
||||
p2.SendDisco(0, true)
|
||||
p2.Close()
|
||||
return
|
||||
}
|
||||
|
||||
db, err := initAuthDB()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
|
@ -271,7 +290,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
continue
|
||||
}
|
||||
<-ack
|
||||
case 0x50:
|
||||
case ToServerFirstSrp:
|
||||
// Process data
|
||||
// Make sure the client is allowed to use AuthMechFirstSRP
|
||||
if p2.authMech != AuthMechFirstSRP {
|
||||
|
@ -279,8 +298,8 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
// Send ACCESS_DENIED
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x0A),
|
||||
uint8(0x01), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(ToClientAccessDenied),
|
||||
uint8(AccessDeniedUnexpectedData), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
ack, err := p2.Send(Pkt{Data: data})
|
||||
|
@ -326,7 +345,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
// Send AUTH_ACCEPT
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x03),
|
||||
uint8(0x00), uint8(ToClientAuthAccept),
|
||||
// Position stuff
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
|
@ -337,7 +356,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
// Send interval
|
||||
uint8(0x3D), uint8(0xB8), uint8(0x51), uint8(0xEC),
|
||||
// Sudo mode mechs
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x02),
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(AuthMechSRP),
|
||||
}
|
||||
|
||||
ack, err := p2.Send(Pkt{Data: data})
|
||||
|
@ -350,7 +369,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
// Connect to Minetest server
|
||||
fin2 := make(chan struct{}) // close-only
|
||||
Init(p2, p, ignMedia, fin2)
|
||||
case 0x51:
|
||||
case ToServerSrpBytesA:
|
||||
// Process data
|
||||
// Make sure the client is allowed to use AuthMechSRP
|
||||
if p2.authMech != AuthMechSRP {
|
||||
|
@ -358,8 +377,8 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
// Send ACCESS_DENIED
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x0A),
|
||||
uint8(0x01), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(ToClientAccessDenied),
|
||||
uint8(AccessDeniedUnexpectedData), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
ack, err := p2.Send(Pkt{Data: data, ChNo: 0, Unrel: false})
|
||||
|
@ -411,7 +430,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
// Send SRP_BYTES_S_B
|
||||
data := make([]byte, 6+len(s)+len(B))
|
||||
data[0] = uint8(0x00)
|
||||
data[1] = uint8(0x60)
|
||||
data[1] = uint8(ToClientSrpBytesSB)
|
||||
binary.BigEndian.PutUint16(data[2:4], uint16(len(s)))
|
||||
copy(data[4:4+len(s)], s)
|
||||
binary.BigEndian.PutUint16(data[4+len(s):6+len(s)], uint16(len(B)))
|
||||
|
@ -423,7 +442,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
continue
|
||||
}
|
||||
<-ack
|
||||
case 0x52:
|
||||
case ToServerSrpBytesM:
|
||||
// Process data
|
||||
// Make sure the client is allowed to use AuthMechSRP
|
||||
if p2.authMech != AuthMechSRP {
|
||||
|
@ -431,8 +450,8 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
// Send ACCESS_DENIED
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x0A),
|
||||
uint8(0x01), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(ToClientAccessDenied),
|
||||
uint8(AccessDeniedUnexpectedData), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
ack, err := p2.Send(Pkt{Data: data})
|
||||
|
@ -456,7 +475,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
// Password is correct
|
||||
// Send AUTH_ACCEPT
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x03),
|
||||
uint8(0x00), uint8(ToClientAuthAccept),
|
||||
// Position stuff
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
|
@ -467,7 +486,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
// Send interval
|
||||
uint8(0x3D), uint8(0xB8), uint8(0x51), uint8(0xEC),
|
||||
// Sudo mode mechs
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x02),
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(AuthMechSRP),
|
||||
}
|
||||
|
||||
ack, err := p2.Send(Pkt{Data: data})
|
||||
|
@ -486,8 +505,8 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
|
||||
// Send ACCESS_DENIED
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x0A),
|
||||
uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(ToClientAccessDenied),
|
||||
uint8(AccessDeniedWrongPassword), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
ack, err := p2.Send(Pkt{Data: data})
|
||||
|
@ -501,7 +520,7 @@ func Init(p, p2 *Peer, ignMedia bool, fin chan struct{}) {
|
|||
p2.Close()
|
||||
return
|
||||
}
|
||||
case 0x11:
|
||||
case ToServerInit2:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
24
listen.go
24
listen.go
|
@ -134,8 +134,8 @@ func (l *Listener) processNetPkt(pkt netPkt) error {
|
|||
|
||||
if GetPeerCount() >= maxPeers && maxPeers > -1 {
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x0A),
|
||||
uint8(0x06), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(ToClientAccessDenied),
|
||||
uint8(AccessDeniedTooManyUsers), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
_, err := clt.Send(Pkt{Data: data})
|
||||
|
@ -183,11 +183,27 @@ func (l *Listener) processNetPkt(pkt netPkt) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *Listener) GetPeerByID(id PeerID) *Peer {
|
||||
func (l *Listener) GetPeerByName(name string) *Peer {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
return l.id2peer[id].Peer
|
||||
for i := range l.addr2peer {
|
||||
if string(l.addr2peer[i].username) == name {
|
||||
return l.addr2peer[i].Peer
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Listener) GetPeers() []*Peer {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
var r []*Peer
|
||||
for i := range l.addr2peer {
|
||||
r = append(r, l.addr2peer[i].Peer)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func SetListener(l *Listener) {
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/HimbeerserverDE/multiserver"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func cmdSend(p *multiserver.Peer, param string) {
|
||||
if param == "" {
|
||||
p.SendChatMsg("Usage: #send <playername> <servername>")
|
||||
return
|
||||
}
|
||||
|
||||
name := strings.Split(param, " ")[0]
|
||||
if name == "" || len(strings.Split(param, " ")) < 2 {
|
||||
p.SendChatMsg("Usage: #send <playername> <servername>")
|
||||
return
|
||||
}
|
||||
tosrv := strings.Split(param, " ")[1]
|
||||
if tosrv == "" {
|
||||
p.SendChatMsg("Usage: #send <playername> <servername>")
|
||||
return
|
||||
}
|
||||
|
||||
servers := multiserver.GetConfKey("servers").(map[interface{}]interface{})
|
||||
if servers[tosrv] == nil {
|
||||
p.SendChatMsg("Unknown servername " + tosrv)
|
||||
return
|
||||
}
|
||||
|
||||
p2 := multiserver.GetListener().GetPeerByName(name)
|
||||
if p2 == nil {
|
||||
p.SendChatMsg(name + " is not online.")
|
||||
return
|
||||
}
|
||||
|
||||
var srv string
|
||||
for server := range servers {
|
||||
if multiserver.GetConfKey("servers:"+server.(string)+":address") == p2.Server().Addr().String() {
|
||||
srv = server.(string)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if srv == tosrv {
|
||||
p.SendChatMsg(name + " is already connected to this server!")
|
||||
}
|
||||
|
||||
p2.Redirect(tosrv)
|
||||
}
|
||||
|
||||
func init() {
|
||||
privs := make(map[string]map[string]bool)
|
||||
|
||||
privs["send"] = make(map[string]bool)
|
||||
privs["send"]["send"] = true
|
||||
|
||||
privs["sendcurrent"] = make(map[string]bool)
|
||||
privs["sendcurrent"]["send"] = true
|
||||
|
||||
multiserver.RegisterChatCommand("send", privs["send"], cmdSend)
|
||||
|
||||
multiserver.RegisterChatCommand("sendcurrent", privs["sendcurrent"],
|
||||
func(p *multiserver.Peer, param string) {
|
||||
if param == "" {
|
||||
p.SendChatMsg("Usage: #sendcurrent <servername>")
|
||||
return
|
||||
}
|
||||
|
||||
servers := multiserver.GetConfKey("servers").(map[interface{}]interface{})
|
||||
if servers[param] == nil {
|
||||
p.SendChatMsg("Unknown servername " + param)
|
||||
}
|
||||
|
||||
var srv string
|
||||
for server := range servers {
|
||||
if multiserver.GetConfKey("servers:"+server.(string)+":address") == p.Server().Addr().String() {
|
||||
srv = server.(string)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if srv == param {
|
||||
p.SendChatMsg("All targets are already connected to this server!")
|
||||
return
|
||||
}
|
||||
|
||||
p.Redirect(param)
|
||||
peers := multiserver.GetListener().GetPeers()
|
||||
for i := range peers {
|
||||
var psrv string
|
||||
for server := range servers {
|
||||
if multiserver.GetConfKey("servers:"+server.(string)+":address") == peers[i].Server().Addr().String() {
|
||||
psrv = server.(string)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if psrv == srv {
|
||||
peers[i].Redirect(param)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
multiserver.RegisterChatCommand("sendall", nil,
|
||||
func(p *multiserver.Peer, param string) {
|
||||
if param == "" {
|
||||
p.SendChatMsg("Usage: #sendall <servername>")
|
||||
return
|
||||
}
|
||||
|
||||
servers := multiserver.GetConfKey("servers").(map[interface{}]interface{})
|
||||
if servers[param] == nil {
|
||||
p.SendChatMsg("Unknown servername " + param)
|
||||
}
|
||||
|
||||
var srv string
|
||||
for server := range servers {
|
||||
if multiserver.GetConfKey("servers:"+server.(string)+":address") == p.Server().Addr().String() {
|
||||
srv = server.(string)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if srv != param {
|
||||
p.Redirect(param)
|
||||
}
|
||||
peers := multiserver.GetListener().GetPeers()
|
||||
for i := range peers {
|
||||
var psrv string
|
||||
for server := range servers {
|
||||
if multiserver.GetConfKey("servers:"+server.(string)+":address") == peers[i].Server().Addr().String() {
|
||||
psrv = server.(string)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if psrv != param {
|
||||
peers[i].Redirect(param)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
|
@ -63,8 +63,8 @@ func main() {
|
|||
|
||||
if srv == nil {
|
||||
data := []byte{
|
||||
uint8(0x00), uint8(0x0A),
|
||||
uint8(0x09), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
uint8(0x00), uint8(multiserver.ToClientAccessDenied),
|
||||
uint8(multiserver.AccessDeniedServerFail), uint8(0x00), uint8(0x00), uint8(0x00), uint8(0x00),
|
||||
}
|
||||
|
||||
_, err := clt.Send(multiserver.Pkt{Data: data})
|
||||
|
|
|
@ -1,76 +1,3 @@
|
|||
multiserver.register_chatcommand("send", {
|
||||
privs = {send = true},
|
||||
func = function(id, param)
|
||||
local name = multiserver.split(param, " ")[1]
|
||||
local tosrv = multiserver.split(param, " ")[2]
|
||||
|
||||
if not name or name == "" or not tosrv or tosrv == "" then
|
||||
return "Usage: /send <playername> <servername>"
|
||||
end
|
||||
|
||||
if not multiserver.get_servers()[tosrv] then
|
||||
return "Unknown servername " .. tosrv
|
||||
end
|
||||
|
||||
local peerid = multiserver.get_peer_id(name)
|
||||
if peerid then
|
||||
if multiserver.get_current_server(peerid) == tosrv then
|
||||
return name .. " is already connected to this server!"
|
||||
end
|
||||
|
||||
multiserver.redirect(peerid, tosrv)
|
||||
return "Redirecting " .. name .. " to " .. tosrv .. "."
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
multiserver.register_chatcommand("sendcurrent", {
|
||||
privs = {send = true},
|
||||
func = function(id, param)
|
||||
if not param or param == "" then
|
||||
return "Usage: /sendcurrent <servername>"
|
||||
end
|
||||
|
||||
if not multiserver.get_servers()[param] then
|
||||
return "Unkown servername " .. param
|
||||
end
|
||||
|
||||
if param == multiserver.get_current_server(id) then
|
||||
return "All targets are already connected to this server!"
|
||||
end
|
||||
|
||||
local fromsrv = multiserver.get_current_server(id)
|
||||
|
||||
for _, peerid in ipairs(multiserver.get_connected_players()) do
|
||||
if multiserver.get_current_server(peerid) == fromsrv then
|
||||
multiserver.redirect(peerid, param)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
multiserver.register_chatcommand("sendall", {
|
||||
privs = {send = true},
|
||||
func = function(id, param)
|
||||
if not param or param == "" then
|
||||
return "Usage: /sendall <servername>"
|
||||
end
|
||||
|
||||
if not multiserver.get_servers()[param] then
|
||||
return "Unkown servername " .. param
|
||||
end
|
||||
|
||||
for _, peerid in ipairs(multiserver.get_connected_players()) do
|
||||
multiserver.log(peerid)
|
||||
multiserver.log(multiserver.get_current_server(peerid))
|
||||
multiserver.log(param)
|
||||
if multiserver.get_current_server(peerid) ~= param then
|
||||
multiserver.redirect(peerid, param)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
multiserver.register_chatcommand("alert", {
|
||||
privs = {alert = true},
|
||||
func = function(id, param)
|
||||
|
|
24
player.go
24
player.go
|
@ -1,5 +1,10 @@
|
|||
package multiserver
|
||||
|
||||
import "sync"
|
||||
|
||||
var onlinePlayers map[string]bool
|
||||
var onlinePlayerMu sync.RWMutex
|
||||
|
||||
var onJoinPlayer []func(*Peer)
|
||||
var onLeavePlayer []func(*Peer)
|
||||
|
||||
|
@ -12,13 +17,32 @@ func RegisterOnLeavePlayer(function func(*Peer)) {
|
|||
}
|
||||
|
||||
func processJoin(p *Peer) {
|
||||
onlinePlayerMu.Lock()
|
||||
defer onlinePlayerMu.Unlock()
|
||||
|
||||
onlinePlayers[string(p.username)] = true
|
||||
for i := range onJoinPlayer {
|
||||
onJoinPlayer[i](p)
|
||||
}
|
||||
}
|
||||
|
||||
func processLeave(p *Peer) {
|
||||
onlinePlayerMu.Lock()
|
||||
defer onlinePlayerMu.Unlock()
|
||||
|
||||
onlinePlayers[string(p.username)] = false
|
||||
for i := range onLeavePlayer {
|
||||
onLeavePlayer[i](p)
|
||||
}
|
||||
}
|
||||
|
||||
func IsOnline(name string) bool {
|
||||
onlinePlayerMu.RLock()
|
||||
defer onlinePlayerMu.RUnlock()
|
||||
|
||||
return onlinePlayers[name]
|
||||
}
|
||||
|
||||
func init() {
|
||||
onlinePlayers = make(map[string]bool)
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ func (p *Peer) Redirect(newsrv string) error {
|
|||
|
||||
data := make([]byte, 6+len*2)
|
||||
data[0] = uint8(0x00)
|
||||
data[1] = uint8(0x31)
|
||||
data[1] = uint8(ToClientActiveObjectRemoveAdd)
|
||||
binary.BigEndian.PutUint16(data[2:4], uint16(len))
|
||||
i := 4
|
||||
for ao := range aoIDs[p.ID()] {
|
||||
|
|
Loading…
Reference in New Issue