Rewritten to use callbacks, bit easier to use.
This commit is contained in:
parent
455e0cd0dd
commit
7019ec3d0e
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
|||||||
include $(GOROOT)/src/Make.$(GOARCH)
|
include $(GOROOT)/src/Make.$(GOARCH)
|
||||||
|
|
||||||
TARG=irc
|
TARG=irc
|
||||||
GOFILES=irc.go irc_struct.go
|
GOFILES=irc.go irc_struct.go irc_callback.go
|
||||||
|
|
||||||
include $(GOROOT)/src/Make.pkg
|
include $(GOROOT)/src/Make.pkg
|
||||||
|
@ -6,9 +6,11 @@ Event based irc client library.
|
|||||||
|
|
||||||
Features
|
Features
|
||||||
---------
|
---------
|
||||||
* Event based
|
* Event based. Register Callbacks for the events you need to handle.
|
||||||
* Automatic Reconnect
|
* Handles basic irc demands for you:
|
||||||
* Handles basic irc demands for you (PING, VERSION)
|
** Standard CTCP
|
||||||
|
** Reconnections on errors
|
||||||
|
** Detect stoned servers
|
||||||
|
|
||||||
Install
|
Install
|
||||||
----------
|
----------
|
||||||
@ -20,3 +22,36 @@ Install
|
|||||||
Example
|
Example
|
||||||
----------
|
----------
|
||||||
See example/test.go
|
See example/test.go
|
||||||
|
|
||||||
|
Events for callbacks
|
||||||
|
---------
|
||||||
|
*001 Welcome
|
||||||
|
*PING
|
||||||
|
*CTCP Unknown CTCP
|
||||||
|
*CTCP_VERSION Version request (Handled internaly)
|
||||||
|
*CTCP_USERINFO
|
||||||
|
*CTCP_CLIENTINFO
|
||||||
|
*CTCP_TIME
|
||||||
|
*CTCP_PING
|
||||||
|
*PRIVMSG
|
||||||
|
*MODE
|
||||||
|
*JOIN
|
||||||
|
|
||||||
|
+Many more
|
||||||
|
|
||||||
|
|
||||||
|
AddCallback Example
|
||||||
|
---------
|
||||||
|
ircobj.AddCallback("PRIVMSG", func(event *irc.IRCEvent) {
|
||||||
|
//e.Message contains the message
|
||||||
|
//e.Nick Contains the sender
|
||||||
|
//e.Arguments[0] Contains the channel
|
||||||
|
});
|
||||||
|
|
||||||
|
Commands
|
||||||
|
--------
|
||||||
|
ircobj.Sendraw("<string>") //sends string to server. Adds \r\n
|
||||||
|
ircobj.Join("#channel [password]")
|
||||||
|
ircobj.Privmsg("#channel", "msg")
|
||||||
|
ircobj.Privmsg("nickname", "msg")
|
||||||
|
ircobj.Notice("nickname or #channel", "msg")
|
||||||
|
@ -1,44 +1,19 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"irc";
|
"irc"
|
||||||
"fmt";
|
"fmt"
|
||||||
"os";
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
events := make(chan *irc.IRCEvent, 100);
|
irccon := irc.IRC("testgo", "testgo")
|
||||||
irccon, err := irc.IRC("irc.efnet.net:6667", "testgo", "testgo", events);
|
err := irccon.Connect("irc.efnet.net:6667")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%s\n", err);
|
fmt.Printf("%s\n", err)
|
||||||
fmt.Printf("%#v\n", irccon);
|
fmt.Printf("%#v\n", irccon)
|
||||||
os.Exit(1);
|
os.Exit(1)
|
||||||
}
|
|
||||||
for {
|
|
||||||
event := <-events;
|
|
||||||
/* switch event.Code {
|
|
||||||
case UNKNOWN:
|
|
||||||
fmt.Printf("%#v\n", event)
|
|
||||||
case 0:
|
|
||||||
fmt.Printf("%#v\n", event)
|
|
||||||
case IRC_PRIVMSG:
|
|
||||||
fmt.Printf("%#v\n", event)
|
|
||||||
case IRC_CHAN_TOPIC:
|
|
||||||
fmt.Printf("%#v\n", event)
|
|
||||||
case IRC_CHAN_MODE:
|
|
||||||
fmt.Printf("%#v\n", event)
|
|
||||||
case IRC_ACTION:
|
|
||||||
fmt.Printf("%#v\n", event)
|
|
||||||
case IRC_WELCOME:
|
|
||||||
irc.Join("#ggpre")
|
|
||||||
}*/
|
|
||||||
if event.Code == irc.IRC_WELCOME {
|
|
||||||
irccon.Join("#gotestchan")
|
|
||||||
} else if event.Code == irc.IRC_PRIVMSG {
|
|
||||||
if event.Message == "!test" {
|
|
||||||
irccon.Privmsg(event.Target, "Whatever man!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("%#v\n", event);
|
|
||||||
}
|
}
|
||||||
|
irccon.AddCallback("001", func(e *irc.IRCEvent) { irccon.Join("#testgo") })
|
||||||
|
irccon.Loop();
|
||||||
}
|
}
|
||||||
|
310
irc.go
310
irc.go
@ -5,195 +5,80 @@
|
|||||||
package irc
|
package irc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt";
|
"fmt"
|
||||||
"net";
|
"net"
|
||||||
"os";
|
"os"
|
||||||
"bufio";
|
"bufio"
|
||||||
"regexp";
|
"strings"
|
||||||
"strings";
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VERSION = "GolangBOT v1.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func reader(irc *IRCConnection) {
|
func reader(irc *IRCConnection) {
|
||||||
br := bufio.NewReader(irc.socket);
|
br := bufio.NewReader(irc.socket)
|
||||||
for {
|
for {
|
||||||
msg, err := br.ReadString('\n');
|
msg, err := br.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%s\n", err);
|
irc.Error <- err
|
||||||
irc.perror <- err;
|
return
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
irc.pread <- msg;
|
irc.lastMessage = time.Seconds()
|
||||||
|
msg = msg[0 : len(msg)-2] //Remove \r\n
|
||||||
|
event := &IRCEvent{Raw: msg}
|
||||||
|
if msg[0] == ':' {
|
||||||
|
if i := strings.Index(msg, " "); i > -1 {
|
||||||
|
event.Source = msg[1:i]
|
||||||
|
msg = msg[i+1 : len(msg)]
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Misformed msg from server: %#s\n", msg)
|
||||||
|
}
|
||||||
|
if i, j := strings.Index(event.Source, "!"), strings.Index(event.Source, "@"); i > -1 && j > -1 {
|
||||||
|
event.Nick = event.Source[0:i]
|
||||||
|
event.User = event.Source[i+1 : j]
|
||||||
|
event.Host = event.Source[j+1 : len(event.Source)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args := strings.Split(msg, " :", 2)
|
||||||
|
if len(args) > 1 {
|
||||||
|
event.Message = args[1]
|
||||||
|
}
|
||||||
|
args = strings.Split(args[0], " ", 0)
|
||||||
|
event.Code = strings.ToUpper(args[0])
|
||||||
|
if len(args) > 1 {
|
||||||
|
event.Arguments = args[1:len(args)]
|
||||||
|
}
|
||||||
|
irc.RunCallbacks(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writer(irc *IRCConnection) {
|
func writer(irc *IRCConnection) {
|
||||||
for {
|
for {
|
||||||
b := strings.Bytes(<-irc.pwrite);
|
b := strings.Bytes(<-irc.pwrite)
|
||||||
_, err := irc.socket.Write(b);
|
_, err := irc.socket.Write(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%s\n", err);
|
fmt.Printf("%s\n", err)
|
||||||
irc.perror <- err;
|
irc.Error <- err
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func reconnector(i *IRCConnection) {
|
|
||||||
fmt.Printf("Reconnecting\n");
|
|
||||||
for {
|
|
||||||
i.Error = connect(i);
|
|
||||||
if i.Error == nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var rx_server_msg = regexp.MustCompile("^:([^ ]+) ([^ ]+) ([^ ]+) :(.*)\r\n")
|
//Pings the server if we have not recived any messages for 5 minutes
|
||||||
var rx_server_msg_c = regexp.MustCompile("^:([^ ]+) ([^ ]+) ([^ ]+) [@]* ([^ ]+) :(.*)\r\n")
|
func pinger(i *IRCConnection) {
|
||||||
var rx_server_msg_p = regexp.MustCompile("^:([^ ]+) ([^ ]+) ([^ ]+) (.*)\r\n")
|
i.ticker = time.Tick(1000 * 1000 * 1000 * 60 * 4) //Every 4 minutes
|
||||||
var rx_server_cmd = regexp.MustCompile("^([^:]+) :(.*)\r\n") //AUTH NOTICE, PING, ERROR
|
i.ticker2 = time.Tick(1000 * 1000 * 1000 * 60 * 15) //Every 15 minutes
|
||||||
var rx_user_action = regexp.MustCompile("^:([^!]+)!([^@]+)@([^ ]+) ([^ ]+) [:]*(.*)\r\n")
|
|
||||||
var rx_user_msg = regexp.MustCompile("^:([^!]+)!([^@]+)@([^ ]+) ([^ ]+) ([^ ]+) :(.*)\r\n")
|
|
||||||
|
|
||||||
func (irc *IRCConnection) handle_command(msg string) *IRCEvent {
|
|
||||||
e := new(IRCEvent);
|
|
||||||
e.RawMessage = msg;
|
|
||||||
if matches := rx_user_msg.MatchStrings(msg); len(matches) == 7 {
|
|
||||||
e.Sender = matches[1];
|
|
||||||
e.SenderUser = matches[2];
|
|
||||||
e.SenderHost = matches[3];
|
|
||||||
e.Message = matches[6];
|
|
||||||
e.Target = matches[5];
|
|
||||||
switch matches[4] {
|
|
||||||
case "PRIVMSG":
|
|
||||||
e.Code = IRC_PRIVMSG
|
|
||||||
case "ACTION":
|
|
||||||
e.Code = IRC_ACTION
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
} else if matches := rx_user_action.MatchStrings(msg); len(matches) == 6 {
|
|
||||||
e.Sender = matches[1];
|
|
||||||
e.SenderUser = matches[2];
|
|
||||||
e.SenderHost = matches[3];
|
|
||||||
e.Message = matches[5];
|
|
||||||
e.Target = matches[5];
|
|
||||||
e.Channel = matches[5];
|
|
||||||
switch matches[4] {
|
|
||||||
case "JOIN":
|
|
||||||
e.Code = IRC_JOIN
|
|
||||||
case "MODE":
|
|
||||||
e.Code = IRC_CHAN_MODE
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
} else if matches := rx_server_msg_c.MatchStrings(msg); len(matches) == 6 {
|
|
||||||
e.Sender = matches[1];
|
|
||||||
e.Target = matches[3];
|
|
||||||
e.Channel = matches[4];
|
|
||||||
e.Message = matches[5];
|
|
||||||
switch matches[2] {
|
|
||||||
case "366":
|
|
||||||
e.Code = IRC_CHAN_NICKLIST
|
|
||||||
case "332":
|
|
||||||
e.Code = IRC_CHAN_TOPIC
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
} else if matches := rx_server_msg.MatchStrings(msg); len(matches) == 5 {
|
|
||||||
e.Sender = matches[1];
|
|
||||||
e.Target = matches[3];
|
|
||||||
e.Message = matches[4];
|
|
||||||
switch matches[2] {
|
|
||||||
case "001":
|
|
||||||
e.Code = IRC_WELCOME
|
|
||||||
case "002":
|
|
||||||
e.Code = IRC_SERVER_INFO
|
|
||||||
case "003":
|
|
||||||
e.Code = IRC_SERVER_UPTIME
|
|
||||||
case "250":
|
|
||||||
e.Code = IRC_STAT_USERS
|
|
||||||
case "251":
|
|
||||||
e.Code = IRC_STAT_USERS
|
|
||||||
case "255":
|
|
||||||
e.Code = IRC_STAT_USERS
|
|
||||||
case "372":
|
|
||||||
e.Code = IRC_MOTD
|
|
||||||
case "375":
|
|
||||||
e.Code = IRC_START_MOTD
|
|
||||||
case "376":
|
|
||||||
e.Code = IRC_END_MOTD
|
|
||||||
case "MODE":
|
|
||||||
e.Code = IRC_MODE
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
} else if matches := rx_server_msg_p.MatchStrings(msg); len(matches) == 5 {
|
|
||||||
e.Sender = matches[1];
|
|
||||||
e.Target = matches[3];
|
|
||||||
e.Message = matches[4];
|
|
||||||
switch matches[2] {
|
|
||||||
case "252":
|
|
||||||
e.Code = IRC_STAT_OPERS
|
|
||||||
case "253":
|
|
||||||
e.Code = IRC_STAT_UNKN
|
|
||||||
case "254":
|
|
||||||
e.Code = IRC_STAT_CONNS
|
|
||||||
case "265":
|
|
||||||
e.Code = IRC_STAT_USERS
|
|
||||||
case "266":
|
|
||||||
e.Code = IRC_STAT_USERS
|
|
||||||
case "004":
|
|
||||||
e.Code = IRC_SERVER_VERSION
|
|
||||||
case "005":
|
|
||||||
e.Code = IRC_CHANINFO
|
|
||||||
case "332":
|
|
||||||
e.Code = IRC_CHAN_TIMESTAMP
|
|
||||||
case "353":
|
|
||||||
e.Code = IRC_CHAN_NICKLIST
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
} else if matches := rx_server_cmd.MatchStrings(msg); len(matches) == 3 {
|
|
||||||
switch matches[1] {
|
|
||||||
case "NOTICE AUTH":
|
|
||||||
e.Code = IRC_NOTICE_AUTH;
|
|
||||||
e.Message = matches[2];
|
|
||||||
case "PING":
|
|
||||||
e.Code = IRC_PING;
|
|
||||||
e.Message = matches[2];
|
|
||||||
// case "ERROR":
|
|
||||||
// e.Code = IRC_PING;
|
|
||||||
// e.Message = matches[2];
|
|
||||||
// e.Error = os.ErrorString(matches[2]);
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
e.Message = msg;
|
|
||||||
e.Code = UNKNOWN;
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
func handler(irc *IRCConnection) {
|
|
||||||
go reader(irc);
|
|
||||||
go writer(irc);
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case msg := <-irc.pread:
|
case <-i.ticker:
|
||||||
e := irc.handle_command(msg);
|
if time.Seconds()-i.lastMessage > 60*4 {
|
||||||
switch e.Code {
|
i.SendRaw(fmt.Sprintf("PING %d", time.Nanoseconds()))
|
||||||
case IRC_PING:
|
|
||||||
irc.pwrite <- fmt.Sprintf("PONG %s\r\n", e.Message)
|
|
||||||
case IRC_PRIVMSG:
|
|
||||||
if e.Message == "\x01VERSION\x01" {
|
|
||||||
irc.pwrite <- fmt.Sprintf("NOTICE %s :\x01VERSION GolangBOT (tj)\x01\r\n", e.Sender)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
case <-i.ticker2:
|
||||||
irc.EventChan <- e;
|
i.SendRaw(fmt.Sprintf("PING %d", time.Nanoseconds()))
|
||||||
case error := <-irc.perror:
|
|
||||||
fmt.Printf("Piped error: %s\n", error);
|
|
||||||
ee := new(IRCEvent);
|
|
||||||
ee.Error = error;
|
|
||||||
ee.Code = ERROR;
|
|
||||||
irc.EventChan <- ee;
|
|
||||||
reconnector(irc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,43 +95,64 @@ func (irc *IRCConnection) Privmsg(target, message string) {
|
|||||||
irc.pwrite <- fmt.Sprintf("PRIVMSG %s :%s\r\n", target, message)
|
irc.pwrite <- fmt.Sprintf("PRIVMSG %s :%s\r\n", target, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Try to reconnect
|
func (irc *IRCConnection) SendRaw(message string) {
|
||||||
func (irc *IRCConnection) Reconnect() os.Error {
|
fmt.Printf("--> %s\n", message)
|
||||||
irc.socket, irc.Error = net.Dial("tcp", "", irc.server);
|
irc.pwrite <- fmt.Sprintf("%s\r\n", message)
|
||||||
if irc.Error != nil {
|
|
||||||
return irc.Error
|
|
||||||
}
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect(i *IRCConnection) os.Error {
|
func (i *IRCConnection) Reconnect() os.Error {
|
||||||
fmt.Printf("Connecting to %s\n", i.server);
|
for {
|
||||||
i.socket, i.Error = net.Dial("tcp", "", i.server);
|
fmt.Printf("Reconnecting to %s\n", i.server)
|
||||||
if i.Error != nil {
|
var err os.Error
|
||||||
return i.Error
|
i.socket, err = net.Dial("tcp", "", i.server)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fmt.Printf("Error: %s\n", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Connected to %s (%s)\n", i.server, i.socket.RemoteAddr());
|
fmt.Printf("Connected to %s (%s)\n", i.server, i.socket.RemoteAddr())
|
||||||
i.pread = make(chan string, 100);
|
go reader(i)
|
||||||
i.pwrite = make(chan string, 100);
|
go writer(i)
|
||||||
i.perror = make(chan os.Error, 10);
|
i.pwrite <- fmt.Sprintf("NICK %s\r\n", i.nick)
|
||||||
go reader(i);
|
i.pwrite <- fmt.Sprintf("USER %s 0.0.0.0 0.0.0.0 :%s\r\n", i.user, i.user)
|
||||||
go writer(i);
|
return nil
|
||||||
i.pwrite <- fmt.Sprintf("NICK %s\r\n", i.nick);
|
|
||||||
i.pwrite <- fmt.Sprintf("USER %s 0.0.0.0 0.0.0.0 :GolangBOT\r\n", i.user);
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func IRC(server string, nick string, user string, events chan *IRCEvent) (*IRCConnection, os.Error) {
|
func (i *IRCConnection) Loop() {
|
||||||
irc := new(IRCConnection);
|
for {
|
||||||
irc.server = server;
|
<-i.Error
|
||||||
irc.registered = false;
|
i.Reconnect()
|
||||||
irc.pread = make(chan string, 100);
|
}
|
||||||
irc.pwrite = make(chan string, 100);
|
}
|
||||||
irc.perror = make(chan os.Error, 10);
|
|
||||||
irc.EventChan = events;
|
func (i *IRCConnection) Connect(server string) os.Error {
|
||||||
irc.nick = nick;
|
i.server = server
|
||||||
irc.user = user;
|
fmt.Printf("Connecting to %s\n", i.server)
|
||||||
connect(irc);
|
var err os.Error
|
||||||
go handler(irc);
|
i.socket, err = net.Dial("tcp", "", i.server)
|
||||||
return irc, nil;
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Connected to %s (%s)\n", i.server, i.socket.RemoteAddr())
|
||||||
|
i.pread = make(chan string, 100)
|
||||||
|
i.pwrite = make(chan string, 100)
|
||||||
|
i.Error = make(chan os.Error, 10)
|
||||||
|
go reader(i)
|
||||||
|
go writer(i)
|
||||||
|
go pinger(i)
|
||||||
|
i.pwrite <- fmt.Sprintf("NICK %s\r\n", i.nick)
|
||||||
|
i.pwrite <- fmt.Sprintf("USER %s 0.0.0.0 0.0.0.0 :%s\r\n", i.user, i.user)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IRC(nick string, user string) *IRCConnection {
|
||||||
|
irc := new(IRCConnection)
|
||||||
|
irc.registered = false
|
||||||
|
irc.pread = make(chan string, 100)
|
||||||
|
irc.pwrite = make(chan string, 100)
|
||||||
|
irc.Error = make(chan os.Error)
|
||||||
|
irc.nick = nick
|
||||||
|
irc.user = user
|
||||||
|
irc.setupCallbacks()
|
||||||
|
return irc
|
||||||
}
|
}
|
||||||
|
@ -5,65 +5,34 @@
|
|||||||
package irc
|
package irc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os";
|
"os"
|
||||||
"net";
|
"net"
|
||||||
)
|
|
||||||
|
|
||||||
type IRCEventCode int
|
|
||||||
|
|
||||||
const (
|
|
||||||
IRC_NOTICE_AUTH IRCEventCode = 1 << iota;
|
|
||||||
IRC_PING;
|
|
||||||
IRC_QUIT;
|
|
||||||
IRC_WELCOME;
|
|
||||||
IRC_SERVER_INFO;
|
|
||||||
IRC_SERVER_UPTIME;
|
|
||||||
IRC_SERVER_VERSION;
|
|
||||||
IRC_START_MOTD;
|
|
||||||
IRC_MOTD;
|
|
||||||
IRC_END_MOTD;
|
|
||||||
IRC_CHANINFO;
|
|
||||||
|
|
||||||
IRC_STAT_USERS;
|
|
||||||
IRC_STAT_OPERS;
|
|
||||||
IRC_STAT_UNKN;
|
|
||||||
IRC_STAT_CONNS;
|
|
||||||
|
|
||||||
IRC_CHAN_TIMESTAMP;
|
|
||||||
IRC_CHAN_NICKLIST;
|
|
||||||
IRC_CHAN_TOPIC;
|
|
||||||
IRC_CHAN_MODE;
|
|
||||||
|
|
||||||
IRC_PRIVMSG;
|
|
||||||
IRC_ACTION;
|
|
||||||
IRC_JOIN;
|
|
||||||
|
|
||||||
IRC_MODE;
|
|
||||||
|
|
||||||
ERROR;
|
|
||||||
UNKNOWN;
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IRCConnection struct {
|
type IRCConnection struct {
|
||||||
socket net.Conn;
|
socket net.Conn
|
||||||
pread, pwrite chan string;
|
pread, pwrite chan string
|
||||||
perror chan os.Error;
|
Error chan os.Error
|
||||||
EventChan chan *IRCEvent;
|
nick string
|
||||||
Error os.Error;
|
user string
|
||||||
nick string;
|
registered bool
|
||||||
user string;
|
server string
|
||||||
registered bool;
|
|
||||||
server string;
|
events map[string][]func(*IRCEvent)
|
||||||
|
|
||||||
|
lastMessage int64;
|
||||||
|
ticker <-chan int64;
|
||||||
|
ticker2 <-chan int64;
|
||||||
}
|
}
|
||||||
|
|
||||||
type IRCEvent struct {
|
type IRCEvent struct {
|
||||||
Message string;
|
Code string
|
||||||
RawMessage string;
|
Message string
|
||||||
Sender string;
|
Raw string
|
||||||
SenderHost string;
|
Nick string //<nick>
|
||||||
SenderUser string;
|
Host string //<nick>!<usr>@<host>
|
||||||
Target string;
|
Source string //<host>
|
||||||
Channel string;
|
User string //<usr>
|
||||||
Code IRCEventCode;
|
|
||||||
Error os.Error;
|
Arguments []string
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user