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.

roleplay.go 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright (c) 2016-2017 Daniel Oaks <daniel@danieloaks.net>
  2. // released under the MIT license
  3. package irc
  4. import (
  5. "fmt"
  6. "github.com/DanielOaks/girc-go/ircmsg"
  7. )
  8. const (
  9. npcNickMask = "*%s*!%s@npc.fakeuser.invalid"
  10. sceneNickMask = "=Scene=!%s@npc.fakeuser.invalid"
  11. )
  12. // SCENE <target> <text to be sent>
  13. func sceneHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  14. target := msg.Params[0]
  15. message := msg.Params[1]
  16. sourceString := fmt.Sprintf(sceneNickMask, client.nick)
  17. sendRoleplayMessage(server, client, sourceString, target, false, message)
  18. return false
  19. }
  20. // NPC <target> <sourcenick> <text to be sent>
  21. func npcHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  22. target := msg.Params[0]
  23. fakeSource := msg.Params[1]
  24. message := msg.Params[2]
  25. _, err := CasefoldName(fakeSource)
  26. if err != nil {
  27. client.Send(nil, client.server.name, ERR_CANNOTSENDRP, target, "Fake source must be a valid nickname")
  28. return false
  29. }
  30. sourceString := fmt.Sprintf(npcNickMask, fakeSource, client.nick)
  31. sendRoleplayMessage(server, client, sourceString, target, false, message)
  32. return false
  33. }
  34. // NPCA <target> <sourcenick> <text to be sent>
  35. func npcaHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  36. target := msg.Params[0]
  37. fakeSource := msg.Params[1]
  38. message := msg.Params[2]
  39. sourceString := fmt.Sprintf(npcNickMask, fakeSource, client.nick)
  40. _, err := CasefoldName(fakeSource)
  41. if err != nil {
  42. client.Send(nil, client.server.name, ERR_CANNOTSENDRP, target, "Fake source must be a valid nickname")
  43. return false
  44. }
  45. sendRoleplayMessage(server, client, sourceString, target, true, message)
  46. return false
  47. }
  48. func sendRoleplayMessage(server *Server, client *Client, source string, targetString string, isAction bool, message string) {
  49. if isAction {
  50. message = fmt.Sprintf("\x01ACTION %s (%s)\x01", message, client.nick)
  51. } else {
  52. message = fmt.Sprintf("%s (%s)", message, client.nick)
  53. }
  54. target, cerr := CasefoldChannel(targetString)
  55. if cerr == nil {
  56. channel := server.channels.Get(target)
  57. if channel == nil {
  58. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, targetString, "No such channel")
  59. return
  60. }
  61. if !channel.CanSpeak(client) {
  62. client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, "Cannot send to channel")
  63. return
  64. }
  65. if !channel.flags[ChanRoleplaying] {
  66. client.Send(nil, client.server.name, ERR_CANNOTSENDRP, channel.name, "Channel doesn't have roleplaying mode available")
  67. return
  68. }
  69. channel.membersMutex.RLock()
  70. for member := range channel.members {
  71. if member == client && !client.capabilities[EchoMessage] {
  72. continue
  73. }
  74. member.Send(nil, source, "PRIVMSG", channel.name, message)
  75. }
  76. channel.membersMutex.RUnlock()
  77. } else {
  78. target, err := CasefoldName(targetString)
  79. user := server.clients.Get(target)
  80. if err != nil || user == nil {
  81. client.Send(nil, server.name, ERR_NOSUCHNICK, target, "No such nick")
  82. return
  83. }
  84. if !user.flags[UserRoleplaying] {
  85. client.Send(nil, client.server.name, ERR_CANNOTSENDRP, user.nick, "User doesn't have roleplaying mode enabled")
  86. return
  87. }
  88. user.Send(nil, source, "PRIVMSG", user.nick, message)
  89. if client.capabilities[EchoMessage] {
  90. client.Send(nil, source, "PRIVMSG", user.nick, message)
  91. }
  92. if user.flags[Away] {
  93. //TODO(dan): possibly implement cooldown of away notifications to users
  94. client.Send(nil, server.name, RPL_AWAY, user.nick, user.awayMessage)
  95. }
  96. }
  97. }