Add basic infrastructure for bouncer service
This commit is contained in:
parent
8274ff17c1
commit
e3d97bb164
@ -326,15 +326,21 @@ func (dc *downstreamConn) handleMessage(msg *irc.Message) error {
|
|||||||
func (dc *downstreamConn) handleMessageUnregistered(msg *irc.Message) error {
|
func (dc *downstreamConn) handleMessageUnregistered(msg *irc.Message) error {
|
||||||
switch msg.Command {
|
switch msg.Command {
|
||||||
case "NICK":
|
case "NICK":
|
||||||
if err := parseMessageParams(msg, &dc.nick); err != nil {
|
var nick string
|
||||||
|
if err := parseMessageParams(msg, &nick); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if nick == serviceNick {
|
||||||
|
return ircError{&irc.Message{
|
||||||
|
Command: irc.ERR_NICKNAMEINUSE,
|
||||||
|
Params: []string{dc.nick, nick, "Nickname reserved for bouncer service"},
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
dc.nick = nick
|
||||||
case "USER":
|
case "USER":
|
||||||
var username string
|
if err := parseMessageParams(msg, &dc.rawUsername, nil, nil, &dc.realname); err != nil {
|
||||||
if err := parseMessageParams(msg, &username, nil, nil, &dc.realname); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dc.rawUsername = username
|
|
||||||
case "PASS":
|
case "PASS":
|
||||||
if err := parseMessageParams(msg, &dc.password); err != nil {
|
if err := parseMessageParams(msg, &dc.password); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -890,6 +896,11 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range strings.Split(targetsStr, ",") {
|
for _, name := range strings.Split(targetsStr, ",") {
|
||||||
|
if name == serviceNick {
|
||||||
|
handleServicePRIVMSG(dc, text)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
uc, upstreamName, err := dc.unmarshalChannel(name)
|
uc, upstreamName, err := dc.unmarshalChannel(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
1
go.mod
1
go.mod
@ -4,6 +4,7 @@ go 1.13
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b
|
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||||
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4
|
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b h1:uhWtEWBHgop1rqEk2klKaxPAkVDCXexai6hSuRQ7Nvs=
|
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b h1:uhWtEWBHgop1rqEk2klKaxPAkVDCXexai6hSuRQ7Nvs=
|
||||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k=
|
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k=
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
87
service.go
Normal file
87
service.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package soju
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/shlex"
|
||||||
|
"gopkg.in/irc.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const serviceNick = "BouncerServ"
|
||||||
|
|
||||||
|
type serviceCommand struct {
|
||||||
|
usage string
|
||||||
|
desc string
|
||||||
|
handle func(dc *downstreamConn, params []string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendServicePRIVMSG(dc *downstreamConn, text string) {
|
||||||
|
dc.SendMessage(&irc.Message{
|
||||||
|
Prefix: &irc.Prefix{Name: serviceNick},
|
||||||
|
Command: "PRIVMSG",
|
||||||
|
Params: []string{dc.nick, text},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleServicePRIVMSG(dc *downstreamConn, text string) {
|
||||||
|
words, err := shlex.Split(text)
|
||||||
|
if err != nil {
|
||||||
|
sendServicePRIVMSG(dc, fmt.Sprintf("error: failed to parse command: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var name string
|
||||||
|
var params []string
|
||||||
|
if len(words) > 0 {
|
||||||
|
name = strings.ToLower(words[0])
|
||||||
|
params = words[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd, ok := serviceCommands[name]
|
||||||
|
if !ok {
|
||||||
|
sendServicePRIVMSG(dc, fmt.Sprintf(`error: unknown command %q (type "help" for a list of commands)`, name))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.handle(dc, params); err != nil {
|
||||||
|
sendServicePRIVMSG(dc, fmt.Sprintf("error: %v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var serviceCommands map[string]serviceCommand
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
serviceCommands = map[string]serviceCommand{
|
||||||
|
"help": {
|
||||||
|
usage: "[command]",
|
||||||
|
desc: "print help message",
|
||||||
|
handle: handleServiceHelp,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleServiceHelp(dc *downstreamConn, params []string) error {
|
||||||
|
if len(params) > 0 {
|
||||||
|
name := strings.ToLower(params[0])
|
||||||
|
cmd, ok := serviceCommands[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unknown command %q", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
text := name
|
||||||
|
if cmd.usage != "" {
|
||||||
|
text += " " + cmd.usage
|
||||||
|
}
|
||||||
|
text += ": " + cmd.desc
|
||||||
|
|
||||||
|
sendServicePRIVMSG(dc, text)
|
||||||
|
} else {
|
||||||
|
var l []string
|
||||||
|
for name := range serviceCommands {
|
||||||
|
l = append(l, name)
|
||||||
|
}
|
||||||
|
sendServicePRIVMSG(dc, "available commands: "+strings.Join(l, ", "))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
17
upstream.go
17
upstream.go
@ -558,9 +558,24 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
|||||||
forwardChannel(dc, ch)
|
forwardChannel(dc, ch)
|
||||||
})
|
})
|
||||||
case "PRIVMSG":
|
case "PRIVMSG":
|
||||||
if err := parseMessageParams(msg, nil, nil); err != nil {
|
if msg.Prefix == nil {
|
||||||
|
return fmt.Errorf("expected a prefix")
|
||||||
|
}
|
||||||
|
|
||||||
|
var nick string
|
||||||
|
if err := parseMessageParams(msg, &nick, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if msg.Prefix.Name == serviceNick {
|
||||||
|
uc.logger.Printf("skipping PRIVMSG from soju's service: %v", msg)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if nick == serviceNick {
|
||||||
|
uc.logger.Printf("skipping PRIVMSG to soju's service: %v", msg)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
uc.ring.Produce(msg)
|
uc.ring.Produce(msg)
|
||||||
case "INVITE":
|
case "INVITE":
|
||||||
var nick string
|
var nick string
|
||||||
|
Loading…
Reference in New Issue
Block a user