You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.go 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package irc
  2. import (
  3. "log"
  4. "net"
  5. "time"
  6. )
  7. type ChannelNameMap map[string]*Channel
  8. type ClientNameMap map[string]*Client
  9. type Server struct {
  10. channels ChannelNameMap
  11. commands chan<- Command
  12. ctime time.Time
  13. hostname string
  14. name string
  15. password string
  16. clients ClientNameMap
  17. }
  18. func NewServer(name string) *Server {
  19. commands := make(chan Command)
  20. server := &Server{
  21. ctime: time.Now(),
  22. name: name,
  23. commands: commands,
  24. clients: make(ClientNameMap),
  25. channels: make(ChannelNameMap),
  26. }
  27. go server.receiveCommands(commands)
  28. return server
  29. }
  30. func (server *Server) receiveCommands(commands <-chan Command) {
  31. for command := range commands {
  32. if DEBUG_SERVER {
  33. log.Printf("%s → %s : %s", command.Client(), server, command)
  34. }
  35. command.Client().atime = time.Now()
  36. command.HandleServer(server)
  37. }
  38. }
  39. func (s *Server) Listen(addr string) {
  40. listener, err := net.Listen("tcp", addr)
  41. if err != nil {
  42. log.Fatal("Server.Listen: ", err)
  43. }
  44. s.hostname = LookupHostname(listener.Addr())
  45. if DEBUG_SERVER {
  46. log.Print("Server.Listen: listening on ", addr)
  47. }
  48. for {
  49. conn, err := listener.Accept()
  50. if err != nil {
  51. log.Print("Server.Listen: ", err)
  52. continue
  53. }
  54. if DEBUG_SERVER {
  55. log.Print("Server.Listen: accepted ", conn.RemoteAddr())
  56. }
  57. NewClient(s, conn)
  58. }
  59. }
  60. func (s *Server) GetOrMakeChannel(name string) *Channel {
  61. channel := s.channels[name]
  62. if channel == nil {
  63. channel = NewChannel(s, name)
  64. s.channels[name] = channel
  65. }
  66. return channel
  67. }
  68. // Send a message to clients of channels fromClient is a member.
  69. func (s *Server) interestedClients(fromClient *Client) ClientSet {
  70. clients := make(ClientSet)
  71. clients[fromClient] = true
  72. for channel := range fromClient.channels {
  73. for client := range channel.members {
  74. clients[client] = true
  75. }
  76. }
  77. return clients
  78. }
  79. // server functionality
  80. func (s *Server) tryRegister(c *Client) {
  81. if !c.registered && c.HasNick() && c.HasUsername() && c.serverPass {
  82. c.registered = true
  83. replies := []Reply{
  84. RplWelcome(s, c),
  85. RplYourHost(s),
  86. RplCreated(s),
  87. RplMyInfo(s),
  88. }
  89. for _, reply := range replies {
  90. c.Replies() <- reply
  91. }
  92. }
  93. }
  94. func (s *Server) Id() string {
  95. return s.name
  96. }
  97. func (s *Server) String() string {
  98. return s.Id()
  99. }
  100. func (s *Server) PublicId() string {
  101. return s.Id()
  102. }
  103. func (s *Server) Nick() string {
  104. return s.name
  105. }
  106. func (s *Server) DeleteChannel(channel *Channel) {
  107. delete(s.channels, channel.name)
  108. }
  109. //
  110. // commands
  111. //
  112. func (m *UnknownCommand) HandleServer(s *Server) {
  113. m.Client().Replies() <- ErrUnknownCommand(s, m.command)
  114. }
  115. func (m *PingCommand) HandleServer(s *Server) {
  116. m.Client().Replies() <- RplPong(s)
  117. }
  118. func (m *PongCommand) HandleServer(s *Server) {
  119. // no-op
  120. }
  121. func (m *PassCommand) HandleServer(s *Server) {
  122. if s.password != m.password {
  123. m.Client().Replies() <- ErrPasswdMismatch(s)
  124. // TODO disconnect
  125. return
  126. }
  127. m.Client().serverPass = true
  128. // no reply?
  129. }
  130. func (m *NickCommand) HandleServer(s *Server) {
  131. c := m.Client()
  132. if s.clients[m.nickname] != nil {
  133. c.replies <- ErrNickNameInUse(s, m.nickname)
  134. return
  135. }
  136. reply := RplNick(c, m.nickname)
  137. for iclient := range s.interestedClients(c) {
  138. iclient.replies <- reply
  139. }
  140. if c.HasNick() {
  141. delete(s.clients, c.nick)
  142. }
  143. s.clients[m.nickname] = c
  144. c.nick = m.nickname
  145. s.tryRegister(c)
  146. }
  147. func (m *UserMsgCommand) HandleServer(s *Server) {
  148. c := m.Client()
  149. if c.registered {
  150. c.replies <- ErrAlreadyRegistered(s)
  151. return
  152. }
  153. c.username, c.realname = m.user, m.realname
  154. s.tryRegister(c)
  155. }
  156. func (m *QuitCommand) HandleServer(s *Server) {
  157. c := m.Client()
  158. reply := RplQuit(c, m.message)
  159. for client := range s.interestedClients(c) {
  160. client.replies <- reply
  161. }
  162. cmd := &PartCommand{
  163. BaseCommand: BaseCommand{c},
  164. }
  165. for channel := range c.channels {
  166. channel.commands <- cmd
  167. }
  168. c.conn.Close()
  169. delete(s.clients, c.nick)
  170. }
  171. func (m *JoinCommand) HandleServer(s *Server) {
  172. c := m.Client()
  173. if m.zero {
  174. cmd := &PartCommand{
  175. BaseCommand: BaseCommand{c},
  176. }
  177. for channel := range c.channels {
  178. channel.commands <- cmd
  179. }
  180. return
  181. }
  182. for name := range m.channels {
  183. s.GetOrMakeChannel(name).commands <- m
  184. }
  185. }
  186. func (m *PartCommand) HandleServer(s *Server) {
  187. for _, chname := range m.channels {
  188. channel := s.channels[chname]
  189. if channel == nil {
  190. m.Client().replies <- ErrNoSuchChannel(s, channel.name)
  191. continue
  192. }
  193. channel.commands <- m
  194. }
  195. }
  196. func (m *TopicCommand) HandleServer(s *Server) {
  197. channel := s.channels[m.channel]
  198. if channel == nil {
  199. m.Client().replies <- ErrNoSuchChannel(s, m.channel)
  200. return
  201. }
  202. channel.commands <- m
  203. }
  204. func (m *PrivMsgCommand) HandleServer(s *Server) {
  205. if m.TargetIsChannel() {
  206. channel := s.channels[m.target]
  207. if channel == nil {
  208. m.Client().replies <- ErrNoSuchChannel(s, m.target)
  209. return
  210. }
  211. channel.commands <- m
  212. return
  213. }
  214. target := s.clients[m.target]
  215. if target == nil {
  216. m.Client().replies <- ErrNoSuchNick(s, m.target)
  217. return
  218. }
  219. target.replies <- RplPrivMsg(m.Client(), target, m.message)
  220. }
  221. func (m *ModeCommand) HandleServer(s *Server) {
  222. m.Client().replies <- RplUModeIs(s, m.Client())
  223. }