1
0
Fork 0
forked from External/ergo

massive refactor and basic channel support: join, part, message

This commit is contained in:
Jeremy Latt 2012-12-08 22:54:58 -08:00
parent 8ac1909c19
commit 24ad2172a8
10 changed files with 657 additions and 191 deletions

View file

@ -7,24 +7,27 @@ import (
)
type Server struct {
ctime time.Time
name string
ch chan *ClientMessage
nicks map[string]*Client
hostname string
ctime time.Time
name string
recv chan<- *ClientMessage
nicks map[string]*Client
channels map[string]*Channel
}
type ClientMessage struct {
client *Client
client *Client
message Message
}
func NewServer(name string) *Server {
server := new(Server)
server.ctime = time.Now()
server.name = name
server.ch = make(chan *ClientMessage)
server.nicks = make(map[string]*Client)
go server.Receive()
recv := make(chan *ClientMessage)
server := &Server{ctime: time.Now(), name: name, recv: recv, nicks: make(map[string]*Client), channels: make(map[string]*Channel)}
go func() {
for m := range recv {
m.message.Handle(server, m.client)
}
}()
return server
}
@ -34,18 +37,104 @@ func (s *Server) Listen(addr string) {
log.Fatal("Server.Listen: ", err)
}
s.hostname = LookupHostname(listener.Addr())
log.Print("Server.Listen: listening on ", addr)
for {
conn, err := listener.Accept()
if err != nil {
log.Print("Server.Listen: ", err)
continue
}
go NewClient(conn).Communicate(s.ch)
log.Print("Server.Listen: accepted ", conn.RemoteAddr())
go NewClient(conn).Communicate(s)
}
}
func (s *Server) Receive() {
for m := range s.ch {
m.message.Handle(s, m.client)
func (s *Server) GetOrMakeChannel(name string) *Channel {
channel := s.channels[name]
if channel == nil {
channel = NewChannel(s, name)
s.channels[name] = channel
}
return channel
}
// Send a message to clients of channels fromClient is a member.
func (s *Server) SendToInterestedClients(fromClient *Client, reply Reply) {
clients := make(map[*Client]bool)
for channel := range fromClient.channels {
for client := range channel.members {
clients[client] = true
}
}
for client := range clients {
client.send <- reply
}
}
// server functionality
func (s *Server) ChangeNick(c *Client, newNick string) {
if s.nicks[newNick] != nil {
c.send <- ErrNickNameInUse(s, newNick)
return
}
s.SendToInterestedClients(c, RplNick(c, newNick))
if c.nick != "" {
delete(s.nicks, c.nick)
}
c.nick = newNick
s.nicks[c.nick] = c
s.TryRegister(c)
}
func (s *Server) Register(c *Client, user string, realName string) {
if c.username != "" {
c.send <- ErrAlreadyRegistered(s)
return
}
c.username, c.realname = user, realName
s.TryRegister(c)
}
func (s *Server) TryRegister(c *Client) {
if !c.registered && c.HasNick() && c.HasUser() {
c.registered = true
c.send <- RplWelcome(s, c)
c.send <- RplYourHost(s, c)
c.send <- RplCreated(s)
c.send <- RplMyInfo(s)
}
}
func (s *Server) Quit(c *Client, message string) {
for channel := range c.channels {
channel.Part(c, message)
}
delete(s.nicks, c.nick)
c.conn.Close()
}
func (s *Server) ChangeUserMode(c *Client, modes []string) {
for _, mode := range modes {
if mode == "+i" {
c.invisible = true
} else if mode == "-i" {
c.invisible = false
}
}
c.send <- RplUModeIs(s, c)
}
func (s *Server) Id() string {
return s.hostname
}