diff --git a/irc/constants.go b/irc/constants.go index a86cf0ee..2a766927 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -23,7 +23,7 @@ var ( ) const ( - SEM_VER = "ergonomadic-1.2.14" + SEM_VER = "ergonomadic-1.2.15" CRLF = "\r\n" MAX_REPLY_LEN = 512 - len(CRLF) diff --git a/irc/reply.go b/irc/reply.go index 2f85588e..4510f76e 100644 --- a/irc/reply.go +++ b/irc/reply.go @@ -142,6 +142,10 @@ func RplKill(client *Client, target *Client, comment string) string { "%s :%s", target.Nick(), comment) } +func RplCap(client *Client, subCommand CapSubCommand, arg interface{}) string { + return NewStringReply(nil, CAP, "%s %s :%s", client.Nick(), subCommand, arg) +} + // numeric replies func (target *Client) RplWelcome() { diff --git a/irc/server.go b/irc/server.go index 8fdefe1b..ff083897 100644 --- a/irc/server.go +++ b/irc/server.go @@ -270,36 +270,28 @@ func (msg *CapCommand) HandleRegServer(server *Server) { switch msg.subCommand { case CAP_LS: client.capState = CapNegotiating - client.Reply("CAP LS * :%s", SupportedCapabilities) + client.Reply(RplCap(client, CAP_LS, SupportedCapabilities)) case CAP_LIST: - client.Reply("CAP LIST * :%s", client.capabilities) + client.Reply(RplCap(client, CAP_LIST, client.capabilities)) case CAP_REQ: client.capState = CapNegotiating for capability := range msg.capabilities { if !SupportedCapabilities[capability] { - client.Reply("CAP NAK * :%s", msg.capabilities) + client.Reply(RplCap(client, CAP_NAK, msg.capabilities)) return } } for capability := range msg.capabilities { client.capabilities[capability] = true } - client.Reply("CAP ACK * :%s", msg.capabilities) + client.Reply(RplCap(client, CAP_ACK, msg.capabilities)) case CAP_CLEAR: - format := strings.TrimRight( - strings.Repeat("%s%s ", len(client.capabilities)), " ") - args := make([]interface{}, len(client.capabilities)) - index := 0 - for capability := range client.capabilities { - args[index] = Disable - args[index+1] = capability - index += 2 - delete(client.capabilities, capability) - } - client.Reply("CAP ACK * :"+format, args...) + reply := RplCap(client, CAP_ACK, client.capabilities.DisableString()) + client.capabilities = make(CapabilitySet) + client.Reply(reply) case CAP_END: client.capState = CapNegotiated diff --git a/irc/types.go b/irc/types.go index fc628bdd..198f7b65 100644 --- a/irc/types.go +++ b/irc/types.go @@ -14,6 +14,10 @@ type CapSubCommand string type Capability string +func (capability Capability) String() string { + return string(capability) +} + type CapModifier rune func (mod CapModifier) String() string { @@ -34,6 +38,16 @@ func (set CapabilitySet) String() string { return strings.Join(strs, " ") } +func (set CapabilitySet) DisableString() string { + parts := make([]string, len(set)) + index := 0 + for capability := range set { + parts[index] = Disable.String() + capability.String() + index += 1 + } + return strings.Join(parts, " ") +} + // a string with wildcards type Mask string