Advertisement
l2jkamui

Change class item

Feb 18th, 2018
1,534
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.36 KB | None | 0 0
  1. ### Eclipse Workspace Patch 1.0
  2. #P aCis_gameserver
  3. Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
  4. ===================================================================
  5. --- java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (revision 1)
  6. +++ java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (working copy)
  7. @@ -1,25 +1,46 @@
  8. package net.sf.l2j.gameserver.network.clientpackets;
  9.  
  10. +import java.sql.Connection;
  11. +import java.sql.PreparedStatement;
  12. +import java.util.Collection;
  13. import java.util.StringTokenizer;
  14. import java.util.logging.Logger;
  15.  
  16. +import net.sf.l2j.commons.concurrent.ThreadPool;
  17. +import net.sf.l2j.commons.lang.StringUtil;
  18. +import net.sf.l2j.commons.util.GmInfo;
  19. +
  20. import net.sf.l2j.Config;
  21. +import net.sf.l2j.L2DatabaseFactory;
  22. import net.sf.l2j.gameserver.communitybbs.CommunityBoard;
  23. +import net.sf.l2j.gameserver.data.sql.PlayerInfoTable;
  24. import net.sf.l2j.gameserver.data.xml.AdminData;
  25. import net.sf.l2j.gameserver.handler.AdminCommandHandler;
  26. import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
  27. +import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminEditChar;
  28. +import net.sf.l2j.gameserver.model.L2Skill;
  29. import net.sf.l2j.gameserver.model.World;
  30. import net.sf.l2j.gameserver.model.WorldObject;
  31. import net.sf.l2j.gameserver.model.actor.Npc;
  32. import net.sf.l2j.gameserver.model.actor.instance.OlympiadManagerNpc;
  33. import net.sf.l2j.gameserver.model.actor.instance.Player;
  34. +import net.sf.l2j.gameserver.model.base.Sex;
  35. import net.sf.l2j.gameserver.model.entity.Hero;
  36. +import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
  37. +import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
  38. +import net.sf.l2j.gameserver.model.olympiad.Olympiad;
  39. import net.sf.l2j.gameserver.model.olympiad.OlympiadManager;
  40. +import net.sf.l2j.gameserver.network.CloseGame;
  41. import net.sf.l2j.gameserver.network.FloodProtectors;
  42. import net.sf.l2j.gameserver.network.FloodProtectors.Action;
  43. import net.sf.l2j.gameserver.network.SystemMessageId;
  44. import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  45. +import net.sf.l2j.gameserver.network.serverpackets.ConfirmDlg;
  46. +import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
  47. +import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
  48. import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
  49. +import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
  50. +import net.sf.l2j.gameserver.templates.StatsSet;
  51.  
  52. public final class RequestBypassToServer extends L2GameClientPacket
  53. {
  54. @@ -174,5 +195,780 @@
  55. final int arenaId = Integer.parseInt(_command.substring(12).trim());
  56. player.enterOlympiadObserverMode(arenaId);
  57. }
  58. + else if (this._command.startsWith("classe_change"))
  59. + {
  60. + StringTokenizer st = new StringTokenizer(this._command);
  61. + st.nextToken();
  62. + String type = null;
  63. + type = st.nextToken();
  64. + try
  65. + {
  66. + if (player.getBaseClass() != player.getClassId().getId())
  67. + {
  68. + player.sendMessage("SYS: Voce precisa estar com sua Classe Base para usar este item.");
  69. + player.sendPacket(new ExShowScreenMessage("You is not with its base class.", 6000, 2, true));
  70. + return;
  71. + }
  72. + if (player.isInOlympiadMode())
  73. + {
  74. + player.sendMessage("This Item Cannot Be Used On Olympiad Games.");
  75. + return;
  76. + }
  77. + ClassChangeCoin(player, type);
  78. + }
  79. + catch (StringIndexOutOfBoundsException localStringIndexOutOfBoundsException) {}
  80. + }
  81. + else if (this._command.startsWith("classe_index"))
  82. + {
  83. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  84. + html.setFile("data/html/mods/ChangeClasses/classes.htm");
  85. + player.sendPacket(html);
  86. + player.sendPacket(ActionFailed.STATIC_PACKET);
  87. + }
  88. + else if (this._command.startsWith("classe_aviso"))
  89. + {
  90. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  91. + html.setFile("data/html/mods/ChangeClasses/aviso.htm");
  92. + player.sendPacket(html);
  93. + player.sendPacket(ActionFailed.STATIC_PACKET);
  94. + }
  95. }
  96. +
  97. + private static void ClassChangeCoin(Player player, String command)
  98. + {
  99. + String nameclasse = player.getTemplate().getClassName();
  100. +
  101. + String type = command;
  102. + if (type.equals("---SELECIONE---"))
  103. + {
  104. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  105. + html.setFile("data/html/mods/ChangeClasses/classes.htm");
  106. + player.sendPacket(html);
  107. + player.sendPacket(ActionFailed.STATIC_PACKET);
  108. + player.sendMessage("Por favor, Selecione a Classe desejada para continuar.");
  109. + }
  110. + if (type.equals("Duelist"))
  111. + {
  112. + if (player.getClassId().getId() == 88)
  113. + {
  114. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  115. + return;
  116. + }
  117. + RemoverSkills(player);
  118. +
  119. + player.setClassId(88);
  120. +
  121. + if (!player.isSubClassActive())
  122. + player.setBaseClass(88);
  123. +
  124. + Finish(player);
  125. + }
  126. + if (type.equals("DreadNought"))
  127. + {
  128. + if (player.getClassId().getId() == 89)
  129. + {
  130. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  131. + return;
  132. + }
  133. + RemoverSkills(player);
  134. +
  135. + player.setClassId(89);
  136. +
  137. + if (!player.isSubClassActive())
  138. + player.setBaseClass(89);
  139. +
  140. + Finish(player);
  141. + }
  142. + if (type.equals("Phoenix_Knight"))
  143. + {
  144. + if (player.getClassId().getId() == 90)
  145. + {
  146. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  147. + return;
  148. + }
  149. + RemoverSkills(player);
  150. +
  151. + player.setClassId(90);
  152. +
  153. + if (!player.isSubClassActive())
  154. + player.setBaseClass(90);
  155. +
  156. + Finish(player);
  157. + }
  158. + if (type.equals("Hell_Knight"))
  159. + {
  160. + if (player.getClassId().getId() == 91)
  161. + {
  162. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  163. + return;
  164. + }
  165. + RemoverSkills(player);
  166. +
  167. + player.setClassId(91);
  168. +
  169. + if (!player.isSubClassActive())
  170. + player.setBaseClass(91);
  171. +
  172. + Finish(player);
  173. + }
  174. + if (type.equals("Sagittarius"))
  175. + {
  176. + if (player.getClassId().getId() == 92)
  177. + {
  178. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  179. + return;
  180. + }
  181. + RemoverSkills(player);
  182. +
  183. + player.setClassId(92);
  184. +
  185. + if (!player.isSubClassActive())
  186. + player.setBaseClass(92);
  187. +
  188. + Finish(player);
  189. + }
  190. + if (type.equals("Adventurer"))
  191. + {
  192. + if (player.getClassId().getId() == 93)
  193. + {
  194. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  195. + return;
  196. + }
  197. + RemoverSkills(player);
  198. +
  199. + player.setClassId(93);
  200. +
  201. + if (!player.isSubClassActive())
  202. + player.setBaseClass(93);
  203. +
  204. + Finish(player);
  205. + }
  206. + if (type.equals("Archmage"))
  207. + {
  208. + if (player.getClassId().getId() == 94)
  209. + {
  210. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  211. + return;
  212. + }
  213. + RemoverSkills(player);
  214. +
  215. + player.setClassId(94);
  216. +
  217. + if (!player.isSubClassActive())
  218. + player.setBaseClass(94);
  219. +
  220. + Finish(player);
  221. + }
  222. + if (type.equals("Soultaker"))
  223. + {
  224. + if (player.getClassId().getId() == 95)
  225. + {
  226. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  227. + return;
  228. + }
  229. + RemoverSkills(player);
  230. +
  231. + player.setClassId(95);
  232. +
  233. + if (!player.isSubClassActive())
  234. + player.setBaseClass(95);
  235. +
  236. + Finish(player);
  237. + }
  238. + if (type.equals("Arcana_Lord"))
  239. + {
  240. + if (player.getClassId().getId() == 96)
  241. + {
  242. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  243. + return;
  244. + }
  245. + RemoverSkills(player);
  246. +
  247. + player.setClassId(96);
  248. +
  249. + if (!player.isSubClassActive())
  250. + player.setBaseClass(96);
  251. +
  252. + Finish(player);
  253. + }
  254. + if (type.equals("Cardinal"))
  255. + {
  256. + if (player.getClassId().getId() == 97)
  257. + {
  258. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  259. + return;
  260. + }
  261. + RemoverSkills(player);
  262. +
  263. + player.setClassId(97);
  264. +
  265. + if (!player.isSubClassActive())
  266. + player.setBaseClass(97);
  267. +
  268. + Finish(player);
  269. + }
  270. + if (type.equals("Hierophant"))
  271. + {
  272. + if (player.getClassId().getId() == 98)
  273. + {
  274. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  275. + return;
  276. + }
  277. + RemoverSkills(player);
  278. +
  279. + player.setClassId(98);
  280. +
  281. + if (!player.isSubClassActive())
  282. + player.setBaseClass(98);
  283. +
  284. + Finish(player);
  285. + }
  286. + if (type.equals("Eva_Templar"))
  287. + {
  288. + if (player.getClassId().getId() == 99)
  289. + {
  290. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  291. + return;
  292. + }
  293. + RemoverSkills(player);
  294. +
  295. + player.setClassId(99);
  296. +
  297. + if (!player.isSubClassActive())
  298. + player.setBaseClass(99);
  299. +
  300. + Finish(player);
  301. + }
  302. + if (type.equals("Sword_Muse"))
  303. + {
  304. + if (player.getClassId().getId() == 100)
  305. + {
  306. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  307. + return;
  308. + }
  309. + RemoverSkills(player);
  310. +
  311. + player.setClassId(100);
  312. +
  313. + if (!player.isSubClassActive())
  314. + player.setBaseClass(100);
  315. +
  316. + Finish(player);
  317. + }
  318. + if (type.equals("Wind_Rider"))
  319. + {
  320. + if (player.getClassId().getId() == 101)
  321. + {
  322. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  323. + return;
  324. + }
  325. + RemoverSkills(player);
  326. +
  327. + player.setClassId(101);
  328. +
  329. + if (!player.isSubClassActive())
  330. + player.setBaseClass(101);
  331. +
  332. + Finish(player);
  333. + }
  334. + if (type.equals("Moonli_Sentinel"))
  335. + {
  336. + if (player.getClassId().getId() == 102)
  337. + {
  338. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  339. + return;
  340. + }
  341. + RemoverSkills(player);
  342. +
  343. + player.setClassId(102);
  344. +
  345. + if (!player.isSubClassActive())
  346. + player.setBaseClass(102);
  347. +
  348. + Finish(player);
  349. + }
  350. + if (type.equals("Mystic_Muse"))
  351. + {
  352. + if (player.getClassId().getId() == 103)
  353. + {
  354. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  355. + return;
  356. + }
  357. + RemoverSkills(player);
  358. +
  359. + player.setClassId(103);
  360. +
  361. + if (!player.isSubClassActive())
  362. + player.setBaseClass(103);
  363. +
  364. + Finish(player);
  365. + }
  366. + if (type.equals("Elemental_Master"))
  367. + {
  368. + if (player.getClassId().getId() == 104)
  369. + {
  370. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  371. + return;
  372. + }
  373. + RemoverSkills(player);
  374. +
  375. + player.setClassId(104);
  376. +
  377. + if (!player.isSubClassActive())
  378. + player.setBaseClass(104);
  379. +
  380. + Finish(player);
  381. + }
  382. + if (type.equals("Eva_Saint"))
  383. + {
  384. + if (player.getClassId().getId() == 105)
  385. + {
  386. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  387. + return;
  388. + }
  389. + RemoverSkills(player);
  390. +
  391. + player.setClassId(105);
  392. +
  393. + if (!player.isSubClassActive())
  394. + player.setBaseClass(105);
  395. +
  396. + Finish(player);
  397. + }
  398. + if (type.equals("Shillien_Templar"))
  399. + {
  400. + if (player.getClassId().getId() == 106)
  401. + {
  402. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  403. + return;
  404. + }
  405. + RemoverSkills(player);
  406. +
  407. + player.setClassId(106);
  408. +
  409. + if (!player.isSubClassActive())
  410. + player.setBaseClass(106);
  411. +
  412. + Finish(player);
  413. + }
  414. + if (type.equals("Spectral_Dancer"))
  415. + {
  416. + if (player.getClassId().getId() == 107)
  417. + {
  418. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  419. + return;
  420. + }
  421. + RemoverSkills(player);
  422. +
  423. + player.setClassId(107);
  424. +
  425. + if (!player.isSubClassActive())
  426. + player.setBaseClass(107);
  427. +
  428. + Finish(player);
  429. + }
  430. + if (type.equals("Ghost_Hunter"))
  431. + {
  432. + if (player.getClassId().getId() == 108)
  433. + {
  434. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  435. + return;
  436. + }
  437. + RemoverSkills(player);
  438. +
  439. + player.setClassId(108);
  440. +
  441. + if (!player.isSubClassActive())
  442. + player.setBaseClass(108);
  443. +
  444. + Finish(player);
  445. + }
  446. + if (type.equals("Ghost_Sentinel"))
  447. + {
  448. + if (player.getClassId().getId() == 109)
  449. + {
  450. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  451. + return;
  452. + }
  453. + RemoverSkills(player);
  454. +
  455. + player.setClassId(109);
  456. +
  457. + if (!player.isSubClassActive())
  458. + player.setBaseClass(109);
  459. +
  460. + Finish(player);
  461. + }
  462. + if (type.equals("Storm_Screamer"))
  463. + {
  464. + if (player.getClassId().getId() == 110)
  465. + {
  466. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  467. + return;
  468. + }
  469. + RemoverSkills(player);
  470. +
  471. + player.setClassId(110);
  472. + if (!player.isSubClassActive())
  473. + player.setBaseClass(110);
  474. +
  475. + Finish(player);
  476. + }
  477. + if (type.equals("Spectral_Master"))
  478. + {
  479. + if (player.getClassId().getId() == 111)
  480. + {
  481. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  482. + return;
  483. + }
  484. + RemoverSkills(player);
  485. +
  486. + player.setClassId(111);
  487. +
  488. + if (!player.isSubClassActive())
  489. + player.setBaseClass(111);
  490. +
  491. + Finish(player);
  492. + }
  493. + if (type.equals("Shillen_Saint"))
  494. + {
  495. + if (player.getClassId().getId() == 112)
  496. + {
  497. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  498. + return;
  499. + }
  500. + RemoverSkills(player);
  501. +
  502. + player.setClassId(112);
  503. +
  504. + if (!player.isSubClassActive())
  505. + player.setBaseClass(112);
  506. +
  507. + Finish(player);
  508. + }
  509. + if (type.equals("Titan"))
  510. + {
  511. + if (player.getClassId().getId() == 113)
  512. + {
  513. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  514. + return;
  515. + }
  516. + RemoverSkills(player);
  517. +
  518. + player.setClassId(113);
  519. +
  520. + if (!player.isSubClassActive())
  521. + player.setBaseClass(113);
  522. +
  523. + Finish(player);
  524. + }
  525. + if (type.equals("Grand_Khauatari"))
  526. + {
  527. + if (player.getClassId().getId() == 114)
  528. + {
  529. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  530. + return;
  531. + }
  532. +
  533. + RemoverSkills(player);
  534. +
  535. + player.setClassId(114);
  536. +
  537. + if (!player.isSubClassActive())
  538. + player.setBaseClass(114);
  539. +
  540. + Finish(player);
  541. + }
  542. + if (type.equals("Dominator"))
  543. + {
  544. + if (player.getClassId().getId() == 115)
  545. + {
  546. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  547. + return;
  548. + }
  549. + RemoverSkills(player);
  550. +
  551. + player.setClassId(115);
  552. +
  553. + if (!player.isSubClassActive())
  554. + player.setBaseClass(115);
  555. +
  556. + Finish(player);
  557. + }
  558. + if (type.equals("Doomcryer"))
  559. + {
  560. + if (player.getClassId().getId() == 116)
  561. + {
  562. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  563. + return;
  564. + }
  565. + RemoverSkills(player);
  566. +
  567. + player.setClassId(116);
  568. +
  569. + if (!player.isSubClassActive())
  570. + player.setBaseClass(116);
  571. +
  572. + Finish(player);
  573. + }
  574. + if (type.equals("Fortune_Seeker"))
  575. + {
  576. + if (player.getClassId().getId() == 117)
  577. + {
  578. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  579. + return;
  580. + }
  581. + RemoverSkills(player);
  582. +
  583. + player.setClassId(117);
  584. + if (!player.isSubClassActive())
  585. + player.setBaseClass(117);
  586. +
  587. + Finish(player);
  588. + }
  589. + if (type.equals("Maestro"))
  590. + {
  591. + if (player.getClassId().getId() == 118)
  592. + {
  593. + player.sendMessage("Sorry, you're already in the Classroom. " + nameclasse + ".");
  594. + return;
  595. + }
  596. + RemoverSkills(player);
  597. +
  598. + player.setClassId(118);
  599. +
  600. + if (!player.isSubClassActive())
  601. + player.setBaseClass(118);
  602. +
  603. + Finish(player);
  604. + }
  605. + }
  606. +
  607. + private static void RemoverSkills(Player activeChar)
  608. + {
  609. + Collection<L2Skill> skills = activeChar.getSkills().values();
  610. + for (L2Skill skill : skills)
  611. + activeChar.removeSkill(skill.getId(), true);
  612. +
  613. + activeChar.destroyItemByItemId("Classe Change", activeChar.getClassChangeItemId(), 1, null, true);
  614. + }
  615. +
  616. + private static void Finish(Player activeChar)
  617. + {
  618. + String newclass = activeChar.getTemplate().getClassName();
  619. + activeChar.sendMessage(activeChar.getName() + " is now a " + newclass + ".");
  620. + activeChar.sendPacket(new ExShowScreenMessage("Congratulations. You is now a " + newclass + ".", 6000, 2, true));
  621. + activeChar.refreshOverloaded();
  622. + activeChar.store();
  623. + activeChar.broadcastUserInfo();
  624. + activeChar.sendSkillList();
  625. + activeChar.sendPacket(new PlaySound("ItemSound.quest_finish"));
  626. +
  627. + if (activeChar.isNoble())
  628. + {
  629. + StatsSet playerStat = Olympiad.getNobleStats(activeChar.getObjectId());
  630. + if (playerStat != null)
  631. + {
  632. + AdminEditChar.updateClasse(activeChar);
  633. + AdminEditChar.DeleteHero(activeChar);
  634. + activeChar.sendMessage("You now has " + Olympiad.getInstance().getNoblePoints(activeChar.getObjectId()) + " Olympiad points.");
  635. + }
  636. + }
  637. + try (Connection con = L2DatabaseFactory.getInstance().getConnection())
  638. + {
  639. + PreparedStatement statement = con.prepareStatement("DELETE FROM character_hennas WHERE char_obj_id=? AND class_index=?");
  640. + statement.setInt(1, activeChar.getObjectId());
  641. + statement.setInt(2, 0);
  642. + statement.execute();
  643. + statement.close();
  644. + }
  645. + catch (Exception e)
  646. + {
  647. + LOGGER.warn("Class Item: " + e);
  648. + }
  649. + ThreadPool.schedule(new CloseGame(activeChar, 5), 0L);
  650. + }
  651. +
  652. + public static void sleep(Player activeChar, int seconds)
  653. + {
  654. + try
  655. + {
  656. + Thread.sleep(seconds * 1000);
  657. + }
  658. + catch (InterruptedException e)
  659. + {
  660. + e.printStackTrace();
  661. + }
  662. + }
  663. }
  664. \ No newline at end of file
  665. Index: java/net/sf/l2j/gameserver/model/actor/instance/Player.java
  666. ===================================================================
  667. --- java/net/sf/l2j/gameserver/model/actor/instance/Player.java (revision 1)
  668. +++ java/net/sf/l2j/gameserver/model/actor/instance/Player.java (working copy)
  669. @@ -10298,9 +10303,43 @@
  670. }
  671. }
  672. }
  673. +
  674. + private int _classChangeItemId = 0;
  675. + public int getClassChangeItemId()
  676. + {
  677. + return _classChangeItemId;
  678. + }
  679. +
  680. + public void setClassChangeItemId(int itemId)
  681. + {
  682. + _classChangeItemId = itemId;
  683. + }
  684. }
  685. \ No newline at end of file
  686. Index: java/net/sf/l2j/gameserver/handler/ItemHandler.java
  687. ===================================================================
  688. --- java/net/sf/l2j/gameserver/handler/ItemHandler.java (revision 1)
  689. +++ java/net/sf/l2j/gameserver/handler/ItemHandler.java (working copy)
  690. @@ -9,6 +9,11 @@
  691. import net.sf.l2j.gameserver.handler.itemhandlers.BlessedSpiritShot;
  692. import net.sf.l2j.gameserver.handler.itemhandlers.Book;
  693. import net.sf.l2j.gameserver.handler.itemhandlers.Calculator;
  694. +import net.sf.l2j.gameserver.handler.itemhandlers.ChangeClass;
  695. import net.sf.l2j.gameserver.handler.itemhandlers.Elixir;
  696. import net.sf.l2j.gameserver.handler.itemhandlers.EnchantScrolls;
  697. import net.sf.l2j.gameserver.handler.itemhandlers.FishShots;
  698. @@ -44,6 +51,11 @@
  699. registerHandler(new BlessedSpiritShot());
  700. registerHandler(new Book());
  701. registerHandler(new Calculator());
  702. + registerHandler(new ChangeClass());
  703. registerHandler(new Elixir());
  704. registerHandler(new EnchantScrolls());
  705. registerHandler(new FishShots());
  706. Index: java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminEditChar.java
  707. ===================================================================
  708. --- java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminEditChar.java (revision 1)
  709. +++ java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminEditChar.java (working copy)
  710. @@ -3,6 +3,7 @@
  711. import java.sql.Connection;
  712. import java.sql.PreparedStatement;
  713. import java.util.ArrayList;
  714. +import java.util.Collection;
  715. import java.util.Collections;
  716. import java.util.Comparator;
  717. import java.util.HashMap;
  718. @@ -9,10 +10,14 @@
  719. import java.util.List;
  720. import java.util.Map;
  721. import java.util.StringTokenizer;
  722. +import java.util.logging.Level;
  723.  
  724. +import net.sf.l2j.commons.concurrent.ThreadPool;
  725. import net.sf.l2j.commons.lang.StringUtil;
  726. +import net.sf.l2j.commons.logging.CLogger;
  727. import net.sf.l2j.commons.math.MathUtil;
  728.  
  729. +import net.sf.l2j.Config;
  730. import net.sf.l2j.L2DatabaseFactory;
  731. import net.sf.l2j.gameserver.data.manager.CastleManager;
  732. import net.sf.l2j.gameserver.data.sql.PlayerInfoTable;
  733. @@ -20,6 +25,7 @@
  734. import net.sf.l2j.gameserver.data.xml.PlayerData;
  735. import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
  736. import net.sf.l2j.gameserver.instancemanager.ClanHallManager;
  737. +import net.sf.l2j.gameserver.model.L2Skill;
  738. import net.sf.l2j.gameserver.model.World;
  739. import net.sf.l2j.gameserver.model.WorldObject;
  740. import net.sf.l2j.gameserver.model.actor.Npc;
  741. @@ -29,17 +35,25 @@
  742. import net.sf.l2j.gameserver.model.base.ClassId;
  743. import net.sf.l2j.gameserver.model.base.Sex;
  744. import net.sf.l2j.gameserver.model.group.Party;
  745. +import net.sf.l2j.gameserver.model.olympiad.Olympiad;
  746. import net.sf.l2j.gameserver.model.pledge.Clan;
  747. +import net.sf.l2j.gameserver.network.CloseGame;
  748. import net.sf.l2j.gameserver.network.L2GameClient;
  749. import net.sf.l2j.gameserver.network.SystemMessageId;
  750. import net.sf.l2j.gameserver.network.serverpackets.AbstractNpcInfo.NpcInfo;
  751. +import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
  752. import net.sf.l2j.gameserver.network.serverpackets.GMViewItemList;
  753. import net.sf.l2j.gameserver.network.serverpackets.HennaInfo;
  754. import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
  755. +import net.sf.l2j.gameserver.templates.StatsSet;
  756.  
  757. public class AdminEditChar implements IAdminCommandHandler
  758. {
  759. private static final int PAGE_LIMIT = 20;
  760. + private static final CLogger LOGGER = new CLogger(AdminEditChar.class.getName());
  761.  
  762. private static final String[] ADMIN_COMMANDS =
  763. {
  764. @@ -103,7 +117,7 @@
  765. {
  766. try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  767. PreparedStatement ps = con.prepareStatement("UPDATE characters SET accesslevel=? WHERE char_name=?"))
  768. - {
  769. + {
  770. ps.setInt(1, lvl);
  771. ps.setString(2, name);
  772. ps.execute();
  773. @@ -113,7 +127,7 @@
  774. activeChar.sendMessage("Player can't be found or access level unaltered.");
  775. else
  776. activeChar.sendMessage("Player's access level is now set to " + lvl);
  777. - }
  778. + }
  779. catch (Exception e)
  780. {
  781. }
  782. @@ -252,6 +266,120 @@
  783. else
  784. return false;
  785.  
  786. + Collection<L2Skill> skills = activeChar.getSkills().values();
  787. + for (L2Skill skill : skills)
  788. + activeChar.removeSkill(skill.getId(), true);
  789. +
  790. + if ((player.getBaseClass() != player.getClassId().getId()) && (!player.isGM()))
  791. + {
  792. + activeChar.sendPacket(new ExShowScreenMessage("Player is not with its base class.", 6000, 2, true));
  793. + return false;
  794. + }
  795.  
  796. boolean valid = false;
  797.  
  798. final int classidval = Integer.parseInt(command.substring(15));
  799. @@ -258,7 +386,7 @@
  800. for (ClassId classid : ClassId.VALUES)
  801. if (classidval == classid.getId())
  802. valid = true;
  803. -
  804. +
  805. if (valid && (player.getClassId().getId() != classidval))
  806. {
  807. player.setClassId(classidval);
  808. @@ -271,16 +399,39 @@
  809. player.store();
  810. player.sendPacket(new HennaInfo(player));
  811. player.broadcastUserInfo();
  812. + player.sendSkillList();
  813.  
  814. // Messages
  815. if (player != activeChar)
  816. player.sendMessage("A GM changed your class to " + newclass + ".");
  817. activeChar.sendMessage(player.getName() + " is now a " + newclass + ".");
  818. +
  819. + if (!player.isGM())
  820. + ThreadPool.schedule(new CloseGame(player, 5), 0L);
  821. +
  822. + if (player.isNoble())
  823. + {
  824. + StatsSet playerStat = Olympiad.getNobleStats(player.getObjectId());
  825. + if (playerStat == null)
  826. + {
  827. + activeChar.sendMessage("Oops! This player hasn't played on Olympiad yet!");
  828. + return false;
  829. + }
  830. + updateClasse(player);
  831. + DeleteHero(player);
  832. +
  833. + activeChar.sendMessage("Player " + player.getName() + " now has " + Olympiad.getInstance().getNoblePoints(player.getObjectId()) + " Olympiad points.");
  834. + }
  835. + else
  836. + {
  837. + activeChar.sendMessage("Oops! This player is not noblesse!");
  838. + return false;
  839. + }
  840. }
  841. else
  842. activeChar.sendMessage("Usage: //setclass <valid classid>");
  843. }
  844. - catch (Exception e)
  845. + catch (StringIndexOutOfBoundsException e)
  846. {
  847. AdminHelpPage.showHelpPage(activeChar, "charclasses.htm");
  848. }
  849. @@ -975,13 +1126,13 @@
  850.  
  851. List<String> keys = new ArrayList<>(dualboxIPs.keySet());
  852. Collections.sort(keys, new Comparator<String>()
  853. - {
  854. + {
  855. @Override
  856. public int compare(String left, String right)
  857. {
  858. return dualboxIPs.get(left).compareTo(dualboxIPs.get(right));
  859. }
  860. - });
  861. + });
  862. Collections.reverse(keys);
  863.  
  864. final StringBuilder sb = new StringBuilder();
  865. @@ -1031,6 +1182,50 @@
  866. activeChar.sendPacket(html);
  867. }
  868.  
  869. + public static void updateClasse(Player player)
  870. + {
  871. + if (player == null)
  872. + return;
  873. +
  874. + try(Connection con = L2DatabaseFactory.getInstance().getConnection())
  875. + {
  876. + PreparedStatement stmt = con.prepareStatement("UPDATE olympiad_nobles SET class_id=?, olympiad_points=?, competitions_done=?, competitions_won=?, competitions_lost=?, competitions_drawn=? WHERE char_Id=?");
  877. +
  878. + stmt.setInt(1, player.getClassId().getId());
  879. + stmt.setInt(2, 18);
  880. + stmt.setInt(3, 0);
  881. + stmt.setInt(4, 0);
  882. + stmt.setInt(5, 0);
  883. + stmt.setInt(6, 0);
  884. + stmt.setInt(7, player.getObjectId());
  885. + stmt.execute();
  886. + stmt.close();
  887. + stmt = null;
  888. + }
  889. + catch (Exception e)
  890. + {
  891. + if (Config.DEBUG)
  892. + e.printStackTrace();
  893. +
  894. + LOGGER.info(Level.SEVERE, "[Class Coin]: Error updating Class: ", e);
  895. + }
  896. + }
  897. +
  898. + public static void DeleteHero(Player player)
  899. + {
  900. + try (Connection con = L2DatabaseFactory.getInstance().getConnection())
  901. + {
  902. + PreparedStatement statement = con.prepareStatement("DELETE FROM heroes WHERE char_id=?");
  903. + statement.setInt(1, player.getObjectId());
  904. + statement.execute();
  905. + statement.close();
  906. + }
  907. + catch (Exception e)
  908. + {
  909. + LOGGER.warn("could not clear char Hero: " + e);
  910. + }
  911. + }
  912. +
  913. @Override
  914. public String[] getAdminCommandList()
  915. {
  916.  
  917. \ No newline at end of file
  918. Index: java/net/sf/l2j/gameserver/handler/itemhandlers/ChangeClass.java
  919. ===================================================================
  920. --- java/net/sf/l2j/gameserver/handler/itemhandlers/ChangeClass.java (revision 0)
  921. +++ java/net/sf/l2j/gameserver/handler/itemhandlers/ChangeClass.java (working copy)
  922. @@ -0,0 +1,35 @@
  923. +package net.sf.l2j.gameserver.handler.itemhandlers;
  924. +
  925. +import net.sf.l2j.gameserver.handler.IItemHandler;
  926. +import net.sf.l2j.gameserver.model.actor.Playable;
  927. +import net.sf.l2j.gameserver.model.actor.instance.Player;
  928. +import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
  929. +import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  930. +import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
  931. +
  932. +/**
  933. + * @author Williams
  934. + *
  935. + */
  936. +public class ChangeClass implements IItemHandler
  937. +{
  938. + @Override
  939. + public void useItem(Playable playable, ItemInstance item, boolean forceUse)
  940. + {
  941. + if (!(playable instanceof Player))
  942. + return;
  943. +
  944. + Player activeChar = (Player)playable;
  945. + if (activeChar.isInOlympiadMode())
  946. + {
  947. + activeChar.sendMessage("SYS: You can not do that.");
  948. + return;
  949. + }
  950. + activeChar.setClassChangeItemId(item.getItemId());
  951. +
  952. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  953. + html.setFile("data/html/mods/ChangeClasses/aviso.htm");
  954. + activeChar.sendPacket(html);
  955. + activeChar.sendPacket(ActionFailed.STATIC_PACKET);
  956. + }
  957. +}
  958. Index: java/net/sf/l2j/gameserver/network/CloseGame.java
  959. ===================================================================
  960. --- java/net/sf/l2j/gameserver/network/CloseGame.java (revision 0)
  961. +++ java/net/sf/l2j/gameserver/network/CloseGame.java (working copy)
  962. @@ -0,0 +1,72 @@
  963. +package net.sf.l2j.gameserver.network;
  964. +
  965. +import net.sf.l2j.commons.concurrent.ThreadPool;
  966. +
  967. +import net.sf.l2j.gameserver.model.actor.instance.Player;
  968. +import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
  969. +
  970. +public class CloseGame implements Runnable
  971. +{
  972. + private final Player _player;
  973. + private int _time;
  974. +
  975. + public CloseGame(Player player, int time)
  976. + {
  977. + _time = time;
  978. + _player = player;
  979. + }
  980. +
  981. + @Override
  982. + public void run()
  983. + {
  984. + if (_player.isOnline())
  985. + {
  986. + switch (_time)
  987. + {
  988. + case 60:
  989. + case 120:
  990. + case 180:
  991. + case 240:
  992. + case 300:
  993. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time / 60 + " minute(s) ..");
  994. + break;
  995. + case 20:
  996. + case 30:
  997. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 3000));
  998. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  999. + break;
  1000. + case 15:
  1001. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 3000));
  1002. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  1003. + break;
  1004. + case 10:
  1005. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 3000));
  1006. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  1007. + break;
  1008. + case 5:
  1009. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 1500));
  1010. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  1011. + break;
  1012. + case 4:
  1013. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 1500));
  1014. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  1015. + break;
  1016. + case 3:
  1017. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 1500));
  1018. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  1019. + break;
  1020. + case 2:
  1021. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 1500));
  1022. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  1023. + break;
  1024. + case 1:
  1025. + _player.sendPacket(new ExShowScreenMessage("" + _time + " ..", 1500));
  1026. + _player.sendChatMessage(0, 0, "SYS", "Desconecting in " + _time + " second(s) ..");
  1027. + ThreadPool.schedule(() -> _player.logout(false), _time);
  1028. + }
  1029. +
  1030. + if (_time > 1)
  1031. + ThreadPool.schedule(new CloseGame(_player, _time - 1), 1000L);
  1032. + }
  1033. + }
  1034. +}
  1035.  
  1036. \ No newline at end of file
  1037. #P aCis_datapack
  1038. Index: data/html/mods/ChangeClasses/aviso.htm
  1039. ===================================================================
  1040. --- data/html/mods/ChangeClasses/aviso.htm (revision 0)
  1041. +++ data/html/mods/ChangeClasses/aviso.htm (working copy)
  1042. @@ -0,0 +1,92 @@
  1043. +<html><title>Change Class</title><body>
  1044. +<center>
  1045. +<img src="l2font-e.replay_logo-e" width=250 height=65>
  1046. +<table><tr><td height=7>
  1047. +<img src="L2UI.SquareGray" width=220 height=1>
  1048. +</td></tr></table>
  1049. +<img src="L2UI.SquareGray" width=295 height=1>
  1050. +<table bgcolor=000000 width=300>
  1051. + <tr>
  1052. + <td><center><font color="CD6339">: TERMOS DE USO :</font></center></td>
  1053. + </tr>
  1054. +</table>
  1055. +<table><tr><td height=7>
  1056. +<img src="L2UI.SquareGray" width=295 height=1>
  1057. +</td></tr></table>
  1058. +<img src="L2UI.SquareGray" width=220 height=1>
  1059. +<br>
  1060. +<img src="l2ui_ch3.herotower_deco" width=256 height=32>
  1061. +<br>
  1062. +<font color="ff9900" align="center">Requisitos:</font>
  1063. +<br1>
  1064. +<img src="L2UI.SquareGray" width=230 height=1>
  1065. +<br1>
  1066. +</center>
  1067. +<table width=300>
  1068. + <tr>
  1069. + <td><img src="L2UI.bbs_boardmaster" width=16 height=16></td>
  1070. + <td> - <font color="00ffe6">Classe Base</font>: Esteja com sua classe Base.</td>
  1071. + </tr>
  1072. +</table>
  1073. +<center>
  1074. +<img src="L2UI.SquareGray" width=230 height=1>
  1075. +</center>
  1076. +
  1077. +<center>
  1078. +<br>
  1079. +<font color="ff9900" align="center">Consequencias:</font>
  1080. +<br1>
  1081. +<img src="L2UI.SquareGray" width=230 height=1>
  1082. +<br1>
  1083. +</center>
  1084. +<table width=300>
  1085. + <tr>
  1086. + <td><img src="L2UI.bbs_boardmaster" width=16 height=16></td>
  1087. + <td> - <font color="00ffe6">Skills</font>: Todas as Skills da classe base serao deletas.</td>
  1088. + </tr>
  1089. +</table>
  1090. +<br1>
  1091. +<center>
  1092. +<img src="L2UI.SquareGray" width=230 height=1>
  1093. +</center>
  1094. +<table width=300>
  1095. + <tr>
  1096. + <td><img src="L2UI.bbs_boardmaster" width=16 height=16></td>
  1097. + <td> - <font color="00ffe6">Hero de Olympiad</font>: Seu HERO sera removido.</td>
  1098. + </tr>
  1099. +</table>
  1100. +<center>
  1101. +<img src="L2UI.SquareGray" width=230 height=1>
  1102. +</center>
  1103. +
  1104. +<table width=300>
  1105. + <tr>
  1106. + <td><img src="L2UI.bbs_boardmaster" width=16 height=16></td>
  1107. + <td> - <font color="00ffe6">Pontos Olympiad</font>: Seus pontos serao removidos.</td>
  1108. + </tr>
  1109. +</table>
  1110. +<center>
  1111. +<img src="L2UI.SquareGray" width=230 height=1>
  1112. +</center>
  1113. +
  1114. +<table width=300>
  1115. + <tr>
  1116. + <td><img src="L2UI.bbs_boardmaster" width=16 height=16></td>
  1117. + <td> - <font color="00ffe6">Lutas Olympiad</font>: Suas participacoes serao removidas.</td>
  1118. + </tr>
  1119. +</table>
  1120. +
  1121. +<center>
  1122. +
  1123. +<br1>
  1124. +<img src="L2UI.SquareGray" width=230 height=1>
  1125. +<br>
  1126. +<br>
  1127. +<table>
  1128. +<tr>
  1129. +<td align=><button value="" action="" width=32 height=16 back="" fore=""></td><td><button value="Continue" action="bypass -h classe_index" width=75 height=21 back="L2UI_CH3.Btn1_normalDisable" fore="L2UI_CH3.Btn1_normalDisable"></td><td align=><button value="" action="" width=32 height=16 back="L2UI_CH3.tutorial_pointer" fore="L2UI_CH3.tutorial_pointer"></td>
  1130. +</tr>
  1131. +</table>
  1132. +<br>
  1133. +</center>
  1134. +</body></html>
  1135. \ No newline at end of file
  1136. Index: data/html/mods/ChangeClasses/classes.htm
  1137. ===================================================================
  1138. --- data/html/mods/ChangeClasses/classes.htm (revision 0)
  1139. +++ data/html/mods/ChangeClasses/classes.htm (working copy)
  1140. @@ -0,0 +1,59 @@
  1141. +<html><body><center>
  1142. +Select a new class:
  1143. +<img src="L2UI.SquareWhite" width=270 height=1><img src="L2UI.SquareBlank" width=1 height=3>
  1144. +<table width=270 border=0 bgcolor="000000">
  1145. + <tr>
  1146. + <td><a action="bypass -h classe_change Duelist"><center>Duelist</center></a></td>
  1147. + <td><a action="bypass -h classe_change Dreadnought"><center>Dreadnought</center></a></td>
  1148. + </tr><tr>
  1149. + <td><a action="bypass -h classe_change Phoenix_Knight"><center>Phoenix Knight</center></a></td>
  1150. + <td><a action="bypass -h classe_change Hell_Knight"><center>Hell Knight</center></a></td>
  1151. + </tr><tr>
  1152. + <td><a action="bypass -h classe_change Sagittarius"><center>Sagittarius</center></a></td>
  1153. + <td><a action="bypass -h classe_change Adventurer"><center>Adventurer</center></a></td>
  1154. + </tr><tr>
  1155. + <td><a action="bypass -h classe_change Archmage"><center>Archmage</center></a></td>
  1156. + <td><a action="bypass -h classe_change Soultaker"><center>Soultaker</center></a></td>
  1157. + </tr><tr>
  1158. + <td><a action="bypass -h classe_change Arcana_Lord"><center>Arcana Lord</center></a></td>
  1159. + <td><a action="bypass -h classe_change Cardinal"><center>Cardinal</center></a></td>
  1160. + </tr><tr>
  1161. + <td><a action="bypass -h classe_change Hierophant"><center>Hierophant</center></a></td>
  1162. + <td><a action="bypass -h classe_change Eva_Templar"><center>Eva's Templar</center></a></td>
  1163. + </tr><tr>
  1164. + <td><a action="bypass -h classe_change Sword_Muse"><center>Sword Muse</center></a></td>
  1165. + <td><a action="bypass -h classe_change Wind_Rider"><center>Wind Rider</center></a></td>
  1166. + </tr><tr>
  1167. + <td><a action="bypass -h classe_change Moonli_Sentinel"><center>Moonlight Sentinel</center></a></td>
  1168. + <td><a action="bypass -h classe_change Mystic_Muse"><center>Mystic Muse</center></a></td>
  1169. + </tr><tr>
  1170. + <td><a action="bypass -h classe_change Elemental_Master"><center>Elemental Master</center></a></td>
  1171. + <td><a action="bypass -h classe_change Eva_Saint"><center>Eva's Saint</center></a></td>
  1172. + </tr><tr>
  1173. + <td><a action="bypass -h classe_change Shillien_Templar"><center>Shillien Templar</center></a></td>
  1174. + <td><a action="bypass -h classe_change Spectral_Dancer"><center>Spectral Dancer</center></a></td>
  1175. + </tr><tr>
  1176. + <td><a action="bypass -h classe_change Ghost_Hunter"><center>Ghost Hunter</center></a></td>
  1177. + <td><a action="bypass -h classe_change Ghost_Sentinel"><center>Ghost Sentinel</center></a></td>
  1178. + </tr><tr>
  1179. + <td><a action="bypass -h classe_change Storm_Screamer"><center>Storm Screamer</center></a></td>
  1180. + <td><a action="bypass -h classe_change Spectral_Master"><center>Spectral Master</center></a></td>
  1181. + </tr><tr>
  1182. + <td><a action="bypass -h classe_change Shillien_Saint"><center>Shillien Saint</center></a></td>
  1183. + <td><a action="bypass -h classe_change Titan"><center>Titan</center></a></td>
  1184. + </tr><tr>
  1185. + <td><a action="bypass -h classe_change Grand_Khavatari"><center>Grand Khavatari</center></a></td>
  1186. + <td><a action="bypass -h classe_change Dominator"><center>Dominator</center></a></td>
  1187. + </tr><tr>
  1188. + <td><a action="bypass -h classe_change Doomcryer"><center>Doomcryer</center></a></td>
  1189. + <td><a action="bypass -h classe_change Fortune_Seeker"><center>Fortune Seeker</center></a></td>
  1190. + </tr><tr>
  1191. + <td><a action="bypass -h classe_change Maestro"><center>Maestro</center></a></td>
  1192. + </tr>
  1193. +</table>
  1194. +<img src="L2UI.SquareWhite" width=270 height=1> <img src="L2UI.SquareBlank" width=1 height=3>
  1195. +<br>
  1196. +<br>
  1197. +<a action="bypass -h classe_aviso">What will happen if I change my class?</a>
  1198. +<br>
  1199. +</center></body></html>
  1200. \ No newline at end of file
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement