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.

modes.go 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package irc
  2. import (
  3. "strings"
  4. )
  5. // user mode flags
  6. type UserMode rune
  7. func (mode UserMode) String() string {
  8. return string(mode)
  9. }
  10. type UserModes []UserMode
  11. func (modes UserModes) String() string {
  12. strs := make([]string, len(modes))
  13. for index, mode := range modes {
  14. strs[index] = mode.String()
  15. }
  16. return strings.Join(strs, "")
  17. }
  18. // channel mode flags
  19. type ChannelMode rune
  20. func (mode ChannelMode) String() string {
  21. return string(mode)
  22. }
  23. type ChannelModes []ChannelMode
  24. func (modes ChannelModes) String() string {
  25. strs := make([]string, len(modes))
  26. for index, mode := range modes {
  27. strs[index] = mode.String()
  28. }
  29. return strings.Join(strs, "")
  30. }
  31. type ModeOp rune
  32. func (op ModeOp) String() string {
  33. return string(op)
  34. }
  35. const (
  36. Add ModeOp = '+'
  37. List ModeOp = '='
  38. Remove ModeOp = '-'
  39. )
  40. const (
  41. Away UserMode = 'a'
  42. Invisible UserMode = 'i'
  43. LocalOperator UserMode = 'O'
  44. Operator UserMode = 'o'
  45. Restricted UserMode = 'r'
  46. ServerNotice UserMode = 's' // deprecated
  47. WallOps UserMode = 'w'
  48. )
  49. var (
  50. SupportedUserModes = UserModes{
  51. Away, Invisible, Operator,
  52. }
  53. )
  54. const (
  55. Anonymous ChannelMode = 'a' // flag
  56. BanMask ChannelMode = 'b' // arg
  57. ChannelCreator ChannelMode = 'O' // flag
  58. ChannelOperator ChannelMode = 'o' // arg
  59. ExceptMask ChannelMode = 'e' // arg
  60. InviteMask ChannelMode = 'I' // arg
  61. InviteOnly ChannelMode = 'i' // flag
  62. Key ChannelMode = 'k' // flag arg
  63. Moderated ChannelMode = 'm' // flag
  64. NoOutside ChannelMode = 'n' // flag
  65. OpOnlyTopic ChannelMode = 't' // flag
  66. Persistent ChannelMode = 'P' // flag
  67. Private ChannelMode = 'p' // flag
  68. Quiet ChannelMode = 'q' // flag
  69. ReOp ChannelMode = 'r' // flag
  70. Secret ChannelMode = 's' // flag, deprecated
  71. Theater ChannelMode = 'T' // flag, nonstandard
  72. UserLimit ChannelMode = 'l' // flag arg
  73. Voice ChannelMode = 'v' // arg
  74. )
  75. var (
  76. SupportedChannelModes = ChannelModes{
  77. BanMask, ExceptMask, InviteMask, InviteOnly, Key, NoOutside,
  78. OpOnlyTopic, Persistent, Private, Theater, UserLimit,
  79. }
  80. )
  81. //
  82. // commands
  83. //
  84. func (m *ModeCommand) HandleServer(s *Server) {
  85. client := m.Client()
  86. target := s.clients.Get(m.nickname)
  87. if target == nil {
  88. client.ErrNoSuchNick(m.nickname)
  89. return
  90. }
  91. if client != target && !client.flags[Operator] {
  92. client.ErrUsersDontMatch()
  93. return
  94. }
  95. changes := make(ModeChanges, 0, len(m.changes))
  96. for _, change := range m.changes {
  97. switch change.mode {
  98. case Invisible, ServerNotice, WallOps:
  99. switch change.op {
  100. case Add:
  101. if target.flags[change.mode] {
  102. continue
  103. }
  104. target.flags[change.mode] = true
  105. changes = append(changes, change)
  106. case Remove:
  107. if !target.flags[change.mode] {
  108. continue
  109. }
  110. delete(target.flags, change.mode)
  111. changes = append(changes, change)
  112. }
  113. case Operator, LocalOperator:
  114. if change.op == Remove {
  115. if !target.flags[change.mode] {
  116. continue
  117. }
  118. delete(target.flags, change.mode)
  119. changes = append(changes, change)
  120. }
  121. }
  122. }
  123. if len(changes) > 0 {
  124. client.Reply(RplModeChanges(client, target, changes))
  125. } else if client == target {
  126. client.RplUModeIs(client)
  127. }
  128. client.Reply(RplCurrentMode(client, target))
  129. }
  130. func (msg *ChannelModeCommand) HandleServer(server *Server) {
  131. client := msg.Client()
  132. channel := server.channels.Get(msg.channel)
  133. if channel == nil {
  134. client.ErrNoSuchChannel(msg.channel)
  135. return
  136. }
  137. channel.Mode(client, msg.changes)
  138. }