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.

143 lines
3.0 KiB

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