3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-10 22:19:31 +01:00
ergo/src/irc/server.go

101 lines
2.1 KiB
Go
Raw Normal View History

2012-04-07 20:44:59 +02:00
package irc
import (
"log"
"net"
2012-04-09 16:57:55 +02:00
"regexp"
2012-04-08 08:32:08 +02:00
"strings"
2012-04-07 20:44:59 +02:00
)
type Server struct {
ch chan Message
2012-04-08 08:32:08 +02:00
nicks map[string]*Client
2012-04-07 20:44:59 +02:00
}
func NewServer() *Server {
2012-04-09 16:57:55 +02:00
server := Server{make(chan Message), make(map[string]*Client)}
2012-04-07 20:44:59 +02:00
go server.Receive()
return &server
}
func (s *Server) Listen(addr string) {
listener, err := net.Listen("tcp", addr)
if err != nil {
2012-04-08 08:32:08 +02:00
log.Fatal("Server.Listen: ", err)
2012-04-07 20:44:59 +02:00
}
for {
conn, err := listener.Accept()
if err != nil {
2012-04-08 08:32:08 +02:00
log.Print("Server.Listen: ", err)
2012-04-07 20:44:59 +02:00
continue
}
2012-04-08 08:32:08 +02:00
go NewClient(conn).Communicate(s)
2012-04-07 20:44:59 +02:00
}
}
func (s *Server) Receive() {
for message := range s.ch {
2012-04-08 08:32:08 +02:00
log.Printf("C -> S: %s %s", message.command, message.args)
switch message.command {
case "PING":
2012-04-09 16:57:55 +02:00
message.client.Send(MessagePong())
2012-04-08 08:32:08 +02:00
case "USER":
s.UserCommand(message.client, message.args)
case "NICK":
s.NickCommand(message.client, message.args)
2012-04-09 16:57:55 +02:00
case "QUIT":
s.QuitCommand(message.client, message.args)
2012-04-08 08:32:08 +02:00
default:
2012-04-09 16:57:55 +02:00
message.client.Send(ErrUnknownCommand(message.client.Nick(), message.command))
2012-04-08 08:32:08 +02:00
}
2012-04-07 20:44:59 +02:00
}
}
2012-04-08 08:32:08 +02:00
func (s *Server) Send(m Message) {
s.ch <- m
}
// commands
func (s *Server) UserCommand(c *Client, args string) {
parts := strings.SplitN(args, " ", 4)
username, _, _, realname := parts[0], parts[1], parts[2], parts[3]
2012-04-09 16:57:55 +02:00
if c.username != "" {
2012-04-08 08:32:08 +02:00
c.Send(ErrAlreadyRegistered(c.nick))
return
}
c.username, c.realname = username, realname
2012-04-09 16:57:55 +02:00
s.TryRegister(c)
2012-04-08 08:32:08 +02:00
}
func (s *Server) NickCommand(c *Client, nick string) {
if s.nicks[nick] != nil {
c.Send(ErrNickNameInUse(nick))
return
}
c.nick = nick
s.nicks[nick] = c
2012-04-09 16:57:55 +02:00
s.TryRegister(c)
}
func (s *Server) TryRegister(c *Client) {
if (!c.registered && c.nick != "" && c.username != "") {
c.registered = true
c.Send(
ReplyWelcome(c.Nick(), c.username, "localhost"),
ReplyYourHost(c.Nick(), "irc.jlatt.com"),
ReplyCreated(c.Nick(), "2012/04/07"),
ReplyMyInfo(c.Nick(), "irc.jlatt.com"))
}
}
func (s *Server) QuitCommand(c *Client, args string) {
re := regexp.MustCompile("^" + RE_QUIT + "$")
matches := re.FindAllStringSubmatch(args, -1)
if matches != nil {
c.Send(MessageError())
}
delete(s.nicks, c.nick)
2012-04-07 20:44:59 +02:00
}