Advertisement
paytaly

Character Killing Monuments - Core

Aug 8th, 2015
2,989
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 31.47 KB | None | 0 0
  1. ### Eclipse Workspace Patch 1.0
  2. #P aCis_gameserver
  3. Index: java/net/sf/l2j/gameserver/network/serverpackets/NpcInfoPolymorph.java
  4. ===================================================================
  5. --- java/net/sf/l2j/gameserver/network/serverpackets/NpcInfoPolymorph.java  (revision 0)
  6. +++ java/net/sf/l2j/gameserver/network/serverpackets/NpcInfoPolymorph.java  (working copy)
  7. @@ -0,0 +1,203 @@
  8. +/*
  9. + * This program is free software: you can redistribute it and/or modify it under
  10. + * the terms of the GNU General Public License as published by the Free Software
  11. + * Foundation, either version 3 of the License, or (at your option) any later
  12. + * version.
  13. + *
  14. + * This program is distributed in the hope that it will be useful, but WITHOUT
  15. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  17. + * details.
  18. + *
  19. + * You should have received a copy of the GNU General Public License along with
  20. + * this program. If not, see <http://www.gnu.org/licenses/>.
  21. + */
  22. +package net.sf.l2j.gameserver.network.serverpackets;
  23. +
  24. +import net.sf.l2j.gameserver.datatables.CharTemplateTable;
  25. +import net.sf.l2j.gameserver.datatables.ClanTable;
  26. +import net.sf.l2j.gameserver.model.CharSelectInfoPackage;
  27. +import net.sf.l2j.gameserver.model.L2Clan;
  28. +import net.sf.l2j.gameserver.model.actor.L2PcPolymorph;
  29. +import net.sf.l2j.gameserver.model.actor.template.PcTemplate;
  30. +import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
  31. +
  32. +/**
  33. + * @author paytaly
  34. + */
  35. +public final class NpcInfoPolymorph extends L2GameServerPacket
  36. +{
  37. +   private final L2PcPolymorph _activeChar;
  38. +   private final CharSelectInfoPackage _morph;
  39. +   private final PcTemplate _template;
  40. +   private final L2Clan _clan;
  41. +   private final int _x, _y, _z, _heading;
  42. +   private final int _mAtkSpd, _pAtkSpd;
  43. +   private final int _runSpd, _walkSpd;
  44. +   private final float _moveMultiplier;
  45. +  
  46. +   public NpcInfoPolymorph(L2PcPolymorph cha)
  47. +   {
  48. +       _activeChar = cha;
  49. +       _morph = cha.getPolymorphInfo();
  50. +       _template = CharTemplateTable.getInstance().getTemplate(_morph.getBaseClassId());
  51. +       _clan = ClanTable.getInstance().getClan(_morph.getClanId());
  52. +      
  53. +       _x = _activeChar.getX();
  54. +       _y = _activeChar.getY();
  55. +       _z = _activeChar.getZ();
  56. +       _heading = _activeChar.getHeading();
  57. +      
  58. +       _mAtkSpd = _activeChar.getMAtkSpd();
  59. +       _pAtkSpd = _activeChar.getPAtkSpd();
  60. +      
  61. +       _moveMultiplier = _activeChar.getMovementSpeedMultiplier();
  62. +       _runSpd = (int) (_activeChar.getRunSpeed() / _moveMultiplier);
  63. +       _walkSpd = (int) (_activeChar.getWalkSpeed() / _moveMultiplier);
  64. +   }
  65. +  
  66. +   @Override
  67. +   protected final void writeImpl()
  68. +   {
  69. +       writeC(0x03);
  70. +       writeD(_x);
  71. +       writeD(_y);
  72. +       writeD(_z);
  73. +       writeD(_heading);
  74. +       writeD(_activeChar.getObjectId());
  75. +       writeS(_morph.getName());
  76. +       writeD(_morph.getRace());
  77. +       writeD(_morph.getSex());
  78. +      
  79. +       writeD(_morph.getBaseClassId());
  80. +      
  81. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_HAIRALL));
  82. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_HEAD));
  83. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_RHAND));
  84. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_LHAND));
  85. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_GLOVES));
  86. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_CHEST));
  87. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_LEGS));
  88. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_FEET));
  89. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_BACK));
  90. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_RHAND));
  91. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_HAIR));
  92. +       writeD(_morph.getPaperdollItemId(Inventory.PAPERDOLL_FACE));
  93. +      
  94. +       // c6 new h's
  95. +       writeH(0x00);
  96. +       writeH(0x00);
  97. +       writeH(0x00);
  98. +       writeH(0x00);
  99. +       writeD(_morph.getAugmentationId());
  100. +       writeH(0x00);
  101. +       writeH(0x00);
  102. +       writeH(0x00);
  103. +       writeH(0x00);
  104. +       writeH(0x00);
  105. +       writeH(0x00);
  106. +       writeH(0x00);
  107. +       writeH(0x00);
  108. +       writeH(0x00);
  109. +       writeH(0x00);
  110. +       writeH(0x00);
  111. +       writeH(0x00);
  112. +       writeD(0x00);
  113. +       writeH(0x00);
  114. +       writeH(0x00);
  115. +       writeH(0x00);
  116. +       writeH(0x00);
  117. +      
  118. +       writeD(0);
  119. +       writeD(0);
  120. +      
  121. +       writeD(_mAtkSpd);
  122. +       writeD(_pAtkSpd);
  123. +      
  124. +       writeD(0);
  125. +       writeD(0);
  126. +      
  127. +       writeD(_runSpd);
  128. +       writeD(_walkSpd);
  129. +       writeD(_runSpd); // swim run speed
  130. +       writeD(_walkSpd); // swim walk speed
  131. +       writeD(_runSpd); // fl run speed
  132. +       writeD(_walkSpd); // fl walk speed
  133. +       writeD(_runSpd); // fly run speed
  134. +       writeD(_walkSpd); // fly walk speed
  135. +       writeF(_activeChar.getMovementSpeedMultiplier());
  136. +       writeF(_activeChar.getAttackSpeedMultiplier());
  137. +      
  138. +       writeF(_template.getCollisionRadius());
  139. +       writeF(_template.getCollisionHeight());
  140. +      
  141. +       writeD(_morph.getHairStyle());
  142. +       writeD(_morph.getHairColor());
  143. +       writeD(_morph.getFace());
  144. +      
  145. +       writeS(_activeChar.getVisibleTitle());
  146. +      
  147. +       if (_clan != null)
  148. +       {
  149. +           writeD(_clan.getClanId());
  150. +           writeD(_clan.getCrestId());
  151. +           writeD(_clan.getAllyId());
  152. +           writeD(_clan.getAllyCrestId());
  153. +       }
  154. +       else
  155. +       {
  156. +           writeD(0);
  157. +           writeD(0);
  158. +           writeD(0);
  159. +           writeD(0);
  160. +       }
  161. +      
  162. +       writeD(0);
  163. +      
  164. +       writeC(1); // standing = 1 sitting = 0
  165. +       writeC(_activeChar.isRunning() ? 1 : 0); // running = 1 walking = 0
  166. +       writeC(_activeChar.isInCombat() ? 1 : 0);
  167. +       writeC(_activeChar.isAlikeDead() ? 1 : 0);
  168. +      
  169. +       writeC(0); // invisible = 1 visible =0
  170. +          
  171. +       writeC(0); // 1 on strider 2 on wyvern 0 no mount
  172. +       writeC(0); // 1 - sellshop
  173. +      
  174. +       writeH(0);
  175. +      
  176. +       writeC(0);
  177. +      
  178. +       writeD(_activeChar.getAbnormalEffect());
  179. +
  180. +       writeC(0);
  181. +       writeH(0); // Blue value for name (0 = white, 255 = pure blue)
  182. +       writeD(_morph.getClassId());
  183. +      
  184. +       writeD(_activeChar.getMaxCp());
  185. +       writeD((int) _activeChar.getCurrentCp());
  186. +       writeC((_morph.getEnchantEffect() > 127) ? 127 : _morph.getEnchantEffect());
  187. +      
  188. +       writeC(0x00); // team circle around feet 1= Blue, 2 = red
  189. +          
  190. +       writeD(_clan != null ? _clan.getCrestLargeId() : 0);
  191. +       writeC(0); // Symbol on char menu ctrl+I
  192. +       writeC(0); // Hero Aura
  193. +      
  194. +       writeC(0); // 0x01: Fishing Mode (Cant be undone by setting back to 0)
  195. +       writeD(0);
  196. +       writeD(0);
  197. +       writeD(0);
  198. +      
  199. +       writeD(_activeChar.getNameColor());
  200. +      
  201. +       writeD(0x00); // isRunning() as in UserInfo?
  202. +      
  203. +       writeD(0);
  204. +       writeD(0);
  205. +      
  206. +       writeD(_activeChar.getTitleColor());
  207. +      
  208. +       writeD(0x00);
  209. +   }
  210. +}
  211. \ No newline at end of file
  212. Index: java/net/sf/l2j/gameserver/GameServer.java
  213. ===================================================================
  214. --- java/net/sf/l2j/gameserver/GameServer.java  (revision 3)
  215. +++ java/net/sf/l2j/gameserver/GameServer.java  (working copy)
  216. @@ -78,6 +78,7 @@
  217.  import net.sf.l2j.gameserver.instancemanager.BoatManager;
  218.  import net.sf.l2j.gameserver.instancemanager.CastleManager;
  219.  import net.sf.l2j.gameserver.instancemanager.CastleManorManager;
  220. +import net.sf.l2j.gameserver.instancemanager.CharacterKillingManager;
  221.  import net.sf.l2j.gameserver.instancemanager.ClanHallManager;
  222.  import net.sf.l2j.gameserver.instancemanager.CoupleManager;
  223.  import net.sf.l2j.gameserver.instancemanager.CursedWeaponsManager;
  224. @@ -301,6 +302,11 @@
  225.         if (Config.ALT_FISH_CHAMPIONSHIP_ENABLED)
  226.             FishingChampionshipManager.getInstance();
  227.        
  228. +       if (Config.CKM_ENABLED)
  229. +       {
  230. +           CharacterKillingManager.getInstance().init();
  231. +       }
  232. +      
  233.         Util.printSection("System");
  234.         TaskManager.getInstance();
  235.         Runtime.getRuntime().addShutdownHook(Shutdown.getInstance());
  236. Index: java/net/sf/l2j/gameserver/model/actor/L2PcPolymorph.java
  237. ===================================================================
  238. --- java/net/sf/l2j/gameserver/model/actor/L2PcPolymorph.java   (revision 0)
  239. +++ java/net/sf/l2j/gameserver/model/actor/L2PcPolymorph.java   (working copy)
  240. @@ -0,0 +1,191 @@
  241. +/*
  242. + * This program is free software: you can redistribute it and/or modify it under
  243. + * the terms of the GNU General Public License as published by the Free Software
  244. + * Foundation, either version 3 of the License, or (at your option) any later
  245. + * version.
  246. + *
  247. + * This program is distributed in the hope that it will be useful, but WITHOUT
  248. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  249. + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  250. + * details.
  251. + *
  252. + * You should have received a copy of the GNU General Public License along with
  253. + * this program. If not, see <http://www.gnu.org/licenses/>.
  254. + */
  255. +package net.sf.l2j.gameserver.model.actor;
  256. +
  257. +import java.sql.Connection;
  258. +import java.sql.PreparedStatement;
  259. +import java.sql.ResultSet;
  260. +import java.util.logging.Level;
  261. +
  262. +import net.sf.l2j.L2DatabaseFactory;
  263. +import net.sf.l2j.gameserver.model.CharSelectInfoPackage;
  264. +import net.sf.l2j.gameserver.model.L2Object;
  265. +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  266. +import net.sf.l2j.gameserver.model.actor.template.NpcTemplate;
  267. +import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
  268. +import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  269. +import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
  270. +import net.sf.l2j.gameserver.network.serverpackets.NpcInfoPolymorph;
  271. +
  272. +/**
  273. + * @author paytaly
  274. + */
  275. +public class L2PcPolymorph extends L2Npc
  276. +{
  277. +   private CharSelectInfoPackage _polymorphInfo;
  278. +   private int _nameColor = 0xFFFFFF;
  279. +   private int _titleColor = 0xFFFF77;
  280. +   private String _visibleTitle = "";
  281. +  
  282. +   public L2PcPolymorph(int objectId, NpcTemplate template)
  283. +   {
  284. +       super(objectId, template);
  285. +       setIsInvul(true);
  286. +   }
  287. +  
  288. +   @Override
  289. +   public boolean hasRandomAnimation()
  290. +   {
  291. +       return false;
  292. +   }
  293. +  
  294. +   public CharSelectInfoPackage getPolymorphInfo()
  295. +   {
  296. +       return _polymorphInfo;
  297. +   }
  298. +  
  299. +   public void setPolymorphInfo(CharSelectInfoPackage polymorphInfo)
  300. +   {
  301. +       _polymorphInfo = polymorphInfo;
  302. +      
  303. +       for (L2Object object : getKnownList().getKnownObjects())
  304. +       {
  305. +           if (object instanceof L2PcInstance)
  306. +           {
  307. +               sendInfo(object.getActingPlayer());
  308. +           }
  309. +       }
  310. +   }
  311. +  
  312. +   public int getNameColor()
  313. +   {
  314. +       return _nameColor;
  315. +   }
  316. +  
  317. +   public void setNameColor(int nameColor)
  318. +   {
  319. +       _nameColor = nameColor;
  320. +   }
  321. +  
  322. +   public int getTitleColor()
  323. +   {
  324. +       return _titleColor;
  325. +   }
  326. +  
  327. +   public void setTitleColor(int titleColor)
  328. +   {
  329. +       _titleColor = titleColor;
  330. +   }
  331. +  
  332. +   public String getVisibleTitle()
  333. +   {
  334. +       return _visibleTitle;
  335. +   }
  336. +  
  337. +   public void setVisibleTitle(String title)
  338. +   {
  339. +       _visibleTitle = title == null ? "" : title;
  340. +   }
  341. +
  342. +   @Override
  343. +   public void sendInfo(L2PcInstance activeChar)
  344. +   {
  345. +       if (getPolymorphInfo() == null)
  346. +       {
  347. +           super.sendInfo(activeChar);
  348. +           return;
  349. +       }
  350. +      
  351. +       activeChar.sendPacket(new NpcInfoPolymorph(this));
  352. +   }
  353. +  
  354. +   @Override
  355. +   public String getHtmlPath(int npcId, int val)
  356. +   {
  357. +       String pom = "" + npcId;
  358. +       if (val != 0)
  359. +       {
  360. +           pom += "-" + val;
  361. +       }
  362. +       return "data/html/polymorph/" + pom + ".htm";
  363. +   }
  364. +  
  365. +   @Override
  366. +   public void showChatWindow(L2PcInstance player, int val)
  367. +   {
  368. +       String filename = getHtmlPath(getNpcId(), val);
  369. +      
  370. +       // Send a Server->Client NpcHtmlMessage containing the text of the L2Npc to the L2PcInstance
  371. +       final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  372. +       html.setFile(filename);
  373. +       html.replace("%objectId%", getObjectId());
  374. +       html.replace("%ownername%", getPolymorphInfo() != null ? getPolymorphInfo().getName() : "");
  375. +       player.sendPacket(html);
  376. +      
  377. +       // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  378. +       player.sendPacket(ActionFailed.STATIC_PACKET);
  379. +   }
  380. +  
  381. +   public static CharSelectInfoPackage loadCharInfo(int objectId)
  382. +   {
  383. +       try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  384. +           PreparedStatement statement = con.prepareStatement("SELECT char_name, race, base_class, classid, sex, face, hairStyle, hairColor, clanid FROM characters WHERE obj_Id = ?"))
  385. +       {
  386. +           statement.setInt(1, objectId);
  387. +          
  388. +           try (ResultSet rs = statement.executeQuery())
  389. +           {
  390. +               if (rs.next())
  391. +               {
  392. +                   final CharSelectInfoPackage charInfo = new CharSelectInfoPackage(objectId, rs.getString("char_name"));
  393. +                   charInfo.setRace(rs.getInt("race"));
  394. +                   charInfo.setBaseClassId(rs.getInt("base_class"));
  395. +                   charInfo.setClassId(rs.getInt("classid"));
  396. +                   charInfo.setSex(rs.getInt("sex"));
  397. +                   charInfo.setFace(rs.getInt("face"));
  398. +                   charInfo.setHairStyle(rs.getInt("hairStyle"));
  399. +                   charInfo.setHairColor(rs.getInt("hairColor"));
  400. +                   charInfo.setClanId(rs.getInt("clanid"));
  401. +                  
  402. +                   // Get the augmentation id for equipped weapon
  403. +                   int weaponObjId = charInfo.getPaperdollObjectId(Inventory.PAPERDOLL_RHAND);
  404. +                   if (weaponObjId > 0)
  405. +                   {
  406. +                       try (PreparedStatement statementAugment = con.prepareStatement("SELECT attributes FROM augmentations WHERE item_id = ?"))
  407. +                       {
  408. +                           statementAugment.setInt(1, weaponObjId);
  409. +                           try (ResultSet rsAugment = statementAugment.executeQuery())
  410. +                           {
  411. +                               if (rsAugment.next())
  412. +                               {
  413. +                                   int augment = rsAugment.getInt("attributes");
  414. +                                   charInfo.setAugmentationId(augment == -1 ? 0 : augment);
  415. +                               }
  416. +                           }
  417. +                       }
  418. +                   }
  419. +                  
  420. +                   return charInfo;
  421. +               }
  422. +           }
  423. +       }
  424. +       catch (Exception e)
  425. +       {
  426. +           _log.log(Level.WARNING, "Could not restore char info: " + e.getMessage(), e);
  427. +       }
  428. +      
  429. +       return null;
  430. +   }
  431. +}
  432. Index: java/net/sf/l2j/Config.java
  433. ===================================================================
  434. --- java/net/sf/l2j/Config.java (revision 3)
  435. +++ java/net/sf/l2j/Config.java (working copy)
  436. @@ -54,6 +54,7 @@
  437.     public static final String PLAYERS_FILE = "./config/players.properties";
  438.     public static final String SERVER_FILE = "./config/server.properties";
  439.     public static final String SIEGE_FILE = "./config/siege.properties";
  440. +   public static final String CUSTOM_FILE = "./config/custom.properties";
  441.    
  442.     // --------------------------------------------------
  443.     // Clans settings
  444. @@ -679,6 +680,16 @@
  445.     public static int CLIENT_PACKET_QUEUE_MAX_UNDERFLOWS_PER_MIN = 1; // default 1
  446.     public static int CLIENT_PACKET_QUEUE_MAX_UNKNOWN_PER_MIN = 5; // default 5
  447.    
  448. +   /** Character Killing Monument settings */
  449. +   public static boolean CKM_ENABLED;
  450. +   public static long CKM_CYCLE_LENGTH;
  451. +   public static String CKM_PVP_NPC_TITLE;
  452. +   public static int CKM_PVP_NPC_TITLE_COLOR;
  453. +   public static int CKM_PVP_NPC_NAME_COLOR;
  454. +   public static String CKM_PK_NPC_TITLE;
  455. +   public static int CKM_PK_NPC_TITLE_COLOR;
  456. +   public static int CKM_PK_NPC_NAME_COLOR;
  457. +  
  458.     // --------------------------------------------------
  459.    
  460.     /**
  461. @@ -1240,6 +1251,17 @@
  462.             ZONE_TOWN = server.getProperty("ZoneTown", 0);
  463.             SERVER_NEWS = server.getProperty("ShowServerNews", false);
  464.             DISABLE_TUTORIAL = server.getProperty("DisableTutorial", false);
  465. +          
  466. +           // Custom
  467. +           final ExProperties custom = load(CUSTOM_FILE);
  468. +           CKM_ENABLED = custom.getProperty("CKMEnabled", false);
  469. +           CKM_CYCLE_LENGTH = custom.getProperty("CKMCycleLength", 86400000);
  470. +           CKM_PVP_NPC_TITLE = custom.getProperty("CKMPvPNpcTitle", "%kills% PvPs in the last 24h");
  471. +           CKM_PVP_NPC_TITLE_COLOR = Integer.decode(StringUtil.concat("0x", custom.getProperty("CKMPvPNpcTitleColor", "00CCFF")));
  472. +           CKM_PVP_NPC_NAME_COLOR = Integer.decode(StringUtil.concat("0x", custom.getProperty("CKMPvPNpcNameColor", "FFFFFF")));
  473. +           CKM_PK_NPC_TITLE = custom.getProperty("CKMPKNpcTitle", "%kills% PKs in the last 24h");
  474. +           CKM_PK_NPC_TITLE_COLOR = Integer.decode(StringUtil.concat("0x", custom.getProperty("CKMPKNpcTitleColor", "00CCFF")));
  475. +           CKM_PK_NPC_NAME_COLOR = Integer.decode(StringUtil.concat("0x", custom.getProperty("CKMPKNpcNameColor", "FFFFFF")));
  476.         }
  477.         else if (Server.serverMode == Server.MODE_LOGINSERVER)
  478.         {
  479. Index: java/net/sf/l2j/gameserver/instancemanager/CharacterKillingManager.java
  480. ===================================================================
  481. --- java/net/sf/l2j/gameserver/instancemanager/CharacterKillingManager.java (revision 0)
  482. +++ java/net/sf/l2j/gameserver/instancemanager/CharacterKillingManager.java (working copy)
  483. @@ -0,0 +1,321 @@
  484. +/*
  485. + * This program is free software: you can redistribute it and/or modify it under
  486. + * the terms of the GNU General Public License as published by the Free Software
  487. + * Foundation, either version 3 of the License, or (at your option) any later
  488. + * version.
  489. + *
  490. + * This program is distributed in the hope that it will be useful, but WITHOUT
  491. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  492. + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  493. + * details.
  494. + *
  495. + * You should have received a copy of the GNU General Public License along with
  496. + * this program. If not, see <http://www.gnu.org/licenses/>.
  497. + */
  498. +package net.sf.l2j.gameserver.instancemanager;
  499. +
  500. +import java.sql.Connection;
  501. +import java.sql.PreparedStatement;
  502. +import java.sql.ResultSet;
  503. +import java.sql.Statement;
  504. +import java.util.List;
  505. +import java.util.concurrent.CopyOnWriteArrayList;
  506. +import java.util.concurrent.ScheduledFuture;
  507. +import java.util.concurrent.TimeUnit;
  508. +import java.util.logging.Level;
  509. +import java.util.logging.Logger;
  510. +
  511. +import net.sf.l2j.Config;
  512. +import net.sf.l2j.L2DatabaseFactory;
  513. +import net.sf.l2j.gameserver.ThreadPoolManager;
  514. +import net.sf.l2j.gameserver.model.CharSelectInfoPackage;
  515. +import net.sf.l2j.gameserver.model.actor.L2PcPolymorph;
  516. +import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
  517. +
  518. +/**
  519. + * @author paytaly
  520. + */
  521. +public final class CharacterKillingManager
  522. +{
  523. +   private static final Logger _log = Logger.getLogger(CharacterKillingManager.class.getName());
  524. +  
  525. +   private int _cycle = 0;
  526. +   private long _cycleStart = 0L;
  527. +   private int _winnerPvPKills;
  528. +   private int _winnerPvPKillsCount;
  529. +   private int _winnerPKKills;
  530. +   private int _winnerPKKillsCount;
  531. +  
  532. +   private volatile CharSelectInfoPackage _winnerPvPKillsInfo;
  533. +   private volatile CharSelectInfoPackage _winnerPKKillsInfo;
  534. +  
  535. +   private ScheduledFuture<?> _scheduledKillingCycleTask = null;
  536. +  
  537. +   private List<L2PcPolymorph> pvpMorphListeners = new CopyOnWriteArrayList<>();
  538. +   private List<L2PcPolymorph> pkMorphListeners = new CopyOnWriteArrayList<>();
  539. +  
  540. +   protected CharacterKillingManager()
  541. +   {
  542. +   }
  543. +  
  544. +   public synchronized void init()
  545. +   {
  546. +       try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  547. +           PreparedStatement st = con.prepareStatement("SELECT cycle, cycle_start, winner_pvpkills, winner_pvpkills_count, winner_pkkills, winner_pkkills_count FROM character_kills_info ORDER BY cycle_start DESC LIMIT 1");
  548. +           ResultSet rs = st.executeQuery())
  549. +       {
  550. +           if (rs.next())
  551. +           {
  552. +               _cycle = rs.getInt("cycle");
  553. +               _cycleStart = rs.getLong("cycle_start");
  554. +               _winnerPvPKills = rs.getInt("winner_pvpkills");
  555. +               _winnerPvPKillsCount = rs.getInt("winner_pvpkills_count");
  556. +               _winnerPKKills = rs.getInt("winner_pkkills");
  557. +               _winnerPKKillsCount = rs.getInt("winner_pkkills_count");
  558. +           }
  559. +       }
  560. +       catch (Exception e)
  561. +       {
  562. +           _log.log(Level.WARNING, "Could not load characters killing cycle: " + e.getMessage(), e);
  563. +       }
  564. +      
  565. +       broadcastMorphUpdate();
  566. +      
  567. +       if (_scheduledKillingCycleTask != null)
  568. +       {
  569. +           _scheduledKillingCycleTask.cancel(true);
  570. +       }
  571. +       long millisToNextCycle = (_cycleStart + Config.CKM_CYCLE_LENGTH) - System.currentTimeMillis();
  572. +       _scheduledKillingCycleTask = ThreadPoolManager.getInstance().scheduleGeneral(new CharacterKillingCycleTask(), millisToNextCycle);
  573. +      
  574. +       _log.info(getClass().getSimpleName() + ": Started! Cycle: " + _cycle + " - Next cycle in: " + _scheduledKillingCycleTask.getDelay(TimeUnit.SECONDS) + "s");
  575. +   }
  576. +  
  577. +   public synchronized void newKillingCycle()
  578. +   {
  579. +       _cycleStart = System.currentTimeMillis();
  580. +       computateCyclePvPWinner();
  581. +       computateCyclePKWinner();
  582. +       refreshKillingSnapshot();
  583. +      
  584. +       try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  585. +           PreparedStatement st = con.prepareStatement("INSERT INTO character_kills_info (cycle_start, winner_pvpkills, winner_pvpkills_count, winner_pkkills, winner_pkkills_count) VALUES (?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS))
  586. +       {
  587. +           st.setLong(1, _cycleStart);
  588. +           st.setInt(2, _winnerPvPKills);
  589. +           st.setInt(3, _winnerPvPKillsCount);
  590. +           st.setInt(4, _winnerPKKills);
  591. +           st.setInt(5, _winnerPKKillsCount);
  592. +           st.execute();
  593. +          
  594. +           try (ResultSet rs = st.getGeneratedKeys())
  595. +           {
  596. +               if (rs.next())
  597. +               {
  598. +                   _cycle = rs.getInt(1);
  599. +               }
  600. +           }
  601. +       }
  602. +       catch (Exception e)
  603. +       {
  604. +           _log.log(Level.WARNING, "Could not create characters killing cycle: " + e.getMessage(), e);
  605. +       }
  606. +      
  607. +       broadcastMorphUpdate();
  608. +      
  609. +       if (_scheduledKillingCycleTask != null)
  610. +       {
  611. +           _scheduledKillingCycleTask.cancel(true);
  612. +       }
  613. +       _scheduledKillingCycleTask = ThreadPoolManager.getInstance().scheduleGeneral(new CharacterKillingCycleTask(), Config.CKM_CYCLE_LENGTH);
  614. +   }
  615. +  
  616. +   private void computateCyclePvPWinner()
  617. +   {
  618. +       _winnerPvPKills = 0;
  619. +       _winnerPvPKillsCount = 0;
  620. +       _winnerPvPKillsInfo = null;
  621. +      
  622. +       try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  623. +           PreparedStatement st = con.prepareStatement("SELECT c.obj_Id, (c.pvpkills - COALESCE(ck.pvpkills, 0)) pvpkills FROM characters c LEFT JOIN character_kills_snapshot ck ON ck.charId = c.obj_Id WHERE accesslevel = 0 ORDER BY pvpkills DESC LIMIT 1");
  624. +           ResultSet rs = st.executeQuery();)
  625. +       {
  626. +           if (rs.next())
  627. +           {
  628. +               int kills = rs.getInt(2);
  629. +               if (kills > 0)
  630. +               {
  631. +                   _winnerPvPKills = rs.getInt(1);
  632. +                   _winnerPvPKillsCount = kills;
  633. +               }
  634. +           }
  635. +       }
  636. +       catch (Exception e)
  637. +       {
  638. +           _log.log(Level.WARNING, "Could not computate characters killing cycle winners: " + e.getMessage(), e);
  639. +       }
  640. +   }
  641. +  
  642. +   private void computateCyclePKWinner()
  643. +   {
  644. +       _winnerPKKills = 0;
  645. +       _winnerPKKillsCount = 0;
  646. +       _winnerPKKillsInfo = null;
  647. +      
  648. +       try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  649. +           PreparedStatement st = con.prepareStatement("SELECT c.obj_Id, (c.pkkills - COALESCE(ck.pkkills, 0)) pkkills FROM characters c LEFT JOIN character_kills_snapshot ck ON ck.charId = c.obj_Id WHERE accesslevel = 0 ORDER BY pkkills DESC LIMIT 1");
  650. +           ResultSet rs = st.executeQuery();)
  651. +       {
  652. +           if (rs.next())
  653. +           {
  654. +               int kills = rs.getInt(2);
  655. +               if (kills > 0)
  656. +               {
  657. +                   _winnerPKKills = rs.getInt(1);
  658. +                   _winnerPKKillsCount = kills;
  659. +               }
  660. +           }
  661. +       }
  662. +       catch (Exception e)
  663. +       {
  664. +           _log.log(Level.WARNING, "Could not computate characters killing cycle winners: " + e.getMessage(), e);
  665. +       }
  666. +   }
  667. +  
  668. +   private static void refreshKillingSnapshot()
  669. +   {
  670. +       try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  671. +           PreparedStatement stTruncate = con.prepareStatement("TRUNCATE TABLE character_kills_snapshot");
  672. +           PreparedStatement stRefresh = con.prepareStatement("INSERT INTO character_kills_snapshot (charId, pvpkills, pkkills) SELECT obj_Id, pvpkills, pkkills FROM characters WHERE (pvpkills > 0 OR pkkills > 0) AND accesslevel = 0"))
  673. +       {
  674. +           stTruncate.executeUpdate();
  675. +           stRefresh.executeUpdate();
  676. +       }
  677. +       catch (Exception e)
  678. +       {
  679. +           _log.log(Level.WARNING, "Could not refresh characters killing snapshot: " + e.getMessage(), e);
  680. +       }
  681. +   }
  682. +  
  683. +   public void broadcastMorphUpdate()
  684. +   {
  685. +       final CharSelectInfoPackage winnerPvPKillsInfo = getWinnerPvPKillsInfo();
  686. +       for (L2PcPolymorph npc : pvpMorphListeners)
  687. +       {
  688. +           broadcastPvPMorphUpdate(npc, winnerPvPKillsInfo);
  689. +       }
  690. +      
  691. +       final CharSelectInfoPackage winnerPKKillsInfo = getWinnerPKKillsInfo();
  692. +       for (L2PcPolymorph npc : pkMorphListeners)
  693. +       {
  694. +           broadcastPKMorphUpdate(npc, winnerPKKillsInfo);
  695. +       }
  696. +   }
  697. +  
  698. +   private void broadcastPvPMorphUpdate(L2PcPolymorph npc, CharSelectInfoPackage winnerPvPKillsInfo)
  699. +   {
  700. +       if (winnerPvPKillsInfo == null)
  701. +       {
  702. +           npc.setPolymorphInfo(null);
  703. +           return;
  704. +       }
  705. +       npc.setVisibleTitle(Config.CKM_PVP_NPC_TITLE.replaceAll("%kills%", String.valueOf(_winnerPvPKillsCount)));
  706. +       npc.setTitleColor(Config.CKM_PVP_NPC_TITLE_COLOR);
  707. +       npc.setNameColor(Config.CKM_PVP_NPC_NAME_COLOR);
  708. +       npc.setPolymorphInfo(winnerPvPKillsInfo);
  709. +       npc.broadcastPacket(new SocialAction(npc, 16));
  710. +   }
  711. +  
  712. +   private void broadcastPKMorphUpdate(L2PcPolymorph npc, CharSelectInfoPackage winnerPKKillsInfo)
  713. +   {
  714. +       if (winnerPKKillsInfo == null)
  715. +       {
  716. +           npc.setPolymorphInfo(null);
  717. +           return;
  718. +       }
  719. +       npc.setVisibleTitle(Config.CKM_PK_NPC_TITLE.replaceAll("%kills%", String.valueOf(_winnerPKKillsCount)));
  720. +       npc.setTitleColor(Config.CKM_PK_NPC_TITLE_COLOR);
  721. +       npc.setNameColor(Config.CKM_PK_NPC_NAME_COLOR);
  722. +       npc.setPolymorphInfo(winnerPKKillsInfo);
  723. +       npc.broadcastPacket(new SocialAction(npc, 16));
  724. +   }
  725. +  
  726. +   public boolean addPvPMorphListener(L2PcPolymorph npc)
  727. +   {
  728. +       if (npc == null)
  729. +       {
  730. +           return false;
  731. +       }
  732. +       broadcastPvPMorphUpdate(npc, getWinnerPvPKillsInfo());
  733. +       return pvpMorphListeners.add(npc);
  734. +   }
  735. +  
  736. +   public boolean removePvPMorphListener(L2PcPolymorph npc)
  737. +   {
  738. +       return pvpMorphListeners.remove(npc);
  739. +   }
  740. +  
  741. +   public boolean addPKMorphListener(L2PcPolymorph npc)
  742. +   {
  743. +       if (npc == null)
  744. +       {
  745. +           return false;
  746. +       }
  747. +       broadcastPKMorphUpdate(npc, getWinnerPKKillsInfo());
  748. +       return pkMorphListeners.add(npc);
  749. +   }
  750. +  
  751. +   public boolean removePKMorphListener(L2PcPolymorph npc)
  752. +   {
  753. +       return pkMorphListeners.remove(npc);
  754. +   }
  755. +  
  756. +   private CharSelectInfoPackage getWinnerPvPKillsInfo()
  757. +   {
  758. +       if (_winnerPvPKills != 0 && _winnerPvPKillsInfo == null)
  759. +       {
  760. +           synchronized (this)
  761. +           {
  762. +               if (_winnerPvPKillsInfo == null)
  763. +               {
  764. +                   _winnerPvPKillsInfo = L2PcPolymorph.loadCharInfo(_winnerPvPKills);
  765. +               }
  766. +           }
  767. +       }
  768. +       return _winnerPvPKillsInfo;
  769. +   }
  770. +  
  771. +   private CharSelectInfoPackage getWinnerPKKillsInfo()
  772. +   {
  773. +       if (_winnerPKKills != 0 && _winnerPKKillsInfo == null)
  774. +       {
  775. +           synchronized (this)
  776. +           {
  777. +               if (_winnerPKKillsInfo == null)
  778. +               {
  779. +                   _winnerPKKillsInfo = L2PcPolymorph.loadCharInfo(_winnerPKKills);
  780. +               }
  781. +           }
  782. +       }
  783. +       return _winnerPKKillsInfo;
  784. +   }
  785. +  
  786. +   protected static class CharacterKillingCycleTask implements Runnable
  787. +   {
  788. +       @Override
  789. +       public void run()
  790. +       {
  791. +           CharacterKillingManager.getInstance().newKillingCycle();
  792. +       }
  793. +   }
  794. +  
  795. +   public static CharacterKillingManager getInstance()
  796. +   {
  797. +       return SingletonHolder._instance;
  798. +   }
  799. +  
  800. +   private static class SingletonHolder
  801. +   {
  802. +       protected static final CharacterKillingManager _instance = new CharacterKillingManager();
  803. +   }
  804. +}
  805. Index: java/net/sf/l2j/gameserver/model/actor/instance/L2TopPKMonumentInstance.java
  806. ===================================================================
  807. --- java/net/sf/l2j/gameserver/model/actor/instance/L2TopPKMonumentInstance.java    (revision 0)
  808. +++ java/net/sf/l2j/gameserver/model/actor/instance/L2TopPKMonumentInstance.java    (working copy)
  809. @@ -0,0 +1,51 @@
  810. +/*
  811. + * This program is free software: you can redistribute it and/or modify it under
  812. + * the terms of the GNU General Public License as published by the Free Software
  813. + * Foundation, either version 3 of the License, or (at your option) any later
  814. + * version.
  815. + *
  816. + * This program is distributed in the hope that it will be useful, but WITHOUT
  817. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  818. + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  819. + * details.
  820. + *
  821. + * You should have received a copy of the GNU General Public License along with
  822. + * this program. If not, see <http://www.gnu.org/licenses/>.
  823. + */
  824. +package net.sf.l2j.gameserver.model.actor.instance;
  825. +
  826. +import net.sf.l2j.Config;
  827. +import net.sf.l2j.gameserver.instancemanager.CharacterKillingManager;
  828. +import net.sf.l2j.gameserver.model.actor.L2PcPolymorph;
  829. +import net.sf.l2j.gameserver.model.actor.template.NpcTemplate;
  830. +
  831. +/**
  832. + * @author paytaly
  833. + */
  834. +public class L2TopPKMonumentInstance extends L2PcPolymorph
  835. +{
  836. +   public L2TopPKMonumentInstance(int objectId, NpcTemplate template)
  837. +   {
  838. +       super(objectId, template);
  839. +   }
  840. +  
  841. +   @Override
  842. +   public void onSpawn()
  843. +   {
  844. +       super.onSpawn();
  845. +       if (Config.CKM_ENABLED)
  846. +       {
  847. +           CharacterKillingManager.getInstance().addPKMorphListener(this);
  848. +       }
  849. +   }
  850. +  
  851. +   @Override
  852. +   public void deleteMe()
  853. +   {
  854. +       super.deleteMe();
  855. +       if (Config.CKM_ENABLED)
  856. +       {
  857. +           CharacterKillingManager.getInstance().removePKMorphListener(this);
  858. +       }
  859. +   }
  860. +}
  861. Index: java/net/sf/l2j/gameserver/model/actor/instance/L2TopPvPMonumentInstance.java
  862. ===================================================================
  863. --- java/net/sf/l2j/gameserver/model/actor/instance/L2TopPvPMonumentInstance.java   (revision 0)
  864. +++ java/net/sf/l2j/gameserver/model/actor/instance/L2TopPvPMonumentInstance.java   (working copy)
  865. @@ -0,0 +1,51 @@
  866. +/*
  867. + * This program is free software: you can redistribute it and/or modify it under
  868. + * the terms of the GNU General Public License as published by the Free Software
  869. + * Foundation, either version 3 of the License, or (at your option) any later
  870. + * version.
  871. + *
  872. + * This program is distributed in the hope that it will be useful, but WITHOUT
  873. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  874. + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  875. + * details.
  876. + *
  877. + * You should have received a copy of the GNU General Public License along with
  878. + * this program. If not, see <http://www.gnu.org/licenses/>.
  879. + */
  880. +package net.sf.l2j.gameserver.model.actor.instance;
  881. +
  882. +import net.sf.l2j.Config;
  883. +import net.sf.l2j.gameserver.instancemanager.CharacterKillingManager;
  884. +import net.sf.l2j.gameserver.model.actor.L2PcPolymorph;
  885. +import net.sf.l2j.gameserver.model.actor.template.NpcTemplate;
  886. +
  887. +/**
  888. + * @author paytaly
  889. + */
  890. +public class L2TopPvPMonumentInstance extends L2PcPolymorph
  891. +{
  892. +   public L2TopPvPMonumentInstance(int objectId, NpcTemplate template)
  893. +   {
  894. +       super(objectId, template);
  895. +   }
  896. +  
  897. +   @Override
  898. +   public void onSpawn()
  899. +   {
  900. +       super.onSpawn();
  901. +       if (Config.CKM_ENABLED)
  902. +       {
  903. +           CharacterKillingManager.getInstance().addPvPMorphListener(this);
  904. +       }
  905. +   }
  906. +  
  907. +   @Override
  908. +   public void deleteMe()
  909. +   {
  910. +       super.deleteMe();
  911. +       if (Config.CKM_ENABLED)
  912. +       {
  913. +           CharacterKillingManager.getInstance().removePvPMorphListener(this);
  914. +       }
  915. +   }
  916. +}
  917. Index: config/custom.properties
  918. ===================================================================
  919. --- config/custom.properties    (revision 0)
  920. +++ config/custom.properties    (working copy)
  921. @@ -0,0 +1,36 @@
  922. +#=============================================================
  923. +#          Character Killing Monuments (by paytaly)
  924. +#=============================================================
  925. +# Enable the Character Killing Monuments
  926. +# Default: False
  927. +CKMEnabled = False
  928. +
  929. +# The killing cycle length
  930. +# Default: 86400000 (24h)
  931. +CKMCycleLength = 86400000
  932. +
  933. +# The title of the Monument for the PvP winner
  934. +# Note: %kills% will be replaced with the winner's PvP count in the cycle
  935. +# Default: %kills% PvPs in the last 24h
  936. +CKMPvPNpcTitle = %kills% PvPs in the last 24h
  937. +
  938. +# The title color of the Monument for the PvP winner
  939. +# Default: 00CCFF (yellow)
  940. +CKMPvPNpcTitleColor = 00CCFF
  941. +
  942. +# The name color of the Monument for the PvP winner
  943. +# Default: FFFFFF (white)
  944. +CKMPvPNpcNameColor = FFFFFF
  945. +
  946. +# The title of the Monument for the PK winner
  947. +# Note: %kills% will be replaced with the winner's PK count in the cycle
  948. +# Default: %kills% PvPs in the last 24h
  949. +CKMPKNpcTitle = %kills% PKs in the last 24h
  950. +
  951. +# The title color of the Monument for the PK winner
  952. +# Default: 00CCFF (yellow)
  953. +CKMPKNpcTitleColor = 00CCFF
  954. +
  955. +# The name color of the Monument for the PK winner
  956. +# Default: FFFFFF (white)
  957. +CKMPKNpcNameColor = FFFFFF
  958. \ No newline at end of file
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement