2021-01-14 04:40:31 -08:00
|
|
|
package multiserver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"log"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
"unicode/utf16"
|
|
|
|
)
|
|
|
|
|
|
|
|
type chatCommand struct {
|
|
|
|
privs map[string]bool
|
|
|
|
function func(*Peer, string)
|
|
|
|
}
|
|
|
|
|
|
|
|
var chatCommands map[string]chatCommand
|
2021-01-14 08:09:06 -08:00
|
|
|
var onChatMsg []func(*Peer, string) bool
|
2021-01-14 04:40:31 -08:00
|
|
|
|
2021-01-17 02:08:34 -08:00
|
|
|
var serverChatCommands map[string]func(*Peer, string)
|
|
|
|
var onServerChatMsg []func(*Peer, string) bool
|
|
|
|
|
2021-01-14 07:27:42 -08:00
|
|
|
func RegisterChatCommand(name string, privs map[string]bool, function func(*Peer, string)) {
|
2021-01-14 04:40:31 -08:00
|
|
|
chatCommands[name] = chatCommand{privs: privs, function: function}
|
|
|
|
}
|
|
|
|
|
2021-01-17 02:08:34 -08:00
|
|
|
func RegisterOnChatMessage(function func(*Peer, string) bool) {
|
2021-01-14 04:40:31 -08:00
|
|
|
onChatMsg = append(onChatMsg, function)
|
|
|
|
}
|
|
|
|
|
2021-01-17 02:08:34 -08:00
|
|
|
func RegisterServerChatCommand(name string, function func(*Peer, string)) {
|
|
|
|
serverChatCommands[name] = function
|
|
|
|
}
|
|
|
|
|
|
|
|
func RegisterOnServerChatMessage(function func(*Peer, string) bool) {
|
|
|
|
onServerChatMsg = append(onServerChatMsg, function)
|
|
|
|
}
|
|
|
|
|
2021-01-14 04:40:31 -08:00
|
|
|
func processChatMessage(p *Peer, pkt Pkt) bool {
|
|
|
|
s := string(narrow(pkt.Data[4:]))
|
|
|
|
if strings.HasPrefix(s, "#") {
|
|
|
|
// Chat command
|
|
|
|
s = strings.Replace(s, "#", "", 1)
|
|
|
|
params := strings.Split(s, " ")
|
|
|
|
|
|
|
|
// Priv check
|
2021-01-14 11:18:58 -08:00
|
|
|
allow, err := p.CheckPrivs(chatCommands[params[0]].privs)
|
2021-01-14 04:40:31 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
if !allow {
|
|
|
|
str := "You do not have permission to run this command! Required privileges: " + strings.Replace(encodePrivs(chatCommands[params[0]].privs), "|", " ", -1)
|
|
|
|
wstr := wider([]byte(str))
|
|
|
|
|
|
|
|
data := make([]byte, 16+len(wstr))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientChatMessage)
|
|
|
|
data[2] = uint8(0x01)
|
|
|
|
data[3] = uint8(0x00)
|
|
|
|
data[4] = uint8(0x00)
|
|
|
|
data[5] = uint8(0x00)
|
|
|
|
binary.BigEndian.PutUint16(data[6:8], uint16(len(str)))
|
|
|
|
copy(data[8:8+len(wstr)], wstr)
|
|
|
|
data[8+len(wstr)] = uint8(0x00)
|
|
|
|
data[9+len(wstr)] = uint8(0x00)
|
|
|
|
data[10+len(wstr)] = uint8(0x00)
|
|
|
|
data[11+len(wstr)] = uint8(0x00)
|
|
|
|
binary.BigEndian.PutUint32(data[12+len(wstr):16+len(wstr)], uint32(time.Now().Unix()))
|
|
|
|
|
|
|
|
ack, err := p.Send(Pkt{Data: data})
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Callback
|
2021-01-14 08:21:24 -08:00
|
|
|
// Existance check
|
|
|
|
if chatCommands[params[0]].function == nil {
|
|
|
|
str := "Unknown command " + params[0] + "."
|
|
|
|
wstr := wider([]byte(str))
|
|
|
|
|
|
|
|
data := make([]byte, 16+len(wstr))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientChatMessage)
|
|
|
|
data[2] = uint8(0x01)
|
|
|
|
data[3] = uint8(0x00)
|
|
|
|
data[4] = uint8(0x00)
|
|
|
|
data[5] = uint8(0x00)
|
|
|
|
binary.BigEndian.PutUint16(data[6:8], uint16(len(str)))
|
|
|
|
copy(data[8:8+len(wstr)], wstr)
|
|
|
|
data[8+len(wstr)] = uint8(0x00)
|
|
|
|
data[9+len(wstr)] = uint8(0x00)
|
|
|
|
data[10+len(wstr)] = uint8(0x00)
|
|
|
|
data[11+len(wstr)] = uint8(0x00)
|
|
|
|
binary.BigEndian.PutUint32(data[12+len(wstr):16+len(wstr)], uint32(time.Now().Unix()))
|
|
|
|
|
|
|
|
ack, err := p.Send(Pkt{Data: data})
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-01-14 04:40:31 -08:00
|
|
|
chatCommands[params[0]].function(p, strings.Join(params[1:], " "))
|
|
|
|
return true
|
|
|
|
} else {
|
|
|
|
// Regular message
|
2021-01-14 13:08:01 -08:00
|
|
|
noforward := false
|
2021-01-14 04:40:31 -08:00
|
|
|
for i := range onChatMsg {
|
|
|
|
if onChatMsg[i](p, s) {
|
2021-01-14 13:08:01 -08:00
|
|
|
noforward = true
|
2021-01-14 04:40:31 -08:00
|
|
|
}
|
|
|
|
}
|
2021-01-14 13:08:01 -08:00
|
|
|
return noforward
|
2021-01-14 04:40:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-17 02:08:34 -08:00
|
|
|
func processServerChatMessage(p *Peer, pkt Pkt) bool {
|
|
|
|
s := string(narrow(pkt.Data[4:]))
|
|
|
|
if strings.HasPrefix(s, ":") {
|
|
|
|
// Server chat command
|
|
|
|
s = strings.Replace(s, ":", "", 1)
|
|
|
|
params := strings.Split(s, " ")
|
|
|
|
|
|
|
|
// Callback
|
|
|
|
// Existance check
|
|
|
|
if serverChatCommands[params[0]] == nil {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
serverChatCommands[params[0]](p, strings.Join(params[1:], " "))
|
|
|
|
return true
|
|
|
|
} else {
|
|
|
|
// Regular message
|
|
|
|
noforward := false
|
|
|
|
for i := range onServerChatMsg {
|
|
|
|
if onServerChatMsg[i](p, s) {
|
|
|
|
noforward = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return noforward
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-14 07:27:42 -08:00
|
|
|
func (p *Peer) SendChatMsg(msg string) {
|
2021-01-14 04:40:31 -08:00
|
|
|
wstr := wider([]byte(msg))
|
|
|
|
|
|
|
|
data := make([]byte, 16+len(wstr))
|
|
|
|
data[0] = uint8(0x00)
|
|
|
|
data[1] = uint8(ToClientChatMessage)
|
|
|
|
data[2] = uint8(0x01)
|
|
|
|
data[3] = uint8(0x00)
|
|
|
|
data[4] = uint8(0x00)
|
|
|
|
data[5] = uint8(0x00)
|
|
|
|
binary.BigEndian.PutUint16(data[6:8], uint16(len(msg)))
|
|
|
|
copy(data[8:8+len(wstr)], wstr)
|
|
|
|
data[8+len(wstr)] = uint8(0x00)
|
|
|
|
data[9+len(wstr)] = uint8(0x00)
|
|
|
|
data[10+len(wstr)] = uint8(0x00)
|
|
|
|
data[11+len(wstr)] = uint8(0x00)
|
|
|
|
binary.BigEndian.PutUint32(data[12+len(wstr):16+len(wstr)], uint32(time.Now().Unix()))
|
|
|
|
|
|
|
|
ack, err := p.Send(Pkt{Data: data})
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
<-ack
|
|
|
|
}
|
|
|
|
|
2021-01-14 07:27:42 -08:00
|
|
|
func ChatSendAll(msg string) {
|
2021-01-14 04:40:31 -08:00
|
|
|
l := GetListener()
|
|
|
|
l.mu.Lock()
|
|
|
|
defer l.mu.Unlock()
|
|
|
|
|
|
|
|
for i := range l.addr2peer {
|
2021-01-14 10:55:12 -08:00
|
|
|
go l.addr2peer[i].SendChatMsg(msg)
|
2021-01-14 04:40:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func narrow(b []byte) []byte {
|
|
|
|
if len(b)%2 != 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
e := make([]uint16, len(b)/2)
|
|
|
|
|
|
|
|
for i := 0; i < len(b); i += 2 {
|
|
|
|
e[i/2] = binary.BigEndian.Uint16(b[i : 2+i])
|
|
|
|
}
|
|
|
|
|
|
|
|
return []byte(string(utf16.Decode(e)))
|
|
|
|
}
|
|
|
|
|
|
|
|
func wider(b []byte) []byte {
|
|
|
|
r := make([]byte, len(b)*2)
|
|
|
|
|
|
|
|
e := utf16.Encode([]rune(string(b)))
|
|
|
|
|
|
|
|
for i := range e {
|
|
|
|
binary.BigEndian.PutUint16(r[i*2:2+i*2], e[i])
|
|
|
|
}
|
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
2021-01-14 10:06:40 -08:00
|
|
|
|
|
|
|
func init() {
|
|
|
|
chatCommands = make(map[string]chatCommand)
|
2021-01-17 02:08:34 -08:00
|
|
|
serverChatCommands = make(map[string]func(*Peer, string))
|
2021-01-14 10:06:40 -08:00
|
|
|
}
|