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.

ChannelEventHandler.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. * Copyright (c) 2006-2014 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc;
  23. import com.dmdirc.actions.ActionManager;
  24. import com.dmdirc.actions.CoreActionType;
  25. import com.dmdirc.interfaces.Connection;
  26. import com.dmdirc.parser.common.AwayState;
  27. import com.dmdirc.parser.common.CallbackManager;
  28. import com.dmdirc.parser.interfaces.ChannelClientInfo;
  29. import com.dmdirc.parser.interfaces.ChannelInfo;
  30. import com.dmdirc.parser.interfaces.ClientInfo;
  31. import com.dmdirc.parser.interfaces.Parser;
  32. import com.dmdirc.parser.interfaces.callbacks.*; //NOPMD
  33. import java.util.Date;
  34. /**
  35. * Handles events for channel objects.
  36. */
  37. public class ChannelEventHandler extends EventHandler implements
  38. ChannelMessageListener, ChannelNamesListener, ChannelTopicListener,
  39. ChannelJoinListener, ChannelPartListener, ChannelKickListener,
  40. ChannelQuitListener, ChannelActionListener, ChannelNickChangeListener,
  41. ChannelModeChangeListener, ChannelUserModeChangeListener,
  42. ChannelCtcpListener, OtherAwayStateListener, ChannelNoticeListener,
  43. ChannelNonUserModeChangeListener, ChannelModeNoticeListener,
  44. ChannelListModeListener {
  45. /** The channel that owns this event handler. */
  46. private final Channel owner;
  47. public ChannelEventHandler(final Channel owner) {
  48. this.owner = owner;
  49. }
  50. /** {@inheritDoc} */
  51. @SuppressWarnings("unchecked")
  52. @Override
  53. protected <T extends CallbackInterface> void addCallback(final CallbackManager cbm,
  54. final Class<T> type) {
  55. if (OtherAwayStateListener.class.equals(type)) {
  56. cbm.addCallback(type, (T) this);
  57. } else {
  58. cbm.addCallback(type, (T) this, owner.getChannelInfo().getName());
  59. }
  60. }
  61. /** {@inheritDoc} */
  62. @Override
  63. protected Connection getConnection() {
  64. return owner.getConnection();
  65. }
  66. /**
  67. * Determines if the specified client represents us.
  68. *
  69. * @param client The client to be tested
  70. * @return True if the client is ourself, false otherwise.
  71. */
  72. protected boolean isMyself(final ChannelClientInfo client) {
  73. return client.getClient().equals(owner.getConnection().getParser().getLocalClient());
  74. }
  75. /** {@inheritDoc} */
  76. @Override
  77. public void onChannelMessage(final Parser parser, final Date date,
  78. final ChannelInfo channel, final ChannelClientInfo client,
  79. final String message, final String host) {
  80. checkParser(parser);
  81. owner.doNotification(date,
  82. isMyself(client) ? "channelSelfExternalMessage" : "channelMessage",
  83. CoreActionType.CHANNEL_MESSAGE, client, message);
  84. }
  85. /** {@inheritDoc} */
  86. @Override
  87. public void onChannelGotNames(final Parser parser, final Date date, final ChannelInfo channel) {
  88. checkParser(parser);
  89. owner.setClients(channel.getChannelClients());
  90. ActionManager.getActionManager().triggerEvent(
  91. CoreActionType.CHANNEL_GOTNAMES, null, owner);
  92. }
  93. /** {@inheritDoc} */
  94. @Override
  95. public void onChannelTopic(final Parser parser, final Date date,
  96. final ChannelInfo channel, final boolean isJoinTopic) {
  97. checkParser(parser);
  98. final Topic newTopic = new Topic(channel.getTopic(),
  99. channel.getTopicSetter(), channel.getTopicTime());
  100. if (isJoinTopic) {
  101. if (newTopic.getTopic().isEmpty()) {
  102. owner.doNotification(date, "channelNoTopic", CoreActionType.CHANNEL_NOTOPIC);
  103. } else {
  104. owner.doNotification(date, "channelTopicDiscovered", CoreActionType.CHANNEL_GOTTOPIC,
  105. newTopic);
  106. }
  107. } else {
  108. owner.doNotification(date, channel.getTopic().isEmpty()
  109. ? "channelTopicRemoved" : "channelTopicChanged",
  110. CoreActionType.CHANNEL_TOPICCHANGE,
  111. channel.getChannelClient(channel.getTopicSetter(), true), channel.getTopic());
  112. }
  113. if (!isJoinTopic
  114. || (owner.getCurrentTopic() == null && !newTopic.getTopic().isEmpty())
  115. || (owner.getCurrentTopic() != null
  116. && !newTopic.getTopic().equals(owner.getCurrentTopic().getTopic()))) {
  117. // Only add the topic if it's being changed when we're on the
  118. // channel (i.e., not a "joinTopic"), or if it's different to the
  119. // one we're expecting
  120. owner.addTopic(newTopic);
  121. }
  122. }
  123. /** {@inheritDoc} */
  124. @Override
  125. public void onChannelJoin(final Parser parser, final Date date, final ChannelInfo channel,
  126. final ChannelClientInfo client) {
  127. checkParser(parser);
  128. owner.doNotification(date, "channelJoin", CoreActionType.CHANNEL_JOIN, client);
  129. owner.addClient(client);
  130. }
  131. /** {@inheritDoc} */
  132. @Override
  133. public void onChannelPart(final Parser parser, final Date date, final ChannelInfo channel,
  134. final ChannelClientInfo client, final String reason) {
  135. checkParser(parser);
  136. owner.doNotification(date, "channel"
  137. + (isMyself(client) ? "Self" : "") + "Part"
  138. + (reason.isEmpty() ? "" : "Reason"), CoreActionType.CHANNEL_PART,
  139. client, reason);
  140. owner.removeClient(client);
  141. }
  142. /** {@inheritDoc} */
  143. @Override
  144. public void onChannelKick(final Parser parser, final Date date, final ChannelInfo channel,
  145. final ChannelClientInfo kickedClient, final ChannelClientInfo client,
  146. final String reason, final String host) {
  147. checkParser(parser);
  148. owner.doNotification(date, "channelKick" + (reason.isEmpty() ? "" : "Reason"),
  149. CoreActionType.CHANNEL_KICK, client, kickedClient, reason);
  150. owner.removeClient(kickedClient);
  151. }
  152. /** {@inheritDoc} */
  153. @Override
  154. public void onChannelQuit(final Parser parser, final Date date, final ChannelInfo channel,
  155. final ChannelClientInfo client, final String reason) {
  156. checkParser(parser);
  157. owner.doNotification(date, "channelQuit" + (reason.isEmpty() ? "" : "Reason"),
  158. CoreActionType.CHANNEL_QUIT, client, reason);
  159. owner.removeClient(client);
  160. }
  161. /** {@inheritDoc} */
  162. @Override
  163. public void onChannelAction(final Parser parser, final Date date, final ChannelInfo channel,
  164. final ChannelClientInfo client, final String message,
  165. final String host) {
  166. checkParser(parser);
  167. owner.doNotification(date,
  168. isMyself(client) ? "channelSelfExternalAction" : "channelAction",
  169. CoreActionType.CHANNEL_ACTION, client, message);
  170. }
  171. /** {@inheritDoc} */
  172. @Override
  173. public void onChannelNickChanged(final Parser parser, final Date date,
  174. final ChannelInfo channel, final ChannelClientInfo client, final String oldNick) {
  175. checkParser(parser);
  176. owner.doNotification(date,
  177. isMyself(client) ? "channelSelfNickChange" : "channelNickChange",
  178. CoreActionType.CHANNEL_NICKCHANGE, client, oldNick);
  179. owner.renameClient(oldNick, client.getClient().getNickname());
  180. }
  181. /** {@inheritDoc} */
  182. @Override
  183. public void onChannelModeChanged(final Parser parser, final Date date,
  184. final ChannelInfo channel, final ChannelClientInfo client, final String host,
  185. final String modes) {
  186. checkParser(parser);
  187. if (!owner.getConfigManager().getOptionBool("channel", "splitusermodes")
  188. || !owner.getConfigManager().getOptionBool("channel", "hideduplicatemodes")) {
  189. if (host.isEmpty()) {
  190. owner.doNotification(date, modes.length() <= 1 ? "channelNoModes"
  191. : "channelModeDiscovered", CoreActionType.CHANNEL_MODESDISCOVERED,
  192. modes.length() <= 1 ? "" : modes);
  193. } else {
  194. owner.doNotification(date, isMyself(client) ? "channelSelfModeChanged"
  195. : "channelModeChanged", CoreActionType.CHANNEL_MODECHANGE,
  196. client, modes);
  197. }
  198. }
  199. owner.refreshClients();
  200. }
  201. /** {@inheritDoc} */
  202. @Override
  203. public void onChannelUserModeChanged(final Parser parser, final Date date,
  204. final ChannelInfo channel, final ChannelClientInfo targetClient,
  205. final ChannelClientInfo client, final String host, final String mode) {
  206. checkParser(parser);
  207. if (owner.getConfigManager().getOptionBool("channel", "splitusermodes")) {
  208. String format = "channelSplitUserMode_" + mode;
  209. if (!owner.getConfigManager().hasOptionString("formatter", format)) {
  210. format = "channelSplitUserMode_default";
  211. }
  212. owner.doNotification(date, format, CoreActionType.CHANNEL_USERMODECHANGE,
  213. client, targetClient, mode);
  214. }
  215. }
  216. /** {@inheritDoc} */
  217. @Override
  218. public void onChannelCTCP(final Parser parser, final Date date,
  219. final ChannelInfo channel, final ChannelClientInfo client,
  220. final String type, final String message, final String host) {
  221. checkParser(parser);
  222. if (owner.doNotification(date, "channelCTCP", CoreActionType.CHANNEL_CTCP,
  223. client, type, message)) {
  224. owner.getConnection().sendCTCPReply(client.getClient().getNickname(),
  225. type, message);
  226. }
  227. }
  228. /** {@inheritDoc} */
  229. @Override
  230. public void onAwayStateOther(final Parser parser, final Date date,
  231. final ClientInfo client, final AwayState oldState, final AwayState state) {
  232. checkParser(parser);
  233. final ChannelClientInfo channelClient = owner.getChannelInfo().getChannelClient(client);
  234. if (channelClient != null) {
  235. final boolean away = state == AwayState.AWAY;
  236. final boolean discovered = oldState == AwayState.UNKNOWN;
  237. owner.doNotification(date, (away ? "channelUserAway" : "channelUserBack")
  238. + (discovered ? "Discovered" : ""),
  239. away ? CoreActionType.CHANNEL_USERAWAY : CoreActionType.CHANNEL_USERBACK,
  240. channelClient);
  241. }
  242. }
  243. /** {@inheritDoc} */
  244. @Override
  245. public void onChannelNotice(final Parser parser, final Date date,
  246. final ChannelInfo channel, final ChannelClientInfo client,
  247. final String message, final String host) {
  248. checkParser(parser);
  249. owner.doNotification(date, "channelNotice", CoreActionType.CHANNEL_NOTICE,
  250. client, message);
  251. }
  252. /** {@inheritDoc} */
  253. @Override
  254. public void onChannelNonUserModeChanged(final Parser parser, final Date date,
  255. final ChannelInfo channel, final ChannelClientInfo client,
  256. final String host, final String modes) {
  257. checkParser(parser);
  258. if (owner.getConfigManager().getOptionBool("channel", "splitusermodes")
  259. && owner.getConfigManager().getOptionBool("channel", "hideduplicatemodes")) {
  260. if (host.isEmpty()) {
  261. owner.doNotification(date, modes.length() <= 1 ? "channelNoModes"
  262. : "channelModeDiscovered", CoreActionType.CHANNEL_MODESDISCOVERED,
  263. modes.length() <= 1 ? "" : modes);
  264. } else {
  265. owner.doNotification(date, isMyself(client) ? "channelSelfModeChanged"
  266. : "channelModeChanged", CoreActionType.CHANNEL_MODECHANGE,
  267. client, modes);
  268. }
  269. }
  270. owner.refreshClients();
  271. }
  272. /** {@inheritDoc} */
  273. @Override
  274. public void onChannelModeNotice(final Parser parser, final Date date,
  275. final ChannelInfo channel, final char prefix,
  276. final ChannelClientInfo client, final String message,
  277. final String host) {
  278. checkParser(parser);
  279. owner.doNotification(date, "channelModeNotice", CoreActionType.CHANNEL_MODE_NOTICE,
  280. client, String.valueOf(prefix), message);
  281. }
  282. /** {@inheritDoc} */
  283. @Override
  284. public void onChannelGotListModes(final Parser parser, final Date date,
  285. final ChannelInfo channel, final char mode) {
  286. checkParser(parser);
  287. owner.doNotification(date, "channelListModeRetrieved",
  288. CoreActionType.CHANNEL_LISTMODERETRIEVED, Character.valueOf(mode));
  289. }
  290. }