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.

99 lines
2.1 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package irc
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "time"
  7. )
  8. var unescapeTags = strings.NewReplacer("\\\\", "\\", "\\:", ";", "\\s", " ", "\\r", "\r", "\\n", "\n")
  9. // ParsePacket parses an irc line and returns an event that's either of kind `packet`, `ctcp` or `ctcpreply`
  10. func ParsePacket(line string) (Event, error) {
  11. event := NewEvent("packet", "")
  12. event.Time = time.Now()
  13. if len(line) == 0 {
  14. return event, errors.New("irc: empty line")
  15. }
  16. // Parse tags
  17. if line[0] == '@' {
  18. split := strings.SplitN(line, " ", 2)
  19. if len(split) < 2 {
  20. return event, errors.New("irc: incomplete packet")
  21. }
  22. tagTokens := strings.Split(split[0][1:], ";")
  23. for _, token := range tagTokens {
  24. kv := strings.SplitN(token, "=", 2)
  25. if len(kv) == 2 {
  26. event.Tags[kv[0]] = unescapeTags.Replace(kv[1])
  27. } else {
  28. event.Tags[kv[0]] = ""
  29. }
  30. }
  31. line = split[1]
  32. }
  33. // Parse prefix
  34. if line[0] == ':' {
  35. split := strings.SplitN(line, " ", 2)
  36. if len(split) < 2 {
  37. return event, errors.New("ParsePacket: incomplete packet")
  38. }
  39. prefixTokens := strings.Split(split[0][1:], "!")
  40. event.Nick = prefixTokens[0]
  41. if len(prefixTokens) > 1 {
  42. userhost := strings.Split(prefixTokens[1], "@")
  43. if len(userhost) < 2 {
  44. return event, errors.New("ParsePacket: invalid user@host format")
  45. }
  46. event.User = userhost[0]
  47. event.Host = userhost[1]
  48. }
  49. line = split[1]
  50. }
  51. // Parse body
  52. split := strings.SplitN(line, " :", 2)
  53. tokens := strings.Split(split[0], " ")
  54. if len(split) == 2 {
  55. event.Text = split[1]
  56. }
  57. event.verb = tokens[0]
  58. event.Args = tokens[1:]
  59. fmt.Printf("%#+v\n", split)
  60. // Parse CTCP
  61. if (event.verb == "PRIVMSG" || event.verb == "NOTICE") && strings.HasPrefix(event.Text, "\x01") {
  62. verbtext := strings.SplitN(strings.Replace(event.Text, "\x01", "", 2), " ", 2)
  63. if event.verb == "PRIVMSG" {
  64. event.kind = "ctcp"
  65. } else {
  66. event.kind = "ctcp-reply"
  67. }
  68. event.verb = verbtext[0]
  69. if len(verbtext) == 2 {
  70. event.Text = verbtext[1]
  71. } else {
  72. event.Text = ""
  73. }
  74. }
  75. event.name = event.kind + "." + strings.ToLower(event.verb)
  76. return event, nil
  77. }