Say2.java 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*
  2. * Copyright (C) 2004-2015 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.network.clientpackets;
  20. import java.util.logging.Level;
  21. import java.util.logging.LogRecord;
  22. import java.util.logging.Logger;
  23. import com.l2jserver.Config;
  24. import com.l2jserver.gameserver.handler.ChatHandler;
  25. import com.l2jserver.gameserver.handler.IChatHandler;
  26. import com.l2jserver.gameserver.model.L2Object;
  27. import com.l2jserver.gameserver.model.L2World;
  28. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  29. import com.l2jserver.gameserver.model.effects.L2EffectType;
  30. import com.l2jserver.gameserver.model.events.EventDispatcher;
  31. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerChat;
  32. import com.l2jserver.gameserver.model.events.returns.ChatFilterReturn;
  33. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  34. import com.l2jserver.gameserver.network.SystemMessageId;
  35. import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
  36. import com.l2jserver.gameserver.util.Util;
  37. /**
  38. * This class ...
  39. * @version $Revision: 1.16.2.12.2.7 $ $Date: 2005/04/11 10:06:11 $
  40. */
  41. public final class Say2 extends L2GameClientPacket
  42. {
  43. private static final String _C__49_SAY2 = "[C] 49 Say2";
  44. private static Logger _logChat = Logger.getLogger("chat");
  45. public static final int ALL = 0;
  46. public static final int SHOUT = 1; // !
  47. public static final int TELL = 2;
  48. public static final int PARTY = 3; // #
  49. public static final int CLAN = 4; // @
  50. public static final int GM = 5;
  51. public static final int PETITION_PLAYER = 6; // used for petition
  52. public static final int PETITION_GM = 7; // * used for petition
  53. public static final int TRADE = 8; // +
  54. public static final int ALLIANCE = 9; // $
  55. public static final int ANNOUNCEMENT = 10;
  56. public static final int BOAT = 11;
  57. public static final int L2FRIEND = 12;
  58. public static final int MSNCHAT = 13;
  59. public static final int PARTYMATCH_ROOM = 14;
  60. public static final int PARTYROOM_COMMANDER = 15; // (Yellow)
  61. public static final int PARTYROOM_ALL = 16; // (Red)
  62. public static final int HERO_VOICE = 17;
  63. public static final int CRITICAL_ANNOUNCE = 18;
  64. public static final int SCREEN_ANNOUNCE = 19;
  65. public static final int BATTLEFIELD = 20;
  66. public static final int MPCC_ROOM = 21;
  67. public static final int NPC_ALL = 22;
  68. public static final int NPC_SHOUT = 23;
  69. private static final String[] CHAT_NAMES =
  70. {
  71. "ALL",
  72. "SHOUT",
  73. "TELL",
  74. "PARTY",
  75. "CLAN",
  76. "GM",
  77. "PETITION_PLAYER",
  78. "PETITION_GM",
  79. "TRADE",
  80. "ALLIANCE",
  81. "ANNOUNCEMENT", // 10
  82. "BOAT",
  83. "L2FRIEND",
  84. "MSNCHAT",
  85. "PARTYMATCH_ROOM",
  86. "PARTYROOM_COMMANDER",
  87. "PARTYROOM_ALL",
  88. "HERO_VOICE",
  89. "CRITICAL_ANNOUNCE",
  90. "SCREEN_ANNOUNCE",
  91. "BATTLEFIELD",
  92. "MPCC_ROOM"
  93. };
  94. private static final String[] WALKER_COMMAND_LIST =
  95. {
  96. "USESKILL",
  97. "USEITEM",
  98. "BUYITEM",
  99. "SELLITEM",
  100. "SAVEITEM",
  101. "LOADITEM",
  102. "MSG",
  103. "DELAY",
  104. "LABEL",
  105. "JMP",
  106. "CALL",
  107. "RETURN",
  108. "MOVETO",
  109. "NPCSEL",
  110. "NPCDLG",
  111. "DLGSEL",
  112. "CHARSTATUS",
  113. "POSOUTRANGE",
  114. "POSINRANGE",
  115. "GOHOME",
  116. "SAY",
  117. "EXIT",
  118. "PAUSE",
  119. "STRINDLG",
  120. "STRNOTINDLG",
  121. "CHANGEWAITTYPE",
  122. "FORCEATTACK",
  123. "ISMEMBER",
  124. "REQUESTJOINPARTY",
  125. "REQUESTOUTPARTY",
  126. "QUITPARTY",
  127. "MEMBERSTATUS",
  128. "CHARBUFFS",
  129. "ITEMCOUNT",
  130. "FOLLOWTELEPORT"
  131. };
  132. private String _text;
  133. private int _type;
  134. private String _target;
  135. @Override
  136. protected void readImpl()
  137. {
  138. _text = readS();
  139. _type = readD();
  140. _target = (_type == TELL) ? readS() : null;
  141. }
  142. @Override
  143. protected void runImpl()
  144. {
  145. if (Config.DEBUG)
  146. {
  147. _log.info("Say2: Msg Type = '" + _type + "' Text = '" + _text + "'.");
  148. }
  149. L2PcInstance activeChar = getClient().getActiveChar();
  150. if (activeChar == null)
  151. {
  152. return;
  153. }
  154. if ((_type < 0) || (_type >= CHAT_NAMES.length))
  155. {
  156. _log.warning("Say2: Invalid type: " + _type + " Player : " + activeChar.getName() + " text: " + String.valueOf(_text));
  157. activeChar.sendPacket(ActionFailed.STATIC_PACKET);
  158. activeChar.logout();
  159. return;
  160. }
  161. if (_text.isEmpty())
  162. {
  163. _log.warning(activeChar.getName() + ": sending empty text. Possible packet hack!");
  164. activeChar.sendPacket(ActionFailed.STATIC_PACKET);
  165. activeChar.logout();
  166. return;
  167. }
  168. // Even though the client can handle more characters than it's current limit allows, an overflow (critical error) happens if you pass a huge (1000+) message.
  169. // July 11, 2011 - Verified on High Five 4 official client as 105.
  170. // Allow higher limit if player shift some item (text is longer then).
  171. if (!activeChar.isGM() && (((_text.indexOf(8) >= 0) && (_text.length() > 500)) || ((_text.indexOf(8) < 0) && (_text.length() > 105))))
  172. {
  173. activeChar.sendPacket(SystemMessageId.DONT_SPAM);
  174. return;
  175. }
  176. if (Config.L2WALKER_PROTECTION && (_type == TELL) && checkBot(_text))
  177. {
  178. Util.handleIllegalPlayerAction(activeChar, "Client Emulator Detect: Player " + activeChar.getName() + " using l2walker.", Config.DEFAULT_PUNISH);
  179. return;
  180. }
  181. if (activeChar.isCursedWeaponEquipped() && ((_type == TRADE) || (_type == SHOUT)))
  182. {
  183. activeChar.sendPacket(SystemMessageId.SHOUT_AND_TRADE_CHAT_CANNOT_BE_USED_WHILE_POSSESSING_CURSED_WEAPON);
  184. return;
  185. }
  186. if (activeChar.isChatBanned() && (_text.charAt(0) != '.'))
  187. {
  188. if (activeChar.getEffectList().getFirstEffect(L2EffectType.CHAT_BLOCK) != null)
  189. {
  190. activeChar.sendPacket(SystemMessageId.YOU_HAVE_BEEN_REPORTED_SO_CHATTING_NOT_ALLOWED);
  191. }
  192. else
  193. {
  194. for (int chatId : Config.BAN_CHAT_CHANNELS)
  195. {
  196. if (_type == chatId)
  197. {
  198. activeChar.sendPacket(SystemMessageId.CHATTING_IS_CURRENTLY_PROHIBITED);
  199. }
  200. }
  201. }
  202. return;
  203. }
  204. if (activeChar.isJailed() && Config.JAIL_DISABLE_CHAT)
  205. {
  206. if ((_type == TELL) || (_type == SHOUT) || (_type == TRADE) || (_type == HERO_VOICE))
  207. {
  208. activeChar.sendMessage("You can not chat with players outside of the jail.");
  209. return;
  210. }
  211. }
  212. if ((_type == PETITION_PLAYER) && activeChar.isGM())
  213. {
  214. _type = PETITION_GM;
  215. }
  216. if (Config.LOG_CHAT)
  217. {
  218. LogRecord record = new LogRecord(Level.INFO, _text);
  219. record.setLoggerName("chat");
  220. if (_type == TELL)
  221. {
  222. record.setParameters(new Object[]
  223. {
  224. CHAT_NAMES[_type],
  225. "[" + activeChar.getName() + " to " + _target + "]"
  226. });
  227. }
  228. else
  229. {
  230. record.setParameters(new Object[]
  231. {
  232. CHAT_NAMES[_type],
  233. "[" + activeChar.getName() + "]"
  234. });
  235. }
  236. _logChat.log(record);
  237. }
  238. if (_text.indexOf(8) >= 0)
  239. {
  240. if (!parseAndPublishItem(activeChar))
  241. {
  242. return;
  243. }
  244. }
  245. final ChatFilterReturn filter = EventDispatcher.getInstance().notifyEvent(new OnPlayerChat(activeChar, L2World.getInstance().getPlayer(_target), _text, _type), ChatFilterReturn.class);
  246. if (filter != null)
  247. {
  248. _text = filter.getFilteredText();
  249. }
  250. // Say Filter implementation
  251. if (Config.USE_SAY_FILTER)
  252. {
  253. checkText();
  254. }
  255. final IChatHandler handler = ChatHandler.getInstance().getHandler(_type);
  256. if (handler != null)
  257. {
  258. handler.handleChat(_type, activeChar, _target, _text);
  259. }
  260. else
  261. {
  262. _log.info("No handler registered for ChatType: " + _type + " Player: " + getClient());
  263. }
  264. }
  265. private boolean checkBot(String text)
  266. {
  267. for (String botCommand : WALKER_COMMAND_LIST)
  268. {
  269. if (text.startsWith(botCommand))
  270. {
  271. return true;
  272. }
  273. }
  274. return false;
  275. }
  276. private void checkText()
  277. {
  278. String filteredText = _text;
  279. for (String pattern : Config.FILTER_LIST)
  280. {
  281. filteredText = filteredText.replaceAll("(?i)" + pattern, Config.CHAT_FILTER_CHARS);
  282. }
  283. _text = filteredText;
  284. }
  285. private boolean parseAndPublishItem(L2PcInstance owner)
  286. {
  287. int pos1 = -1;
  288. while ((pos1 = _text.indexOf(8, pos1)) > -1)
  289. {
  290. int pos = _text.indexOf("ID=", pos1);
  291. if (pos == -1)
  292. {
  293. return false;
  294. }
  295. StringBuilder result = new StringBuilder(9);
  296. pos += 3;
  297. while (Character.isDigit(_text.charAt(pos)))
  298. {
  299. result.append(_text.charAt(pos++));
  300. }
  301. int id = Integer.parseInt(result.toString());
  302. L2Object item = L2World.getInstance().findObject(id);
  303. if (item instanceof L2ItemInstance)
  304. {
  305. if (owner.getInventory().getItemByObjectId(id) == null)
  306. {
  307. _log.info(getClient() + " trying publish item which doesnt own! ID:" + id);
  308. return false;
  309. }
  310. ((L2ItemInstance) item).publish();
  311. }
  312. else
  313. {
  314. _log.info(getClient() + " trying publish object which is not item! Object:" + item);
  315. return false;
  316. }
  317. pos1 = _text.indexOf(8, pos) + 1;
  318. if (pos1 == 0) // missing ending tag
  319. {
  320. _log.info(getClient() + " sent invalid publish item msg! ID:" + id);
  321. return false;
  322. }
  323. }
  324. return true;
  325. }
  326. @Override
  327. public String getType()
  328. {
  329. return _C__49_SAY2;
  330. }
  331. @Override
  332. protected boolean triggersOnActionRequest()
  333. {
  334. return false;
  335. }
  336. }