Mirror of github.com/gissleh/irc
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.

151 lines
3.2 KiB

6 years ago
6 years ago
  1. package irc
  2. import (
  3. "strings"
  4. "github.com/gissleh/irc/list"
  5. )
  6. // A Channel is a target that manages the userlist
  7. type Channel struct {
  8. name string
  9. userlist *list.List
  10. parted bool
  11. }
  12. // Kind returns "channel"
  13. func (channel *Channel) Kind() string {
  14. return "channel"
  15. }
  16. // Name gets the channel name
  17. func (channel *Channel) Name() string {
  18. return channel.name
  19. }
  20. func (channel *Channel) State() TargetState {
  21. return TargetState{
  22. Kind: "channel",
  23. Name: channel.name,
  24. Users: channel.userlist.Users(),
  25. }
  26. }
  27. // UserList gets the channel userlist
  28. func (channel *Channel) UserList() list.Immutable {
  29. return channel.userlist.Immutable()
  30. }
  31. // Parted returnes whether the channel has been parted
  32. func (channel *Channel) Parted() bool {
  33. return channel.parted
  34. }
  35. // AddHandler handles messages routed to this channel by the client's event loop
  36. func (channel *Channel) Handle(event *Event, client *Client) {
  37. switch event.Name() {
  38. case "packet.join":
  39. {
  40. // Support extended-join
  41. account := ""
  42. if accountArg := event.Arg(1); accountArg != "" && accountArg != "*" {
  43. account = accountArg
  44. }
  45. channel.userlist.Insert(list.User{
  46. Nick: event.Nick,
  47. User: event.User,
  48. Host: event.Host,
  49. Account: account,
  50. })
  51. }
  52. case "packet.part", "packet.quit":
  53. {
  54. channel.userlist.Remove(event.Nick)
  55. }
  56. case "packet.kick":
  57. {
  58. channel.userlist.Remove(event.Arg(1))
  59. }
  60. case "packet.nick":
  61. {
  62. channel.userlist.Rename(event.Nick, event.Arg(0))
  63. }
  64. case "packet.account":
  65. {
  66. newAccount := event.Arg(0)
  67. if newAccount != "*" && newAccount != "" {
  68. channel.userlist.Patch(event.Nick, list.UserPatch{Account: newAccount})
  69. } else {
  70. channel.userlist.Patch(event.Nick, list.UserPatch{ClearAccount: true})
  71. }
  72. }
  73. case "packet.away":
  74. {
  75. if event.Text != "" {
  76. channel.userlist.Patch(event.Nick, list.UserPatch{Away: event.Text})
  77. } else {
  78. channel.userlist.Patch(event.Nick, list.UserPatch{ClearAway: true})
  79. }
  80. }
  81. case "packet.chghost":
  82. {
  83. newUser := event.Arg(0)
  84. newHost := event.Arg(1)
  85. channel.userlist.Patch(event.Nick, list.UserPatch{User: newUser, Host: newHost})
  86. }
  87. case "packet.353": // NAMES
  88. {
  89. channel.userlist.SetAutoSort(false)
  90. tokens := strings.Split(event.Text, " ")
  91. for _, token := range tokens {
  92. channel.userlist.InsertFromNamesToken(token)
  93. }
  94. }
  95. case "packet.366": // End of NAMES
  96. {
  97. channel.userlist.SetAutoSort(true)
  98. }
  99. case "packet.mode":
  100. {
  101. isupport := client.ISupport()
  102. plus := false
  103. argIndex := 2
  104. for _, ch := range event.Arg(1) {
  105. if ch == '+' {
  106. plus = true
  107. continue
  108. }
  109. if ch == '-' {
  110. plus = false
  111. continue
  112. }
  113. arg := ""
  114. if isupport.ModeTakesArgument(ch, plus) {
  115. arg = event.Arg(argIndex)
  116. argIndex++
  117. }
  118. if isupport.IsPermissionMode(ch) {
  119. if plus {
  120. channel.userlist.AddMode(arg, ch)
  121. } else {
  122. channel.userlist.RemoveMode(arg, ch)
  123. }
  124. } else {
  125. // TODO: track non-permission modes
  126. }
  127. }
  128. }
  129. case "packet.privmsg", "ctcp.action":
  130. {
  131. if accountTag, ok := event.Tags["account"]; ok && accountTag != "" {
  132. channel.userlist.Patch(event.Nick, list.UserPatch{Account: accountTag})
  133. }
  134. }
  135. }
  136. }