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

158 lines
3.0 KiB
Go
Raw Normal View History

2012-04-07 20:44:59 +02:00
package irc
import (
"log"
"net"
2012-04-18 07:21:41 +02:00
"time"
2012-04-07 20:44:59 +02:00
)
type Server struct {
2012-12-10 05:24:53 +01:00
hostname string
ctime time.Time
name string
recv chan<- *ClientMessage
nicks map[string]*Client
channels map[string]*Channel
password string
operators map[string]string
2012-04-07 20:44:59 +02:00
}
type ClientMessage struct {
client *Client
message Message
}
2012-04-18 07:11:35 +02:00
func NewServer(name string) *Server {
recv := make(chan *ClientMessage)
2012-12-09 21:51:50 +01:00
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 {
log.Printf("%s -> %T%+v", m.client.Id(), m.message, m.message)
2012-12-12 08:12:35 +01:00
m.client.atime = time.Now()
m.message.Handle(server, m.client)
}
}()
return server
2012-04-07 20:44:59 +02:00
}
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
}
s.hostname = LookupHostname(listener.Addr())
log.Print("Server.Listen: listening on ", addr)
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
}
log.Print("Server.Listen: accepted ", conn.RemoteAddr())
2012-12-09 21:51:50 +01:00
go NewClient(s, conn).Communicate()
}
}
func (s *Server) GetOrMakeChannel(name string) *Channel {
channel := s.channels[name]
if channel == nil {
channel = NewChannel(s, name)
s.channels[name] = channel
}
return channel
}
2012-12-10 05:24:53 +01:00
func (s *Server) AddOperator(name string, password string) {
s.operators[name] = password
}
// Send a message to clients of channels fromClient is a member.
func (s *Server) SendToInterestedClients(fromClient *Client, reply Reply) {
clients := make(map[*Client]bool)
2012-12-09 21:51:50 +01:00
clients[fromClient] = true
for channel := range fromClient.channels {
for client := range channel.members {
clients[client] = true
}
}
for client := range clients {
client.send <- reply
2012-04-07 20:44:59 +02:00
}
}
// server functionality
func (s *Server) ChangeNick(c *Client, newNick string) {
if s.nicks[newNick] != nil {
c.send <- ErrNickNameInUse(s, newNick)
return
2012-04-09 16:57:55 +02:00
}
if c.nick != "" {
delete(s.nicks, c.nick)
}
2012-12-12 08:34:41 +01:00
s.nicks[newNick] = c
2012-12-09 21:51:50 +01:00
s.SendToInterestedClients(c, RplNick(c, newNick))
c.nick = newNick
s.tryRegister(c)
}
2012-12-09 21:51:50 +01:00
func (s *Server) UserLogin(c *Client, user string, realName string) {
if c.username != "" {
c.send <- ErrAlreadyRegistered(s)
return
}
c.username, c.realname = user, realName
2012-12-09 21:51:50 +01:00
s.tryRegister(c)
}
2012-12-09 21:51:50 +01:00
func (s *Server) tryRegister(c *Client) {
if !c.registered && c.HasNick() && c.HasUser() && (s.password == "" || c.serverPass) {
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 {
2012-12-10 05:24:53 +01:00
switch mode {
case "+w":
c.wallOps = true
case "-w":
c.wallOps = false
}
}
c.send <- RplUModeIs(s, c)
}
func (s *Server) Id() string {
return s.hostname
2012-04-07 20:44:59 +02:00
}