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.

113 lines
3.1 KiB

  1. package handlers
  2. import (
  3. "strings"
  4. "github.com/gissleh/irc"
  5. "github.com/gissleh/irc/ircutil"
  6. )
  7. // MRoleplay is a handler that adds commands for cutting NPC commands, as well as cleaning up
  8. // the input from the server. It's named after Charybdis IRCd's m_roleplay module.
  9. func MRoleplay(event *irc.Event, client *irc.Client) {
  10. switch event.Name() {
  11. case "input.enablerp", "input.disablerp":
  12. {
  13. sign := "+"
  14. if event.Verb() == "disablerp" {
  15. sign = "-"
  16. }
  17. chanMode, chanModeOk := client.ISupport().Get("RPCHAN")
  18. channel := event.ChannelTarget()
  19. if channel != nil && chanModeOk {
  20. client.SendQueuedf("MODE %s %s%s", channel.Name(), sign, chanMode)
  21. }
  22. userMode, userModeOk := client.ISupport().Get("RPUSER")
  23. query := event.QueryTarget()
  24. status := event.StatusTarget()
  25. if (query != nil || status != nil) && userModeOk {
  26. client.SendQueuedf("MODE %s%s", sign, userMode)
  27. }
  28. }
  29. // Parse roleplaying messages, and replace underscored-nick with a render tag.
  30. case "packet.privmsg", "ctcp.action":
  31. {
  32. // Detect m_roleplay
  33. if strings.HasPrefix(event.Nick, "\x1F") {
  34. event.Nick = event.Nick[1 : len(event.Nick)-2]
  35. if event.Verb() == "PRIVMSG" {
  36. event.RenderTags["mRoleplay"] = "npc"
  37. } else {
  38. event.RenderTags["mRoleplay"] = "npca"
  39. }
  40. } else if strings.HasPrefix(event.Nick, "=") {
  41. event.RenderTags["mRoleplay"] = "scene"
  42. } else {
  43. break
  44. }
  45. lastSpace := strings.LastIndex(event.Text, " ")
  46. lastParanthesis := strings.LastIndex(event.Text, "(")
  47. if lastParanthesis != -1 && lastSpace != -1 && lastParanthesis == lastSpace+1 {
  48. event.Text = event.Text[:lastSpace]
  49. }
  50. }
  51. // NPC commands
  52. case "input.npcc", "input.npcac":
  53. {
  54. isAction := event.Verb() == "npcac"
  55. nick, text := ircutil.ParseArgAndText(event.Text)
  56. if nick == "" || text == "" {
  57. client.EmitNonBlocking(irc.NewErrorEvent("input", "Usage: /"+event.Verb()+" <nick> <text...>"))
  58. break
  59. }
  60. channel := event.ChannelTarget()
  61. if channel == nil {
  62. client.EmitNonBlocking(irc.NewErrorEvent("input", "Target is not a channel"))
  63. break
  64. }
  65. overhead := ircutil.MessageOverhead("\x1f"+nick+"\x1f", client.Nick(), "npc.fakeuser.invalid", channel.Name(), isAction)
  66. cuts := ircutil.CutMessage(text, overhead)
  67. for _, cut := range cuts {
  68. npcCommand := "NPC"
  69. if isAction {
  70. npcCommand = "NPCA"
  71. }
  72. client.SendQueuedf("%s %s %s :%s", npcCommand, channel.Name(), nick, cut)
  73. }
  74. event.PreventDefault()
  75. }
  76. // Scene/narrator command
  77. case "input.scenec", "input.narratorc":
  78. {
  79. if event.Text == "" {
  80. client.EmitNonBlocking(irc.NewErrorEvent("input", "Usage: /scenec <text...>"))
  81. break
  82. }
  83. channel := event.ChannelTarget()
  84. if channel == nil {
  85. client.EmitNonBlocking(irc.NewErrorEvent("input", "Target is not a channel"))
  86. break
  87. }
  88. overhead := ircutil.MessageOverhead("=Scene=", client.Nick(), "npc.fakeuser.invalid", channel.Name(), false)
  89. cuts := ircutil.CutMessage(event.Text, overhead)
  90. for _, cut := range cuts {
  91. client.SendQueuedf("SCENE %s :%s", channel.Name(), cut)
  92. }
  93. event.PreventDefault()
  94. }
  95. }
  96. }