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.

139 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.nick":
  50. {
  51. channel.userlist.Rename(event.Nick, event.Arg(0))
  52. }
  53. case "packet.account":
  54. {
  55. newAccount := event.Arg(0)
  56. if newAccount != "*" && newAccount != "" {
  57. channel.userlist.Patch(event.Nick, list.UserPatch{Account: newAccount})
  58. } else {
  59. channel.userlist.Patch(event.Nick, list.UserPatch{ClearAccount: true})
  60. }
  61. }
  62. case "packet.away":
  63. {
  64. if event.Text != "" {
  65. channel.userlist.Patch(event.Nick, list.UserPatch{Away: event.Text})
  66. } else {
  67. channel.userlist.Patch(event.Nick, list.UserPatch{ClearAway: true})
  68. }
  69. }
  70. case "packet.chghost":
  71. {
  72. newUser := event.Arg(0)
  73. newHost := event.Arg(1)
  74. channel.userlist.Patch(event.Nick, list.UserPatch{User: newUser, Host: newHost})
  75. }
  76. case "packet.353": // NAMES
  77. {
  78. channel.userlist.SetAutoSort(false)
  79. tokens := strings.Split(event.Text, " ")
  80. for _, token := range tokens {
  81. channel.userlist.InsertFromNamesToken(token)
  82. }
  83. }
  84. case "packet.366": // End of NAMES
  85. {
  86. channel.userlist.SetAutoSort(true)
  87. }
  88. case "packet.mode":
  89. {
  90. isupport := client.ISupport()
  91. plus := false
  92. argIndex := 2
  93. for _, ch := range event.Arg(1) {
  94. if ch == '+' {
  95. plus = true
  96. continue
  97. }
  98. if ch == '-' {
  99. plus = false
  100. continue
  101. }
  102. arg := ""
  103. if isupport.ModeTakesArgument(ch, plus) {
  104. arg = event.Arg(argIndex)
  105. argIndex++
  106. }
  107. if isupport.IsPermissionMode(ch) {
  108. if plus {
  109. channel.userlist.AddMode(arg, ch)
  110. } else {
  111. channel.userlist.RemoveMode(arg, ch)
  112. }
  113. } else {
  114. // TODO: track non-permission modes
  115. }
  116. }
  117. }
  118. case "packet.privmsg", "ctcp.action":
  119. {
  120. if accountTag, ok := event.Tags["account"]; ok && accountTag != "" {
  121. channel.userlist.Patch(event.Nick, list.UserPatch{Account: accountTag})
  122. }
  123. }
  124. }
  125. }