選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

channel.go 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package irc
  2. import (
  3. "log"
  4. )
  5. type Channel struct {
  6. commands chan<- ChannelCommand
  7. key string
  8. members ClientSet
  9. name string
  10. noOutside bool
  11. password string
  12. replies chan<- Reply
  13. server *Server
  14. topic string
  15. }
  16. type ChannelSet map[*Channel]bool
  17. type ChannelCommand interface {
  18. Command
  19. HandleChannel(channel *Channel)
  20. }
  21. // NewChannel creates a new channel from a `Server` and a `name`
  22. // string, which must be unique on the server.
  23. func NewChannel(s *Server, name string) *Channel {
  24. commands := make(chan ChannelCommand)
  25. replies := make(chan Reply)
  26. channel := &Channel{
  27. name: name,
  28. members: make(ClientSet),
  29. server: s,
  30. commands: commands,
  31. replies: replies,
  32. }
  33. go channel.receiveCommands(commands)
  34. go channel.receiveReplies(replies)
  35. return channel
  36. }
  37. func (channel *Channel) receiveCommands(commands <-chan ChannelCommand) {
  38. for command := range commands {
  39. if DEBUG_CHANNEL {
  40. log.Printf("%s → %s : %s", command.Source(), channel, command)
  41. }
  42. command.HandleChannel(channel)
  43. }
  44. }
  45. func (channel *Channel) receiveReplies(replies <-chan Reply) {
  46. for reply := range replies {
  47. if DEBUG_CHANNEL {
  48. log.Printf("%s ← %s : %s", channel, reply.Source(), reply)
  49. }
  50. for client := range channel.members {
  51. client.replies <- reply
  52. }
  53. }
  54. }
  55. func (channel *Channel) IsEmpty() bool {
  56. return len(channel.members) == 0
  57. }
  58. func (channel *Channel) GetTopic(replier Replier) {
  59. if channel.topic == "" {
  60. replier.Replies() <- RplNoTopic(channel)
  61. return
  62. }
  63. replier.Replies() <- RplTopic(channel)
  64. }
  65. func (channel *Channel) GetUsers(replier Replier) {
  66. replier.Replies() <- NewNamesReply(channel)
  67. }
  68. func (channel *Channel) Nicks() []string {
  69. nicks := make([]string, len(channel.members))
  70. i := 0
  71. for client := range channel.members {
  72. nicks[i] = client.Nick()
  73. i += 1
  74. }
  75. return nicks
  76. }
  77. func (channel *Channel) Replies() chan<- Reply {
  78. return channel.replies
  79. }
  80. func (channel *Channel) Id() string {
  81. return channel.name
  82. }
  83. func (channel *Channel) Nick() string {
  84. return channel.name
  85. }
  86. func (channel *Channel) PublicId() string {
  87. return channel.name
  88. }
  89. func (channel *Channel) String() string {
  90. return channel.Id()
  91. }
  92. func (channel *Channel) Join(client *Client) {
  93. channel.members[client] = true
  94. client.channels[channel] = true
  95. reply := RplJoin(channel, client)
  96. channel.replies <- reply
  97. channel.GetTopic(client)
  98. channel.GetUsers(client)
  99. }
  100. func (channel *Channel) HasMember(client *Client) bool {
  101. return channel.members[client]
  102. }
  103. //
  104. // commands
  105. //
  106. func (m *JoinCommand) HandleChannel(channel *Channel) {
  107. client := m.Client()
  108. if channel.key != m.channels[channel.name] {
  109. client.replies <- ErrBadChannelKey(channel)
  110. return
  111. }
  112. channel.Join(client)
  113. }
  114. func (m *PartCommand) HandleChannel(channel *Channel) {
  115. c := m.Client()
  116. if !channel.HasMember(c) {
  117. c.replies <- ErrNotOnChannel(channel)
  118. return
  119. }
  120. msg := m.message
  121. if msg == "" {
  122. msg = c.Nick()
  123. }
  124. channel.replies <- RplPart(channel, c, msg)
  125. delete(channel.members, c)
  126. delete(c.channels, channel)
  127. if channel.IsEmpty() { // TODO persistent channels
  128. channel.server.DeleteChannel(channel)
  129. }
  130. }
  131. func (m *TopicCommand) HandleChannel(channel *Channel) {
  132. client := m.Client()
  133. if !channel.HasMember(client) {
  134. client.replies <- ErrNotOnChannel(channel)
  135. return
  136. }
  137. if m.topic == "" {
  138. channel.GetTopic(client)
  139. return
  140. }
  141. channel.topic = m.topic
  142. channel.GetTopic(channel)
  143. }
  144. func (m *PrivMsgCommand) HandleChannel(channel *Channel) {
  145. channel.replies <- RplPrivMsgChannel(channel, m.Client(), m.message)
  146. }