RequestBypassToServer.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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.StringTokenizer;
  21. import java.util.logging.Level;
  22. import com.l2jserver.Config;
  23. import com.l2jserver.gameserver.ai.CtrlIntention;
  24. import com.l2jserver.gameserver.data.xml.impl.AdminData;
  25. import com.l2jserver.gameserver.enums.InstanceType;
  26. import com.l2jserver.gameserver.enums.PlayerAction;
  27. import com.l2jserver.gameserver.handler.AdminCommandHandler;
  28. import com.l2jserver.gameserver.handler.BypassHandler;
  29. import com.l2jserver.gameserver.handler.CommunityBoardHandler;
  30. import com.l2jserver.gameserver.handler.IAdminCommandHandler;
  31. import com.l2jserver.gameserver.handler.IBypassHandler;
  32. import com.l2jserver.gameserver.model.L2Object;
  33. import com.l2jserver.gameserver.model.L2World;
  34. import com.l2jserver.gameserver.model.actor.L2Character;
  35. import com.l2jserver.gameserver.model.actor.L2Npc;
  36. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  37. import com.l2jserver.gameserver.model.entity.Hero;
  38. import com.l2jserver.gameserver.model.events.EventDispatcher;
  39. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcManorBypass;
  40. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerBypass;
  41. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  42. import com.l2jserver.gameserver.network.SystemMessageId;
  43. import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
  44. import com.l2jserver.gameserver.network.serverpackets.ConfirmDlg;
  45. import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
  46. import com.l2jserver.gameserver.util.GMAudit;
  47. import com.l2jserver.gameserver.util.Util;
  48. /**
  49. * RequestBypassToServer client packet implementation.
  50. * @author HorridoJoho
  51. */
  52. public final class RequestBypassToServer extends L2GameClientPacket
  53. {
  54. private static final String _C__23_REQUESTBYPASSTOSERVER = "[C] 23 RequestBypassToServer";
  55. // FIXME: This is for compatibility, will be changed when bypass functionality got an overhaul by NosBit
  56. private static final String[] _possibleNonHtmlCommands =
  57. {
  58. "_bbs",
  59. "bbs",
  60. "_mail",
  61. "_friend",
  62. "_match",
  63. "_diary",
  64. "_olympiad?command",
  65. "manor_menu_select"
  66. };
  67. // S
  68. private String _command;
  69. @Override
  70. protected void readImpl()
  71. {
  72. _command = readS();
  73. }
  74. @Override
  75. protected void runImpl()
  76. {
  77. final L2PcInstance activeChar = getClient().getActiveChar();
  78. if (activeChar == null)
  79. {
  80. return;
  81. }
  82. if (_command.isEmpty())
  83. {
  84. _log.warning("Player " + activeChar.getName() + " sent empty bypass!");
  85. activeChar.logout();
  86. return;
  87. }
  88. boolean requiresBypassValidation = true;
  89. for (String possibleNonHtmlCommand : _possibleNonHtmlCommands)
  90. {
  91. if (_command.startsWith(possibleNonHtmlCommand))
  92. {
  93. requiresBypassValidation = false;
  94. break;
  95. }
  96. }
  97. int bypassOriginId = 0;
  98. if (requiresBypassValidation)
  99. {
  100. bypassOriginId = activeChar.validateHtmlAction(_command);
  101. if (bypassOriginId == -1)
  102. {
  103. _log.warning("Player " + activeChar.getName() + " sent non cached bypass: '" + _command + "'");
  104. return;
  105. }
  106. if ((bypassOriginId > 0) && !Util.isInsideRangeOfObjectId(activeChar, bypassOriginId, L2Npc.INTERACTION_DISTANCE))
  107. {
  108. // No logging here, this could be a common case where the player has the html still open and run too far away and then clicks a html action
  109. return;
  110. }
  111. }
  112. if (!getClient().getFloodProtectors().getServerBypass().tryPerformAction(_command))
  113. {
  114. return;
  115. }
  116. try
  117. {
  118. if (_command.startsWith("admin_"))
  119. {
  120. String command = _command.split(" ")[0];
  121. IAdminCommandHandler ach = AdminCommandHandler.getInstance().getHandler(command);
  122. if (ach == null)
  123. {
  124. if (activeChar.isGM())
  125. {
  126. activeChar.sendMessage("The command " + command.substring(6) + " does not exist!");
  127. }
  128. _log.warning(activeChar + " requested not registered admin command '" + command + "'");
  129. return;
  130. }
  131. if (!AdminData.getInstance().hasAccess(command, activeChar.getAccessLevel()))
  132. {
  133. activeChar.sendMessage("You don't have the access rights to use this command!");
  134. _log.warning("Character " + activeChar.getName() + " tried to use admin command " + command + ", without proper access level!");
  135. return;
  136. }
  137. if (AdminData.getInstance().requireConfirm(command))
  138. {
  139. activeChar.setAdminConfirmCmd(_command);
  140. ConfirmDlg dlg = new ConfirmDlg(SystemMessageId.S1);
  141. dlg.addString("Are you sure you want execute command " + _command.substring(6) + " ?");
  142. activeChar.addAction(PlayerAction.ADMIN_COMMAND);
  143. activeChar.sendPacket(dlg);
  144. }
  145. else
  146. {
  147. if (Config.GMAUDIT)
  148. {
  149. GMAudit.auditGMAction(activeChar.getName() + " [" + activeChar.getObjectId() + "]", _command, (activeChar.getTarget() != null ? activeChar.getTarget().getName() : "no-target"));
  150. }
  151. ach.useAdminCommand(_command, activeChar);
  152. }
  153. }
  154. else if (CommunityBoardHandler.getInstance().isCommunityBoardCommand(_command))
  155. {
  156. CommunityBoardHandler.getInstance().handleParseCommand(_command, activeChar);
  157. }
  158. else if (_command.equals("come_here") && activeChar.isGM())
  159. {
  160. comeHere(activeChar);
  161. }
  162. else if (_command.startsWith("npc_"))
  163. {
  164. int endOfId = _command.indexOf('_', 5);
  165. String id;
  166. if (endOfId > 0)
  167. {
  168. id = _command.substring(4, endOfId);
  169. }
  170. else
  171. {
  172. id = _command.substring(4);
  173. }
  174. if (Util.isDigit(id))
  175. {
  176. L2Object object = L2World.getInstance().findObject(Integer.parseInt(id));
  177. if ((object != null) && object.isNpc() && (endOfId > 0) && activeChar.isInsideRadius(object, L2Npc.INTERACTION_DISTANCE, false, false))
  178. {
  179. ((L2Npc) object).onBypassFeedback(activeChar, _command.substring(endOfId + 1));
  180. }
  181. }
  182. activeChar.sendPacket(ActionFailed.STATIC_PACKET);
  183. }
  184. else if (_command.startsWith("item_"))
  185. {
  186. int endOfId = _command.indexOf('_', 5);
  187. String id;
  188. if (endOfId > 0)
  189. {
  190. id = _command.substring(5, endOfId);
  191. }
  192. else
  193. {
  194. id = _command.substring(5);
  195. }
  196. try
  197. {
  198. final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(Integer.parseInt(id));
  199. if ((item != null) && (endOfId > 0))
  200. {
  201. item.onBypassFeedback(activeChar, _command.substring(endOfId + 1));
  202. }
  203. activeChar.sendPacket(ActionFailed.STATIC_PACKET);
  204. }
  205. catch (NumberFormatException nfe)
  206. {
  207. _log.log(Level.WARNING, "NFE for command [" + _command + "]", nfe);
  208. }
  209. }
  210. else if (_command.startsWith("_match"))
  211. {
  212. String params = _command.substring(_command.indexOf("?") + 1);
  213. StringTokenizer st = new StringTokenizer(params, "&");
  214. int heroclass = Integer.parseInt(st.nextToken().split("=")[1]);
  215. int heropage = Integer.parseInt(st.nextToken().split("=")[1]);
  216. int heroid = Hero.getInstance().getHeroByClass(heroclass);
  217. if (heroid > 0)
  218. {
  219. Hero.getInstance().showHeroFights(activeChar, heroclass, heroid, heropage);
  220. }
  221. }
  222. else if (_command.startsWith("_diary"))
  223. {
  224. String params = _command.substring(_command.indexOf("?") + 1);
  225. StringTokenizer st = new StringTokenizer(params, "&");
  226. int heroclass = Integer.parseInt(st.nextToken().split("=")[1]);
  227. int heropage = Integer.parseInt(st.nextToken().split("=")[1]);
  228. int heroid = Hero.getInstance().getHeroByClass(heroclass);
  229. if (heroid > 0)
  230. {
  231. Hero.getInstance().showHeroDiary(activeChar, heroclass, heroid, heropage);
  232. }
  233. }
  234. else if (_command.startsWith("_olympiad?command"))
  235. {
  236. int arenaId = Integer.parseInt(_command.split("=")[2]);
  237. final IBypassHandler handler = BypassHandler.getInstance().getHandler("arenachange");
  238. if (handler != null)
  239. {
  240. handler.useBypass("arenachange " + (arenaId - 1), activeChar, null);
  241. }
  242. }
  243. else if (_command.startsWith("manor_menu_select"))
  244. {
  245. final L2Npc lastNpc = activeChar.getLastFolkNPC();
  246. if (Config.ALLOW_MANOR && (lastNpc != null) && lastNpc.canInteract(activeChar))
  247. {
  248. final String[] split = _command.substring(_command.indexOf("?") + 1).split("&");
  249. final int ask = Integer.parseInt(split[0].split("=")[1]);
  250. final int state = Integer.parseInt(split[1].split("=")[1]);
  251. final boolean time = split[2].split("=")[1].equals("1");
  252. EventDispatcher.getInstance().notifyEventAsync(new OnNpcManorBypass(activeChar, lastNpc, ask, state, time), lastNpc);
  253. }
  254. }
  255. else
  256. {
  257. final IBypassHandler handler = BypassHandler.getInstance().getHandler(_command);
  258. if (handler != null)
  259. {
  260. if (bypassOriginId > 0)
  261. {
  262. L2Object bypassOrigin = activeChar.getKnownList().getKnownObjects().get(bypassOriginId);
  263. if ((bypassOrigin != null) && bypassOrigin.isInstanceTypes(InstanceType.L2Character))
  264. {
  265. handler.useBypass(_command, activeChar, (L2Character) bypassOrigin);
  266. }
  267. else
  268. {
  269. handler.useBypass(_command, activeChar, null);
  270. }
  271. }
  272. else
  273. {
  274. handler.useBypass(_command, activeChar, null);
  275. }
  276. }
  277. else
  278. {
  279. _log.warning(getClient() + " sent not handled RequestBypassToServer: [" + _command + "]");
  280. }
  281. }
  282. }
  283. catch (Exception e)
  284. {
  285. _log.log(Level.WARNING, "Exception processing bypass from player " + activeChar.getName() + ": " + _command, e);
  286. if (activeChar.isGM())
  287. {
  288. StringBuilder sb = new StringBuilder(200);
  289. sb.append("<html><body>");
  290. sb.append("Bypass error: " + e + "<br1>");
  291. sb.append("Bypass command: " + _command + "<br1>");
  292. sb.append("StackTrace:<br1>");
  293. for (StackTraceElement ste : e.getStackTrace())
  294. {
  295. sb.append(ste.toString() + "<br1>");
  296. }
  297. sb.append("</body></html>");
  298. // item html
  299. final NpcHtmlMessage msg = new NpcHtmlMessage(0, 1, sb.toString());
  300. msg.disableValidation();
  301. activeChar.sendPacket(msg);
  302. }
  303. }
  304. EventDispatcher.getInstance().notifyEventAsync(new OnPlayerBypass(activeChar, _command), activeChar);
  305. }
  306. /**
  307. * @param activeChar
  308. */
  309. private static void comeHere(L2PcInstance activeChar)
  310. {
  311. L2Object obj = activeChar.getTarget();
  312. if (obj == null)
  313. {
  314. return;
  315. }
  316. if (obj instanceof L2Npc)
  317. {
  318. L2Npc temp = (L2Npc) obj;
  319. temp.setTarget(activeChar);
  320. temp.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, activeChar.getLocation());
  321. }
  322. }
  323. @Override
  324. public String getType()
  325. {
  326. return _C__23_REQUESTBYPASSTOSERVER;
  327. }
  328. }