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.

reply.go 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package irc
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. )
  7. type Identifier interface {
  8. Id() string
  9. }
  10. type Reply interface {
  11. String(client *Client) string
  12. }
  13. type BasicReply struct {
  14. source Identifier
  15. code string
  16. message string
  17. }
  18. func (reply *BasicReply) String(client *Client) string {
  19. prefix := fmt.Sprintf(":%s %s %s ", reply.source.Id(), reply.code, client.Nick())
  20. return prefix + reply.message
  21. }
  22. type ChannelReply struct {
  23. *BasicReply
  24. channel *Channel
  25. }
  26. func (reply *ChannelReply) String(client *Client) string {
  27. prefix := fmt.Sprintf(":%s %s %s ", reply.source.Id(), reply.code, reply.channel.name)
  28. return prefix + reply.message
  29. }
  30. func NewReply(source Identifier, code string, message string) *BasicReply {
  31. return &BasicReply{source, code, message}
  32. }
  33. // messaging
  34. func RplPrivMsg(source *Client, message string) Reply {
  35. return NewReply(source, RPL_PRIVMSG, ":"+message)
  36. }
  37. func RplNick(client *Client, newNick string) Reply {
  38. return NewReply(client, RPL_NICK, ":"+newNick)
  39. }
  40. func RplInviteMsg(channel *Channel, inviter *Client) Reply {
  41. return NewReply(inviter, RPL_INVITE, channel.name)
  42. }
  43. func RplInvitingMsg(channel *Channel, invitee *Client) Reply {
  44. return NewReply(channel.server, RPL_INVITING,
  45. fmt.Sprintf("%s %s", channel.name, invitee.Nick()))
  46. }
  47. // Server Info
  48. func RplWelcome(source Identifier, client *Client) Reply {
  49. return NewReply(source, RPL_WELCOME,
  50. "Welcome to the Internet Relay Network "+client.Id())
  51. }
  52. func RplYourHost(server *Server, target *Client) Reply {
  53. return NewReply(server, RPL_YOURHOST,
  54. fmt.Sprintf("Your host is %s, running version %s", server.hostname, VERSION))
  55. }
  56. func RplCreated(server *Server) Reply {
  57. return NewReply(server, RPL_CREATED,
  58. "This server was created "+server.ctime.Format(time.RFC1123))
  59. }
  60. func RplMyInfo(server *Server) Reply {
  61. return NewReply(server, RPL_MYINFO,
  62. fmt.Sprintf("%s %s i ik", server.name, VERSION))
  63. }
  64. func RplUModeIs(server *Server, client *Client) Reply {
  65. return NewReply(server, RPL_UMODEIS, client.UModeString())
  66. }
  67. // channel operations
  68. func RplPrivMsgChannel(channel *Channel, source *Client, message string) Reply {
  69. return &ChannelReply{NewReply(source, RPL_PRIVMSG, ":"+message), channel}
  70. }
  71. func RplJoin(channel *Channel, client *Client) Reply {
  72. return &ChannelReply{NewReply(client, RPL_JOIN, ""), channel}
  73. }
  74. func RplPart(channel *Channel, client *Client, message string) Reply {
  75. return &ChannelReply{NewReply(client, RPL_PART, ":"+message), channel}
  76. }
  77. func RplNoTopic(channel *Channel) Reply {
  78. return &ChannelReply{NewReply(channel.server, RPL_NOTOPIC, ":No topic is set"), channel}
  79. }
  80. func RplTopic(channel *Channel) Reply {
  81. return &ChannelReply{NewReply(channel.server, RPL_TOPIC, ":"+channel.topic), channel}
  82. }
  83. // server info
  84. func RplNamReply(channel *Channel) Reply {
  85. // TODO multiple names and splitting based on message size
  86. return NewReply(channel.server, RPL_NAMREPLY,
  87. fmt.Sprintf("= %s :%s", channel.name, strings.Join(channel.Nicks(), " ")))
  88. }
  89. func RplEndOfNames(source Identifier) Reply {
  90. return NewReply(source, RPL_ENDOFNAMES, ":End of NAMES list")
  91. }
  92. func RplPong(server *Server) Reply {
  93. return NewReply(server, RPL_PONG, "")
  94. }
  95. // errors
  96. func ErrAlreadyRegistered(source Identifier) Reply {
  97. return NewReply(source, ERR_ALREADYREGISTRED, ":You may not reregister")
  98. }
  99. func ErrNickNameInUse(source Identifier, nick string) Reply {
  100. return NewReply(source, ERR_NICKNAMEINUSE,
  101. nick+" :Nickname is already in use")
  102. }
  103. func ErrUnknownCommand(source Identifier, command string) Reply {
  104. return NewReply(source, ERR_UNKNOWNCOMMAND,
  105. command+" :Unknown command")
  106. }
  107. func ErrUsersDontMatch(source Identifier) Reply {
  108. return NewReply(source, ERR_USERSDONTMATCH,
  109. ":Cannot change mode for other users")
  110. }
  111. func ErrNeedMoreParams(source Identifier, command string) Reply {
  112. return NewReply(source, ERR_NEEDMOREPARAMS,
  113. command+"%s :Not enough parameters")
  114. }
  115. func ErrNoSuchChannel(source Identifier, channel string) Reply {
  116. return NewReply(source, ERR_NOSUCHCHANNEL,
  117. channel+" :No such channel")
  118. }
  119. func ErrUserOnChannel(channel *Channel, member *Client) Reply {
  120. return NewReply(channel.server, ERR_USERONCHANNEL,
  121. fmt.Sprintf("%s %s :is already on channel", member.nick, channel.name))
  122. }
  123. func ErrNotOnChannel(channel *Channel) Reply {
  124. return NewReply(channel.server, ERR_NOTONCHANNEL,
  125. channel.name+" :You're not on that channel")
  126. }
  127. func ErrInviteOnlyChannel(channel *Channel) Reply {
  128. return NewReply(channel.server, ERR_INVITEONLYCHAN,
  129. channel.name+" :Cannot join channel (+i)")
  130. }
  131. func ErrBadChannelKey(channel *Channel) Reply {
  132. return NewReply(channel.server, ERR_BADCHANNELKEY,
  133. channel.name+" :Cannot join channel (+k)")
  134. }
  135. func ErrNoSuchNick(source Identifier, nick string) Reply {
  136. return NewReply(source, ERR_NOSUCHNICK,
  137. nick+" :No such nick/channel")
  138. }