message.go (3623B)
1 // Copyright 2013 TLH and dsp. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package irc 6 7 import ( 8 "fmt" 9 "strings" 10 ) 11 12 type Message struct { 13 Command string 14 Raw string 15 Nick string 16 Host string 17 Source string 18 User string 19 Args []string 20 } 21 22 func (i *Context) Pong(host string) { 23 msg := Message{ 24 Command: "PONG", 25 Args: []string{":" + host}, 26 } 27 i.outgoingMsg <- msg 28 } 29 30 func (i *Context) Pass() { 31 msg := Message{ 32 Command: "PASS", 33 Args: []string{i.network.pass}, 34 } 35 i.outgoingMsg <- msg 36 } 37 38 func (i *Context) Nick() { 39 msg := Message{ 40 Command: "NICK", 41 Args: []string{i.network.nick}, 42 } 43 i.outgoingMsg <- msg 44 } 45 46 func (i *Context) User() { 47 msg := Message{ 48 Command: "USER", 49 Args: []string{ 50 i.network.user, 51 "* 8", 52 ":" + i.network.realName, 53 }, 54 } 55 i.outgoingMsg <- msg 56 } 57 58 func (i *Context) Join(channel string, key string) { 59 msg := Message{ 60 Command: "JOIN", 61 Args: []string{channel, key}, 62 } 63 i.outgoingMsg <- msg 64 } 65 66 func (i *Context) Part(channel string, text string) { 67 msg := Message{ 68 Command: "PART", 69 Args: []string{ 70 channel, 71 ":" + text, 72 }, 73 } 74 i.outgoingMsg <- msg 75 } 76 77 func (i *Context) Quit(text string) { 78 msg := Message{ 79 Command: "QUIT", 80 Args: []string{":" + text}, 81 } 82 i.outgoingMsg <- msg 83 } 84 85 func (i *Context) Privmsg(channel string, text string) { 86 msg := Message{ 87 Command: "PRIVMSG", 88 Args: []string{ 89 channel, 90 ":" + text, 91 }, 92 } 93 i.outgoingMsg <- msg 94 } 95 96 func (i *Context) Notice(nick string, text string) { 97 msg := Message{ 98 Command: "NOTICE", 99 Args: []string{ 100 nick, 101 ":" + text, 102 }, 103 } 104 i.outgoingMsg <- msg 105 } 106 107 func (i *Context) Topic(channel string, text string) { 108 msg := Message{ 109 Command: "TOPIC", 110 Args: []string{ 111 channel, 112 ":" + text, 113 }, 114 } 115 i.outgoingMsg <- msg 116 } 117 118 func (i *Context) ParseRawMessage(raw string) (*Message, error) { 119 var msg Message 120 msg.Raw = raw 121 raw = strings.TrimSpace(raw) 122 if raw[0] == ':' { 123 if i := strings.Index(raw, " "); i != -1 { 124 msg.Source = raw[1:i] 125 raw = raw[1:] 126 } else { 127 return nil, fmt.Errorf("Could not parse source, ignoring...") 128 } 129 if i := strings.Index(raw, "!"); i != -1 { 130 msg.Nick = raw[:i] 131 raw = raw[i+1:] 132 } else { 133 return nil, fmt.Errorf("Could not parse nick, ignoring...") 134 } 135 if i := strings.Index(raw, "@"); i != -1 { 136 msg.User = raw[:i] 137 raw = raw[i+1:] 138 } else { 139 return nil, fmt.Errorf("Could not parse user, ignoring...") 140 } 141 if i := strings.Index(raw, " "); i != -1 { 142 msg.Host = raw[:i] 143 raw = raw[i+1:] 144 } else { 145 return nil, fmt.Errorf("Could not parse host, ignoring...") 146 } 147 } 148 if i := strings.Index(raw, " "); i != -1 { 149 msg.Command = raw[:i] 150 raw = raw[i+1:] 151 } else { 152 return nil, fmt.Errorf("Could not parse command, ignoring...") 153 } 154 if raw[0] == ':' { 155 msg.Args = []string{raw[1:]} 156 } else { 157 msg.Args = strings.SplitN(raw, " :", 2) 158 } 159 return &msg, nil 160 } 161 162 // Unpack a message into a byte array 163 func (i *Context) UnpackMessage(msg Message) []byte { 164 rawMsg := msg.Command + " " + strings.Join(msg.Args, " ") 165 rawMsg = strings.TrimSpace(rawMsg) + "\r\n" 166 return []byte(rawMsg) 167 } 168 169 func (i *Context) incomingMsgLoop() error { 170 for { 171 select { 172 case msg, ok := <-i.incomingMsg: 173 if !ok { 174 return nil 175 } 176 i.dispatchHandler(msg) 177 } 178 } 179 return nil 180 } 181 182 func (i *Context) outgoingMsgLoop() error { 183 for { 184 select { 185 case msg, ok := <-i.outgoingMsg: 186 if !ok { 187 return nil 188 } 189 rawMsg := i.UnpackMessage(msg) 190 err := i.TxRawMessage(rawMsg) 191 if err != nil { 192 return err 193 } 194 } 195 } 196 return nil 197 }