Created
July 9, 2014 23:40
-
-
Save Xe/34d6f5aa72b47133f032 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tetra | |
import ( | |
"bufio" | |
"errors" | |
"github.com/Xe/Tetra/1459" | |
"github.com/Xe/Tetra/modes" | |
"log" | |
"net" | |
"net/textproto" | |
"os" | |
"strconv" | |
) | |
type Clients struct { | |
ByNick map[string]*Client | |
ByUID map[string]*Client | |
Tetra *Tetra | |
} | |
func (clients *Clients) AddClient(client *Client) { | |
clients.ByNick[client.Nick] = client | |
clients.ByUID[client.Uid] = client | |
} | |
func (clients *Clients) DelClient(client *Client) (err error) { | |
delete(clients.ByNick, client.Nick) | |
delete(clients.ByUID, client.Uid) | |
return | |
} | |
type Tetra struct { | |
Conn *Connection | |
Info *Server | |
Clients *Clients | |
Channels map[string]*Channel | |
Bursted bool | |
Handlers map[string]map[string]*Handler | |
Services map[string]*Client | |
Servers map[string]*Server | |
nextuid int | |
//Config *Config | |
} | |
func NewTetra() (tetra *Tetra) { | |
tetra = &Tetra{ | |
Conn: &Connection{ | |
Log: log.New(os.Stdout, "", log.LstdFlags), | |
}, | |
Info: &Server{ | |
Name: "tetra.int", | |
Sid: "420", | |
Gecos: "Tetra in Go!", | |
}, | |
Clients: &Clients{ | |
ByNick: make(map[string]*Client), | |
ByUID: make(map[string]*Client), | |
Tetra: tetra, | |
}, | |
Channels: make(map[string]*Channel), | |
Handlers: make(map[string]map[string]*Handler), | |
Services: make(map[string]*Client), | |
Servers: make(map[string]*Server), | |
Bursted: false, | |
nextuid: 100000, | |
} | |
tetra.AddHandler("EUID", func(line *r1459.RawLine) { | |
// :47G EUID xena 1 1404369238 +ailoswxz xena staff.yolo-swag.com 0::1 47GAAAABK 0::1 * :Xena | |
nick := line.Args[0] | |
umodes := line.Args[3] | |
user := line.Args[4] | |
host := line.Args[5] | |
ip := line.Args[8] | |
uid := line.Args[7] | |
// TODO: make this its own function somewhere? | |
modeflags := 0 | |
for _, char := range umodes { | |
if _, ok := modes.UMODES[string(char)]; ok { | |
modeflags = modeflags | modes.UMODES[string(char)] | |
} | |
} | |
client := &Client{ | |
Nick: nick, | |
User: user, | |
VHost: host, | |
Host: line.Args[6], | |
Uid: uid, | |
Ip: ip, | |
Account: line.Args[9], | |
Gecos: line.Args[10], | |
tetra: tetra, | |
Umodes: modeflags, | |
} | |
tetra.Clients.AddClient(client) | |
}) | |
tetra.AddHandler("SJOIN", func(line *r1459.RawLine) { | |
// :47G SJOIN 1404424869 #test +nt :@47GAAAABL | |
ts := line.Args[0] | |
name := line.Args[1] | |
cmodes := line.Args[2] | |
users := line.Args[3] | |
var channel *Channel | |
if mychannel, ok := tetra.Channels[name]; ok { | |
channel = mychannel | |
} else { | |
// The ircd should never give an invalid TS. | |
numberts, _ := strconv.ParseInt(ts, 10, 64) | |
// TODO: make this its own function somewhere? | |
modeflags := 0 | |
for _, char := range cmodes { | |
if _, ok := modes.CHANMODES[1][string(char)]; ok { | |
modeflags = modeflags | modes.CHANMODES[1][string(char)] | |
} | |
} | |
channel = &Channel{ | |
Name: name, | |
Modes: modeflags, | |
Clients: make(map[string]*ChanUser), | |
Lists: make(map[int][]string), | |
//Ts: ts // TODO: convert string to int64 | |
Ts: numberts, | |
} | |
tetra.Channels[name] = channel | |
} | |
}) | |
tetra.AddService("tetra", "Tetra", "user", "yolo-swag.com", "Tetra in Go!") | |
return | |
} | |
func (tetra *Tetra) NextUID() string { | |
tetra.nextuid++ | |
return tetra.Info.Sid + strconv.Itoa(tetra.nextuid) | |
} | |
func (tetra *Tetra) Connect(host, port string) (err error) { | |
tetra.Conn.Conn, err = net.Dial("tcp", host+":"+port) | |
if err != nil { | |
panic(err) | |
} | |
tetra.Conn.Reader = bufio.NewReader(tetra.Conn.Conn) | |
tetra.Conn.Tp = textproto.NewReader(tetra.Conn.Reader) | |
return | |
} | |
func (tetra *Tetra) AddService(service, nick, user, host, gecos string) (cli *Client) { | |
cli = &Client{ | |
Nick: nick, | |
User: user, | |
Host: host, | |
VHost: host, | |
Gecos: gecos, | |
Account: "*", | |
Ip: "0", | |
Ts: 0, | |
Uid: tetra.NextUID(), | |
} | |
tetra.Services[service] = cli | |
tetra.Clients.AddClient(cli) | |
return | |
} | |
func (tetra *Tetra) DelService(service string) (err error) { | |
if _, ok := tetra.Services[service]; !ok { | |
panic(errors.New("No such service " + service)) | |
} | |
client := tetra.Services[service] | |
tetra.Clients.DelClient(client) | |
return | |
} | |
func (tetra *Tetra) GetConn() *net.Conn { | |
return &tetra.Conn.Conn | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment