Forward irc errors to the client, improve command validation and feedback, handle topic changes
This commit is contained in:
parent
993d29242e
commit
aa59e71745
17 changed files with 328 additions and 96 deletions
|
@ -3,6 +3,7 @@ package server
|
|||
import (
|
||||
"log"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/kjk/betterguid"
|
||||
|
||||
|
@ -52,6 +53,10 @@ func (i *ircHandler) run() {
|
|||
}
|
||||
|
||||
func (i *ircHandler) dispatchMessage(msg *irc.Message) {
|
||||
if msg.Command[0] == '4' {
|
||||
i.session.printError(formatIRCError(msg))
|
||||
}
|
||||
|
||||
if handler, ok := i.handlers[msg.Command]; ok {
|
||||
handler(msg)
|
||||
}
|
||||
|
@ -78,14 +83,18 @@ func (i *ircHandler) join(msg *irc.Message) {
|
|||
Channels: msg.Params,
|
||||
})
|
||||
|
||||
channelStore.AddUser(msg.Nick, i.client.Host, msg.Params[0])
|
||||
channel := msg.Params[0]
|
||||
channelStore.AddUser(msg.Nick, i.client.Host, channel)
|
||||
|
||||
if msg.Nick == i.client.GetNick() {
|
||||
i.session.sendLastMessages(i.client.Host, msg.Params[0], 50)
|
||||
// Incase no topic is set and theres a cached one that needs to be cleared
|
||||
i.client.Topic(channel)
|
||||
|
||||
i.session.sendLastMessages(i.client.Host, channel, 50)
|
||||
|
||||
go i.session.user.AddChannel(storage.Channel{
|
||||
Server: i.client.Host,
|
||||
Name: msg.Params[0],
|
||||
Name: channel,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -193,13 +202,35 @@ func (i *ircHandler) whoisEnd(msg *irc.Message) {
|
|||
}
|
||||
|
||||
func (i *ircHandler) topic(msg *irc.Message) {
|
||||
var channel string
|
||||
var nick string
|
||||
|
||||
if msg.Command == irc.Topic {
|
||||
channel = msg.Params[0]
|
||||
nick = msg.Nick
|
||||
} else {
|
||||
channel = msg.Params[1]
|
||||
}
|
||||
|
||||
i.session.sendJSON("topic", Topic{
|
||||
Server: i.client.Host,
|
||||
Channel: msg.Params[1],
|
||||
Channel: channel,
|
||||
Topic: msg.LastParam(),
|
||||
Nick: nick,
|
||||
})
|
||||
|
||||
channelStore.SetTopic(msg.LastParam(), i.client.Host, msg.Params[1])
|
||||
channelStore.SetTopic(msg.LastParam(), i.client.Host, channel)
|
||||
}
|
||||
|
||||
func (i *ircHandler) noTopic(msg *irc.Message) {
|
||||
channel := msg.Params[1]
|
||||
|
||||
i.session.sendJSON("topic", Topic{
|
||||
Server: i.client.Host,
|
||||
Channel: channel,
|
||||
})
|
||||
|
||||
channelStore.SetTopic("", i.client.Host, channel)
|
||||
}
|
||||
|
||||
func (i *ircHandler) names(msg *irc.Message) {
|
||||
|
@ -245,6 +276,7 @@ func (i *ircHandler) initHandlers() {
|
|||
irc.Privmsg: i.message,
|
||||
irc.Notice: i.message,
|
||||
irc.Quit: i.quit,
|
||||
irc.Topic: i.topic,
|
||||
irc.ReplyWelcome: i.info,
|
||||
irc.ReplyYourHost: i.info,
|
||||
irc.ReplyCreated: i.info,
|
||||
|
@ -257,6 +289,7 @@ func (i *ircHandler) initHandlers() {
|
|||
irc.ReplyWhoisServer: i.whoisServer,
|
||||
irc.ReplyWhoisChannels: i.whoisChannels,
|
||||
irc.ReplyEndOfWhois: i.whoisEnd,
|
||||
irc.ReplyNoTopic: i.noTopic,
|
||||
irc.ReplyTopic: i.topic,
|
||||
irc.ReplyNamReply: i.names,
|
||||
irc.ReplyEndOfNames: i.namesEnd,
|
||||
|
@ -289,6 +322,19 @@ func isChannel(s string) bool {
|
|||
return strings.IndexAny(s, "&#+!") == 0
|
||||
}
|
||||
|
||||
func formatIRCError(msg *irc.Message) string {
|
||||
errMsg := strings.TrimSuffix(msg.LastParam(), ".")
|
||||
if len(msg.Params) > 2 {
|
||||
for _, c := range msg.LastParam() {
|
||||
if unicode.IsLower(c) {
|
||||
return msg.Params[1] + " " + errMsg
|
||||
}
|
||||
return msg.Params[1] + ": " + errMsg
|
||||
}
|
||||
}
|
||||
return errMsg
|
||||
}
|
||||
|
||||
func printMessage(msg *irc.Message, i *irc.Client) {
|
||||
log.Println(i.GetNick()+":", msg.Prefix, msg.Command, msg.Params, msg.LastParam())
|
||||
}
|
||||
|
|
|
@ -225,6 +225,31 @@ func TestHandleIRCTopic(t *testing.T) {
|
|||
Channel: "#chan",
|
||||
Topic: "the topic",
|
||||
}, res)
|
||||
|
||||
res = dispatchMessage(&irc.Message{
|
||||
Command: irc.Topic,
|
||||
Params: []string{"#chan", "the topic"},
|
||||
Nick: "bob",
|
||||
})
|
||||
|
||||
checkResponse(t, "topic", Topic{
|
||||
Server: "host.com",
|
||||
Channel: "#chan",
|
||||
Topic: "the topic",
|
||||
Nick: "bob",
|
||||
}, res)
|
||||
}
|
||||
|
||||
func TestHandleIRCNoTopic(t *testing.T) {
|
||||
res := dispatchMessage(&irc.Message{
|
||||
Command: irc.ReplyNoTopic,
|
||||
Params: []string{"target", "#chan", "No topic set."},
|
||||
})
|
||||
|
||||
checkResponse(t, "topic", Topic{
|
||||
Server: "host.com",
|
||||
Channel: "#chan",
|
||||
}, res)
|
||||
}
|
||||
|
||||
func TestHandleIRCNames(t *testing.T) {
|
||||
|
|
|
@ -61,11 +61,12 @@ type Quit struct {
|
|||
}
|
||||
|
||||
type Message struct {
|
||||
ID string `json:"id"`
|
||||
Server string `json:"server"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Server string `json:"server,omitempty"`
|
||||
From string `json:"from,omitempty"`
|
||||
To string `json:"to,omitempty"`
|
||||
Content string `json:"content"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
type Messages struct {
|
||||
|
@ -79,7 +80,8 @@ type Messages struct {
|
|||
type Topic struct {
|
||||
Server string `json:"server"`
|
||||
Channel string `json:"channel"`
|
||||
Topic string `json:"topic"`
|
||||
Topic string `json:"topic,omitempty"`
|
||||
Nick string `json:"nick,omitempty"`
|
||||
}
|
||||
|
||||
type Userlist struct {
|
||||
|
|
|
@ -162,13 +162,19 @@ func (s *Session) sendMessages(server, channel string, count int, fromID string)
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Session) print(server string, a ...interface{}) {
|
||||
func (s *Session) print(a ...interface{}) {
|
||||
s.sendJSON("print", Message{
|
||||
Server: server,
|
||||
Content: fmt.Sprintln(a...),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Session) printError(a ...interface{}) {
|
||||
s.sendJSON("print", Message{
|
||||
Content: fmt.Sprintln(a...),
|
||||
Type: "error",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Session) resetExpirationIfEmpty() {
|
||||
if s.numIRC() == 0 && s.numWS() == 0 {
|
||||
s.reset <- AnonymousSessionExpiration
|
||||
|
|
|
@ -190,6 +190,15 @@ func (h *wsHandler) nick(b []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *wsHandler) topic(b []byte) {
|
||||
var data Topic
|
||||
json.Unmarshal(b, &data)
|
||||
|
||||
if i, ok := h.session.getIRC(data.Server); ok {
|
||||
i.Topic(data.Channel, data.Topic)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *wsHandler) invite(b []byte) {
|
||||
var data Invite
|
||||
json.Unmarshal(b, &data)
|
||||
|
@ -282,6 +291,7 @@ func (h *wsHandler) initHandlers() {
|
|||
"quit": h.quit,
|
||||
"message": h.message,
|
||||
"nick": h.nick,
|
||||
"topic": h.topic,
|
||||
"invite": h.invite,
|
||||
"kick": h.kick,
|
||||
"whois": h.whois,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue