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.

133 lines
2.8 KiB

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