AdminPForge.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. /*
  2. * Copyright (C) 2004-2014 L2J DataPack
  3. *
  4. * This file is part of L2J DataPack.
  5. *
  6. * L2J DataPack 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 DataPack 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 handlers.admincommandhandlers;
  20. import java.math.BigInteger;
  21. import java.nio.ByteBuffer;
  22. import java.util.Collection;
  23. import java.util.LinkedList;
  24. import java.util.StringTokenizer;
  25. import org.mmocore.network.NioNetStringBuffer;
  26. import com.l2jserver.gameserver.GameServer;
  27. import com.l2jserver.gameserver.ThreadPoolManager;
  28. import com.l2jserver.gameserver.cache.HtmCache;
  29. import com.l2jserver.gameserver.handler.IAdminCommandHandler;
  30. import com.l2jserver.gameserver.model.L2Object;
  31. import com.l2jserver.gameserver.model.actor.L2Character;
  32. import com.l2jserver.gameserver.model.actor.L2Playable;
  33. import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
  34. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  35. import com.l2jserver.gameserver.network.clientpackets.L2GameClientPacket;
  36. import com.l2jserver.gameserver.network.serverpackets.AdminForgePacket;
  37. import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
  38. /**
  39. * This class handles commands for gm to forge packets
  40. * @author Maktakien, HorridoJoho
  41. */
  42. public final class AdminPForge implements IAdminCommandHandler
  43. {
  44. private static final String[] ADMIN_COMMANDS =
  45. {
  46. "admin_forge",
  47. "admin_forge_values",
  48. "admin_forge_send"
  49. };
  50. private String[] getOpCodes(StringTokenizer st)
  51. {
  52. Collection<String> opCodes = null;
  53. while (st.hasMoreTokens())
  54. {
  55. String token = st.nextToken();
  56. if (";".equals(token))
  57. {
  58. break;
  59. }
  60. if (opCodes == null)
  61. {
  62. opCodes = new LinkedList<>();
  63. }
  64. opCodes.add(token);
  65. }
  66. if (opCodes == null)
  67. {
  68. return null;
  69. }
  70. return opCodes.toArray(new String[opCodes.size()]);
  71. }
  72. private boolean validateOpCodes(String[] opCodes)
  73. {
  74. if ((opCodes == null) || (opCodes.length == 0) || (opCodes.length > 3))
  75. {
  76. return false;
  77. }
  78. for (int i = 0; i < opCodes.length; ++i)
  79. {
  80. final String opCode = opCodes[i];
  81. long opCodeLong;
  82. try
  83. {
  84. opCodeLong = Long.parseLong(opCode);
  85. }
  86. catch (Exception e)
  87. {
  88. if (i > 0)
  89. {
  90. return true;
  91. }
  92. return false;
  93. }
  94. if (opCodeLong < 0)
  95. {
  96. return false;
  97. }
  98. if ((i == 0) && (opCodeLong > 255))
  99. {
  100. return false;
  101. }
  102. else if ((i == 1) && (opCodeLong > 65535))
  103. {
  104. return false;
  105. }
  106. else if ((i == 2) && (opCodeLong > 4294967295L))
  107. {
  108. return false;
  109. }
  110. }
  111. return true;
  112. }
  113. private boolean validateFormat(String format)
  114. {
  115. for (int chIdx = 0; chIdx < format.length(); ++chIdx)
  116. {
  117. switch (format.charAt(chIdx))
  118. {
  119. case 'b':
  120. case 'B':
  121. case 'x':
  122. case 'X':
  123. // array
  124. break;
  125. case 'c':
  126. case 'C':
  127. // byte
  128. break;
  129. case 'h':
  130. case 'H':
  131. // word
  132. break;
  133. case 'd':
  134. case 'D':
  135. // dword
  136. break;
  137. case 'q':
  138. case 'Q':
  139. // qword
  140. break;
  141. case 'f':
  142. case 'F':
  143. // double
  144. break;
  145. case 's':
  146. case 'S':
  147. // string
  148. break;
  149. default:
  150. return false;
  151. }
  152. }
  153. return true;
  154. }
  155. private boolean validateMethod(String method)
  156. {
  157. switch (method)
  158. {
  159. case "sc":
  160. case "sb":
  161. case "cs":
  162. return true;
  163. }
  164. return false;
  165. }
  166. private void showValuesUsage(L2PcInstance activeChar)
  167. {
  168. activeChar.sendMessage("Usage: //forge_values opcode1[ opcode2[ opcode3]] ;[ format]");
  169. showMainPage(activeChar);
  170. }
  171. private void showSendUsage(L2PcInstance activeChar, String[] opCodes, String format)
  172. {
  173. activeChar.sendMessage("Usage: //forge_send sc|sb|cs opcode1[;opcode2[;opcode3]][ format value1 ... valueN] ");
  174. if (opCodes == null)
  175. {
  176. showMainPage(activeChar);
  177. }
  178. else
  179. {
  180. showValuesPage(activeChar, opCodes, format);
  181. }
  182. }
  183. private void showMainPage(L2PcInstance activeChar)
  184. {
  185. AdminHtml.showAdminHtml(activeChar, "pforge/main.htm");
  186. }
  187. private void showValuesPage(L2PcInstance activeChar, String[] opCodes, String format)
  188. {
  189. String sendBypass = null;
  190. String valuesHtml = HtmCache.getInstance().getHtmForce(activeChar.getHtmlPrefix(), "data/html/admin/pforge/values.htm");
  191. if (opCodes.length == 3)
  192. {
  193. valuesHtml = valuesHtml.replace("%opformat%", "chd");
  194. sendBypass = opCodes[0] + ";" + opCodes[1] + ";" + opCodes[2];
  195. }
  196. else if (opCodes.length == 2)
  197. {
  198. valuesHtml = valuesHtml.replace("%opformat%", "ch");
  199. sendBypass = opCodes[0] + ";" + opCodes[1];
  200. }
  201. else
  202. {
  203. valuesHtml = valuesHtml.replace("%opformat%", "c");
  204. sendBypass = opCodes[0];
  205. }
  206. valuesHtml = valuesHtml.replace("%opcodes%", sendBypass);
  207. String editorsHtml = "";
  208. if (format == null)
  209. {
  210. valuesHtml = valuesHtml.replace("%format%", "");
  211. editorsHtml = "";
  212. }
  213. else
  214. {
  215. valuesHtml = valuesHtml.replace("%format%", format);
  216. sendBypass += " " + format;
  217. String editorTemplate = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/admin/pforge/inc/editor.htm");
  218. if (editorTemplate != null)
  219. {
  220. StringBuilder singleCharSequence = new StringBuilder(1);
  221. singleCharSequence.append(' ');
  222. for (int chIdx = 0; chIdx < format.length(); ++chIdx)
  223. {
  224. char ch = format.charAt(chIdx);
  225. singleCharSequence.setCharAt(0, ch);
  226. editorsHtml += editorTemplate.replace("%format%", singleCharSequence).replace("%editor_index%", String.valueOf(chIdx));
  227. sendBypass += " $v" + chIdx;
  228. }
  229. }
  230. else
  231. {
  232. editorsHtml = "";
  233. }
  234. }
  235. valuesHtml = valuesHtml.replace("%editors%", editorsHtml);
  236. valuesHtml = valuesHtml.replace("%send_bypass%", sendBypass);
  237. activeChar.sendPacket(new NpcHtmlMessage(valuesHtml));
  238. }
  239. @Override
  240. public boolean useAdminCommand(String command, L2PcInstance activeChar)
  241. {
  242. if (command.equals("admin_forge"))
  243. {
  244. showMainPage(activeChar);
  245. }
  246. else if (command.startsWith("admin_forge_values "))
  247. {
  248. try
  249. {
  250. StringTokenizer st = new StringTokenizer(command);
  251. st.nextToken(); // skip command token
  252. if (!st.hasMoreTokens())
  253. {
  254. showValuesUsage(activeChar);
  255. return false;
  256. }
  257. String[] opCodes = getOpCodes(st);
  258. if (!validateOpCodes(opCodes))
  259. {
  260. activeChar.sendMessage("Invalid op codes!");
  261. showValuesUsage(activeChar);
  262. return false;
  263. }
  264. String format = null;
  265. if (st.hasMoreTokens())
  266. {
  267. format = st.nextToken();
  268. if (!validateFormat(format))
  269. {
  270. activeChar.sendMessage("Format invalid!");
  271. showValuesUsage(activeChar);
  272. return false;
  273. }
  274. }
  275. showValuesPage(activeChar, opCodes, format);
  276. }
  277. catch (Exception e)
  278. {
  279. e.printStackTrace();
  280. showValuesUsage(activeChar);
  281. return false;
  282. }
  283. }
  284. else if (command.startsWith("admin_forge_send "))
  285. {
  286. try
  287. {
  288. StringTokenizer st = new StringTokenizer(command);
  289. st.nextToken(); // skip command token
  290. if (!st.hasMoreTokens())
  291. {
  292. showSendUsage(activeChar, null, null);
  293. return false;
  294. }
  295. String method = st.nextToken();
  296. if (!validateMethod(method))
  297. {
  298. activeChar.sendMessage("Invalid method!");
  299. showSendUsage(activeChar, null, null);
  300. return false;
  301. }
  302. String[] opCodes = st.nextToken().split(";");
  303. if (!validateOpCodes(opCodes))
  304. {
  305. activeChar.sendMessage("Invalid op codes!");
  306. showSendUsage(activeChar, null, null);
  307. return false;
  308. }
  309. String format = null;
  310. if (st.hasMoreTokens())
  311. {
  312. format = st.nextToken();
  313. if (!validateFormat(format))
  314. {
  315. activeChar.sendMessage("Format invalid!");
  316. showSendUsage(activeChar, null, null);
  317. return false;
  318. }
  319. }
  320. AdminForgePacket afp = null;
  321. ByteBuffer bb = null;
  322. for (int i = 0; i < opCodes.length; ++i)
  323. {
  324. char type;
  325. if (i == 0)
  326. {
  327. type = 'c';
  328. }
  329. else if (i == 1)
  330. {
  331. type = 'h';
  332. }
  333. else
  334. {
  335. type = 'd';
  336. }
  337. if (method.equals("sc") || method.equals("sb"))
  338. {
  339. if (afp == null)
  340. {
  341. afp = new AdminForgePacket();
  342. }
  343. afp.addPart((byte) type, opCodes[i]);
  344. }
  345. else
  346. {
  347. if (bb == null)
  348. {
  349. bb = ByteBuffer.allocate(32767);
  350. }
  351. write((byte) type, opCodes[i], bb);
  352. }
  353. }
  354. if (format != null)
  355. {
  356. for (int i = 0; i < format.length(); ++i)
  357. {
  358. if (!st.hasMoreTokens())
  359. {
  360. activeChar.sendMessage("Not enough values!");
  361. showSendUsage(activeChar, null, null);
  362. return false;
  363. }
  364. L2Object target = null;
  365. L2BoatInstance boat = null;
  366. String value = st.nextToken();
  367. switch (value)
  368. {
  369. case "$oid":
  370. value = String.valueOf(activeChar.getObjectId());
  371. break;
  372. case "$boid":
  373. boat = activeChar.getBoat();
  374. if (boat != null)
  375. {
  376. value = String.valueOf(boat.getObjectId());
  377. }
  378. else
  379. {
  380. value = "0";
  381. }
  382. break;
  383. case "$title":
  384. value = activeChar.getTitle();
  385. break;
  386. case "$name":
  387. value = activeChar.getName();
  388. break;
  389. case "$x":
  390. value = String.valueOf(activeChar.getX());
  391. break;
  392. case "$y":
  393. value = String.valueOf(activeChar.getY());
  394. break;
  395. case "$z":
  396. value = String.valueOf(activeChar.getZ());
  397. break;
  398. case "$heading":
  399. value = String.valueOf(activeChar.getHeading());
  400. break;
  401. case "$toid":
  402. value = String.valueOf(activeChar.getTargetId());
  403. break;
  404. case "$tboid":
  405. target = activeChar.getTarget();
  406. if ((target != null) && (target instanceof L2Playable))
  407. {
  408. boat = ((L2Playable) target).getActingPlayer().getBoat();
  409. if (boat != null)
  410. {
  411. value = String.valueOf(boat.getObjectId());
  412. }
  413. else
  414. {
  415. value = "0";
  416. }
  417. }
  418. break;
  419. case "$ttitle":
  420. target = activeChar.getTarget();
  421. if ((target != null) && (target instanceof L2Character))
  422. {
  423. value = String.valueOf(((L2Character) target).getTitle());
  424. }
  425. else
  426. {
  427. value = "";
  428. }
  429. break;
  430. case "$tname":
  431. target = activeChar.getTarget();
  432. if (target != null)
  433. {
  434. value = String.valueOf(target.getName());
  435. }
  436. else
  437. {
  438. value = "";
  439. }
  440. break;
  441. case "$tx":
  442. target = activeChar.getTarget();
  443. if (target != null)
  444. {
  445. value = String.valueOf(target.getX());
  446. }
  447. else
  448. {
  449. value = "0";
  450. }
  451. break;
  452. case "$ty":
  453. target = activeChar.getTarget();
  454. if (target != null)
  455. {
  456. value = String.valueOf(target.getY());
  457. }
  458. else
  459. {
  460. value = "0";
  461. }
  462. break;
  463. case "$tz":
  464. target = activeChar.getTarget();
  465. if (target != null)
  466. {
  467. value = String.valueOf(target.getZ());
  468. }
  469. else
  470. {
  471. value = "0";
  472. }
  473. break;
  474. case "$theading":
  475. target = activeChar.getTarget();
  476. if (target != null)
  477. {
  478. value = String.valueOf(target.getHeading());
  479. }
  480. else
  481. {
  482. value = "0";
  483. }
  484. break;
  485. }
  486. if (method.equals("sc") || method.equals("sb"))
  487. {
  488. if (afp != null)
  489. {
  490. afp.addPart((byte) format.charAt(i), value);
  491. }
  492. }
  493. else
  494. {
  495. write((byte) format.charAt(i), value, bb);
  496. }
  497. }
  498. }
  499. if (method.equals("sc"))
  500. {
  501. activeChar.sendPacket(afp);
  502. }
  503. else if (method.equals("sb"))
  504. {
  505. activeChar.broadcastPacket(afp);
  506. }
  507. else if (bb != null)
  508. {
  509. bb.flip();
  510. L2GameClientPacket p = (L2GameClientPacket) GameServer.gameServer.getL2GamePacketHandler().handlePacket(bb, activeChar.getClient());
  511. if (p != null)
  512. {
  513. p.setBuffers(bb, activeChar.getClient(), new NioNetStringBuffer(2000));
  514. if (p.read())
  515. {
  516. ThreadPoolManager.getInstance().executePacket(p);
  517. }
  518. }
  519. }
  520. showValuesPage(activeChar, opCodes, format);
  521. }
  522. catch (Exception e)
  523. {
  524. e.printStackTrace();
  525. showSendUsage(activeChar, null, null);
  526. return false;
  527. }
  528. }
  529. return true;
  530. }
  531. private boolean write(byte b, String string, ByteBuffer buf)
  532. {
  533. if ((b == 'C') || (b == 'c'))
  534. {
  535. buf.put(Byte.decode(string));
  536. return true;
  537. }
  538. else if ((b == 'D') || (b == 'd'))
  539. {
  540. buf.putInt(Integer.decode(string));
  541. return true;
  542. }
  543. else if ((b == 'H') || (b == 'h'))
  544. {
  545. buf.putShort(Short.decode(string));
  546. return true;
  547. }
  548. else if ((b == 'F') || (b == 'f'))
  549. {
  550. buf.putDouble(Double.parseDouble(string));
  551. return true;
  552. }
  553. else if ((b == 'S') || (b == 's'))
  554. {
  555. final int len = string.length();
  556. for (int i = 0; i < len; i++)
  557. {
  558. buf.putChar(string.charAt(i));
  559. }
  560. buf.putChar('\000');
  561. return true;
  562. }
  563. else if ((b == 'B') || (b == 'b') || (b == 'X') || (b == 'x'))
  564. {
  565. buf.put(new BigInteger(string).toByteArray());
  566. return true;
  567. }
  568. else if ((b == 'Q') || (b == 'q'))
  569. {
  570. buf.putLong(Long.decode(string));
  571. return true;
  572. }
  573. return false;
  574. }
  575. @Override
  576. public String[] getAdminCommandList()
  577. {
  578. return ADMIN_COMMANDS;
  579. }
  580. }