Hero.java 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. /*
  2. * Copyright (C) 2004-2015 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model.entity;
  20. import java.sql.Connection;
  21. import java.sql.PreparedStatement;
  22. import java.sql.ResultSet;
  23. import java.sql.SQLException;
  24. import java.sql.Statement;
  25. import java.text.SimpleDateFormat;
  26. import java.util.ArrayList;
  27. import java.util.Calendar;
  28. import java.util.Collections;
  29. import java.util.Date;
  30. import java.util.List;
  31. import java.util.Map;
  32. import java.util.Map.Entry;
  33. import java.util.concurrent.ConcurrentHashMap;
  34. import java.util.logging.Logger;
  35. import com.l2jserver.Config;
  36. import com.l2jserver.commons.database.pool.impl.ConnectionFactory;
  37. import com.l2jserver.gameserver.cache.HtmCache;
  38. import com.l2jserver.gameserver.data.sql.impl.CharNameTable;
  39. import com.l2jserver.gameserver.data.sql.impl.ClanTable;
  40. import com.l2jserver.gameserver.data.xml.impl.ClassListData;
  41. import com.l2jserver.gameserver.data.xml.impl.NpcData;
  42. import com.l2jserver.gameserver.instancemanager.CastleManager;
  43. import com.l2jserver.gameserver.model.L2Clan;
  44. import com.l2jserver.gameserver.model.L2World;
  45. import com.l2jserver.gameserver.model.StatsSet;
  46. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  47. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  48. import com.l2jserver.gameserver.model.itemcontainer.Inventory;
  49. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  50. import com.l2jserver.gameserver.model.olympiad.Olympiad;
  51. import com.l2jserver.gameserver.network.SystemMessageId;
  52. import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
  53. import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
  54. import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
  55. import com.l2jserver.gameserver.network.serverpackets.SocialAction;
  56. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  57. import com.l2jserver.gameserver.network.serverpackets.UserInfo;
  58. import com.l2jserver.util.StringUtil;
  59. /**
  60. * Hero entity.
  61. * @author godson
  62. */
  63. public class Hero
  64. {
  65. private static final Logger _log = Logger.getLogger(Hero.class.getName());
  66. private static final String GET_HEROES = "SELECT heroes.charId, characters.char_name, heroes.class_id, heroes.count, heroes.played, heroes.claimed FROM heroes, characters WHERE characters.charId = heroes.charId AND heroes.played = 1";
  67. private static final String GET_ALL_HEROES = "SELECT heroes.charId, characters.char_name, heroes.class_id, heroes.count, heroes.played, heroes.claimed FROM heroes, characters WHERE characters.charId = heroes.charId";
  68. private static final String UPDATE_ALL = "UPDATE heroes SET played = 0";
  69. private static final String INSERT_HERO = "INSERT INTO heroes (charId, class_id, count, played, claimed) VALUES (?,?,?,?,?)";
  70. private static final String UPDATE_HERO = "UPDATE heroes SET count = ?, played = ?, claimed = ? WHERE charId = ?";
  71. private static final String GET_CLAN_ALLY = "SELECT characters.clanid AS clanid, coalesce(clan_data.ally_Id, 0) AS allyId FROM characters LEFT JOIN clan_data ON clan_data.clan_id = characters.clanid WHERE characters.charId = ?";
  72. // delete hero items
  73. private static final String DELETE_ITEMS = "DELETE FROM items WHERE item_id IN (6842, 6611, 6612, 6613, 6614, 6615, 6616, 6617, 6618, 6619, 6620, 6621, 9388, 9389, 9390) AND owner_id NOT IN (SELECT charId FROM characters WHERE accesslevel > 0)";
  74. private static final Map<Integer, StatsSet> HEROES = new ConcurrentHashMap<>();
  75. private static final Map<Integer, StatsSet> COMPLETE_HEROS = new ConcurrentHashMap<>();
  76. private static final Map<Integer, StatsSet> HERO_COUNTS = new ConcurrentHashMap<>();
  77. private static final Map<Integer, List<StatsSet>> HERO_FIGHTS = new ConcurrentHashMap<>();
  78. private static final Map<Integer, List<StatsSet>> HERO_DIARY = new ConcurrentHashMap<>();
  79. private static final Map<Integer, String> HERO_MESSAGE = new ConcurrentHashMap<>();
  80. public static final String COUNT = "count";
  81. public static final String PLAYED = "played";
  82. public static final String CLAIMED = "claimed";
  83. public static final String CLAN_NAME = "clan_name";
  84. public static final String CLAN_CREST = "clan_crest";
  85. public static final String ALLY_NAME = "ally_name";
  86. public static final String ALLY_CREST = "ally_crest";
  87. public static final int ACTION_RAID_KILLED = 1;
  88. public static final int ACTION_HERO_GAINED = 2;
  89. public static final int ACTION_CASTLE_TAKEN = 3;
  90. protected Hero()
  91. {
  92. init();
  93. }
  94. private void init()
  95. {
  96. HEROES.clear();
  97. COMPLETE_HEROS.clear();
  98. HERO_COUNTS.clear();
  99. HERO_FIGHTS.clear();
  100. HERO_DIARY.clear();
  101. HERO_MESSAGE.clear();
  102. try (Connection con = ConnectionFactory.getInstance().getConnection();
  103. Statement s1 = con.createStatement();
  104. ResultSet rset = s1.executeQuery(GET_HEROES);
  105. PreparedStatement ps = con.prepareStatement(GET_CLAN_ALLY);
  106. Statement s2 = con.createStatement();
  107. ResultSet rset2 = s2.executeQuery(GET_ALL_HEROES))
  108. {
  109. while (rset.next())
  110. {
  111. StatsSet hero = new StatsSet();
  112. int charId = rset.getInt(Olympiad.CHAR_ID);
  113. hero.set(Olympiad.CHAR_NAME, rset.getString(Olympiad.CHAR_NAME));
  114. hero.set(Olympiad.CLASS_ID, rset.getInt(Olympiad.CLASS_ID));
  115. hero.set(COUNT, rset.getInt(COUNT));
  116. hero.set(PLAYED, rset.getInt(PLAYED));
  117. hero.set(CLAIMED, Boolean.parseBoolean(rset.getString(CLAIMED)));
  118. loadFights(charId);
  119. loadDiary(charId);
  120. loadMessage(charId);
  121. processHeros(ps, charId, hero);
  122. HEROES.put(charId, hero);
  123. }
  124. while (rset2.next())
  125. {
  126. StatsSet hero = new StatsSet();
  127. int charId = rset2.getInt(Olympiad.CHAR_ID);
  128. hero.set(Olympiad.CHAR_NAME, rset2.getString(Olympiad.CHAR_NAME));
  129. hero.set(Olympiad.CLASS_ID, rset2.getInt(Olympiad.CLASS_ID));
  130. hero.set(COUNT, rset2.getInt(COUNT));
  131. hero.set(PLAYED, rset2.getInt(PLAYED));
  132. hero.set(CLAIMED, Boolean.parseBoolean(rset2.getString(CLAIMED)));
  133. processHeros(ps, charId, hero);
  134. COMPLETE_HEROS.put(charId, hero);
  135. }
  136. }
  137. catch (SQLException e)
  138. {
  139. _log.warning("Hero System: Couldnt load Heroes: " + e.getMessage());
  140. }
  141. _log.info("Hero System: Loaded " + HEROES.size() + " Heroes.");
  142. _log.info("Hero System: Loaded " + COMPLETE_HEROS.size() + " all time Heroes.");
  143. }
  144. private void processHeros(PreparedStatement ps, int charId, StatsSet hero) throws SQLException
  145. {
  146. ps.setInt(1, charId);
  147. try (ResultSet rs = ps.executeQuery())
  148. {
  149. if (rs.next())
  150. {
  151. int clanId = rs.getInt("clanid");
  152. int allyId = rs.getInt("allyId");
  153. String clanName = "";
  154. String allyName = "";
  155. int clanCrest = 0;
  156. int allyCrest = 0;
  157. if (clanId > 0)
  158. {
  159. clanName = ClanTable.getInstance().getClan(clanId).getName();
  160. clanCrest = ClanTable.getInstance().getClan(clanId).getCrestId();
  161. if (allyId > 0)
  162. {
  163. allyName = ClanTable.getInstance().getClan(clanId).getAllyName();
  164. allyCrest = ClanTable.getInstance().getClan(clanId).getAllyCrestId();
  165. }
  166. }
  167. hero.set(CLAN_CREST, clanCrest);
  168. hero.set(CLAN_NAME, clanName);
  169. hero.set(ALLY_CREST, allyCrest);
  170. hero.set(ALLY_NAME, allyName);
  171. }
  172. ps.clearParameters();
  173. }
  174. }
  175. private String calcFightTime(long FightTime)
  176. {
  177. String format = String.format("%%0%dd", 2);
  178. FightTime = FightTime / 1000;
  179. String seconds = String.format(format, FightTime % 60);
  180. String minutes = String.format(format, (FightTime % 3600) / 60);
  181. String time = minutes + ":" + seconds;
  182. return time;
  183. }
  184. /**
  185. * Restore hero message from Db.
  186. * @param charId
  187. */
  188. public void loadMessage(int charId)
  189. {
  190. try (Connection con = ConnectionFactory.getInstance().getConnection();
  191. PreparedStatement ps = con.prepareStatement("SELECT message FROM heroes WHERE charId=?"))
  192. {
  193. ps.setInt(1, charId);
  194. try (ResultSet rset = ps.executeQuery())
  195. {
  196. if (rset.next())
  197. {
  198. HERO_MESSAGE.put(charId, rset.getString("message"));
  199. }
  200. }
  201. }
  202. catch (SQLException e)
  203. {
  204. _log.warning("Hero System: Couldnt load Hero Message for CharId: " + charId + ": " + e.getMessage());
  205. }
  206. }
  207. public void loadDiary(int charId)
  208. {
  209. final List<StatsSet> diary = new ArrayList<>();
  210. int diaryentries = 0;
  211. try (Connection con = ConnectionFactory.getInstance().getConnection();
  212. PreparedStatement ps = con.prepareStatement("SELECT * FROM heroes_diary WHERE charId=? ORDER BY time ASC"))
  213. {
  214. ps.setInt(1, charId);
  215. try (ResultSet rset = ps.executeQuery())
  216. {
  217. while (rset.next())
  218. {
  219. StatsSet _diaryentry = new StatsSet();
  220. long time = rset.getLong("time");
  221. int action = rset.getInt("action");
  222. int param = rset.getInt("param");
  223. String date = (new SimpleDateFormat("yyyy-MM-dd HH")).format(new Date(time));
  224. _diaryentry.set("date", date);
  225. if (action == ACTION_RAID_KILLED)
  226. {
  227. L2NpcTemplate template = NpcData.getInstance().getTemplate(param);
  228. if (template != null)
  229. {
  230. _diaryentry.set("action", template.getName() + " was defeated");
  231. }
  232. }
  233. else if (action == ACTION_HERO_GAINED)
  234. {
  235. _diaryentry.set("action", "Gained Hero status");
  236. }
  237. else if (action == ACTION_CASTLE_TAKEN)
  238. {
  239. Castle castle = CastleManager.getInstance().getCastleById(param);
  240. if (castle != null)
  241. {
  242. _diaryentry.set("action", castle.getName() + " Castle was successfuly taken");
  243. }
  244. }
  245. diary.add(_diaryentry);
  246. diaryentries++;
  247. }
  248. }
  249. HERO_DIARY.put(charId, diary);
  250. _log.info("Hero System: Loaded " + diaryentries + " diary entries for Hero: " + CharNameTable.getInstance().getNameById(charId));
  251. }
  252. catch (SQLException e)
  253. {
  254. _log.warning("Hero System: Couldnt load Hero Diary for CharId: " + charId + ": " + e.getMessage());
  255. }
  256. }
  257. public void loadFights(int charId)
  258. {
  259. final List<StatsSet> fights = new ArrayList<>();
  260. StatsSet heroCountData = new StatsSet();
  261. Calendar data = Calendar.getInstance();
  262. data.set(Calendar.DAY_OF_MONTH, 1);
  263. data.set(Calendar.HOUR_OF_DAY, 0);
  264. data.set(Calendar.MINUTE, 0);
  265. data.set(Calendar.MILLISECOND, 0);
  266. long from = data.getTimeInMillis();
  267. int numberoffights = 0;
  268. int _victorys = 0;
  269. int _losses = 0;
  270. int _draws = 0;
  271. try (Connection con = ConnectionFactory.getInstance().getConnection();
  272. PreparedStatement ps = con.prepareStatement("SELECT * FROM olympiad_fights WHERE (charOneId=? OR charTwoId=?) AND start<? ORDER BY start ASC"))
  273. {
  274. ps.setInt(1, charId);
  275. ps.setInt(2, charId);
  276. ps.setLong(3, from);
  277. try (ResultSet rset = ps.executeQuery())
  278. {
  279. int charOneId;
  280. int charOneClass;
  281. int charTwoId;
  282. int charTwoClass;
  283. int winner;
  284. long start;
  285. long time;
  286. int classed;
  287. while (rset.next())
  288. {
  289. charOneId = rset.getInt("charOneId");
  290. charOneClass = rset.getInt("charOneClass");
  291. charTwoId = rset.getInt("charTwoId");
  292. charTwoClass = rset.getInt("charTwoClass");
  293. winner = rset.getInt("winner");
  294. start = rset.getLong("start");
  295. time = rset.getLong("time");
  296. classed = rset.getInt("classed");
  297. if (charId == charOneId)
  298. {
  299. String name = CharNameTable.getInstance().getNameById(charTwoId);
  300. String cls = ClassListData.getInstance().getClass(charTwoClass).getClientCode();
  301. if ((name != null) && (cls != null))
  302. {
  303. StatsSet fight = new StatsSet();
  304. fight.set("oponent", name);
  305. fight.set("oponentclass", cls);
  306. fight.set("time", calcFightTime(time));
  307. String date = (new SimpleDateFormat("yyyy-MM-dd HH:mm")).format(new Date(start));
  308. fight.set("start", date);
  309. fight.set("classed", classed);
  310. if (winner == 1)
  311. {
  312. fight.set("result", "<font color=\"00ff00\">victory</font>");
  313. _victorys++;
  314. }
  315. else if (winner == 2)
  316. {
  317. fight.set("result", "<font color=\"ff0000\">loss</font>");
  318. _losses++;
  319. }
  320. else if (winner == 0)
  321. {
  322. fight.set("result", "<font color=\"ffff00\">draw</font>");
  323. _draws++;
  324. }
  325. fights.add(fight);
  326. numberoffights++;
  327. }
  328. }
  329. else if (charId == charTwoId)
  330. {
  331. String name = CharNameTable.getInstance().getNameById(charOneId);
  332. String cls = ClassListData.getInstance().getClass(charOneClass).getClientCode();
  333. if ((name != null) && (cls != null))
  334. {
  335. StatsSet fight = new StatsSet();
  336. fight.set("oponent", name);
  337. fight.set("oponentclass", cls);
  338. fight.set("time", calcFightTime(time));
  339. String date = (new SimpleDateFormat("yyyy-MM-dd HH:mm")).format(new Date(start));
  340. fight.set("start", date);
  341. fight.set("classed", classed);
  342. if (winner == 1)
  343. {
  344. fight.set("result", "<font color=\"ff0000\">loss</font>");
  345. _losses++;
  346. }
  347. else if (winner == 2)
  348. {
  349. fight.set("result", "<font color=\"00ff00\">victory</font>");
  350. _victorys++;
  351. }
  352. else if (winner == 0)
  353. {
  354. fight.set("result", "<font color=\"ffff00\">draw</font>");
  355. _draws++;
  356. }
  357. fights.add(fight);
  358. numberoffights++;
  359. }
  360. }
  361. }
  362. }
  363. heroCountData.set("victory", _victorys);
  364. heroCountData.set("draw", _draws);
  365. heroCountData.set("loss", _losses);
  366. HERO_COUNTS.put(charId, heroCountData);
  367. HERO_FIGHTS.put(charId, fights);
  368. _log.info("Hero System: Loaded " + numberoffights + " fights for Hero: " + CharNameTable.getInstance().getNameById(charId));
  369. }
  370. catch (SQLException e)
  371. {
  372. _log.warning("Hero System: Couldnt load Hero fights history for CharId: " + charId + ": " + e);
  373. }
  374. }
  375. public Map<Integer, StatsSet> getHeroes()
  376. {
  377. return HEROES;
  378. }
  379. public int getHeroByClass(int classid)
  380. {
  381. for (Entry<Integer, StatsSet> e : HEROES.entrySet())
  382. {
  383. if (e.getValue().getInt(Olympiad.CLASS_ID) == classid)
  384. {
  385. return e.getKey();
  386. }
  387. }
  388. return 0;
  389. }
  390. public void resetData()
  391. {
  392. HERO_DIARY.clear();
  393. HERO_FIGHTS.clear();
  394. HERO_COUNTS.clear();
  395. HERO_MESSAGE.clear();
  396. }
  397. public void showHeroDiary(L2PcInstance activeChar, int heroclass, int charid, int page)
  398. {
  399. final int perpage = 10;
  400. final List<StatsSet> mainList = HERO_DIARY.get(charid);
  401. if (mainList != null)
  402. {
  403. final NpcHtmlMessage diaryReply = new NpcHtmlMessage();
  404. final String htmContent = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/olympiad/herodiary.htm");
  405. final String heroMessage = HERO_MESSAGE.get(charid);
  406. if ((htmContent != null) && (heroMessage != null))
  407. {
  408. diaryReply.setHtml(htmContent);
  409. diaryReply.replace("%heroname%", CharNameTable.getInstance().getNameById(charid));
  410. diaryReply.replace("%message%", heroMessage);
  411. diaryReply.disableValidation();
  412. if (!mainList.isEmpty())
  413. {
  414. final List<StatsSet> list = new ArrayList<>(mainList);
  415. Collections.reverse(list);
  416. boolean color = true;
  417. final StringBuilder fList = new StringBuilder(500);
  418. int counter = 0;
  419. int breakat = 0;
  420. for (int i = ((page - 1) * perpage); i < list.size(); i++)
  421. {
  422. breakat = i;
  423. StatsSet diaryEntry = list.get(i);
  424. StringUtil.append(fList, "<tr><td>");
  425. if (color)
  426. {
  427. StringUtil.append(fList, "<table width=270 bgcolor=\"131210\">");
  428. }
  429. else
  430. {
  431. StringUtil.append(fList, "<table width=270>");
  432. }
  433. StringUtil.append(fList, "<tr><td width=270><font color=\"LEVEL\">" + diaryEntry.getString("date") + ":xx</font></td></tr>");
  434. StringUtil.append(fList, "<tr><td width=270>" + diaryEntry.getString("action") + "</td></tr>");
  435. StringUtil.append(fList, "<tr><td>&nbsp;</td></tr></table>");
  436. StringUtil.append(fList, "</td></tr>");
  437. color = !color;
  438. counter++;
  439. if (counter >= perpage)
  440. {
  441. break;
  442. }
  443. }
  444. if (breakat < (list.size() - 1))
  445. {
  446. diaryReply.replace("%buttprev%", "<button value=\"Prev\" action=\"bypass _diary?class=" + heroclass + "&page=" + (page + 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
  447. }
  448. else
  449. {
  450. diaryReply.replace("%buttprev%", "");
  451. }
  452. if (page > 1)
  453. {
  454. diaryReply.replace("%buttnext%", "<button value=\"Next\" action=\"bypass _diary?class=" + heroclass + "&page=" + (page - 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
  455. }
  456. else
  457. {
  458. diaryReply.replace("%buttnext%", "");
  459. }
  460. diaryReply.replace("%list%", fList.toString());
  461. }
  462. else
  463. {
  464. diaryReply.replace("%list%", "");
  465. diaryReply.replace("%buttprev%", "");
  466. diaryReply.replace("%buttnext%", "");
  467. }
  468. activeChar.sendPacket(diaryReply);
  469. }
  470. }
  471. }
  472. public void showHeroFights(L2PcInstance activeChar, int heroclass, int charid, int page)
  473. {
  474. final int perpage = 20;
  475. int _win = 0;
  476. int _loss = 0;
  477. int _draw = 0;
  478. final List<StatsSet> heroFights = HERO_FIGHTS.get(charid);
  479. if (heroFights != null)
  480. {
  481. final NpcHtmlMessage FightReply = new NpcHtmlMessage();
  482. final String htmContent = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/olympiad/herohistory.htm");
  483. if (htmContent != null)
  484. {
  485. FightReply.setHtml(htmContent);
  486. FightReply.replace("%heroname%", CharNameTable.getInstance().getNameById(charid));
  487. if (!heroFights.isEmpty())
  488. {
  489. final StatsSet heroCount = HERO_COUNTS.get(charid);
  490. if (heroCount != null)
  491. {
  492. _win = heroCount.getInt("victory");
  493. _loss = heroCount.getInt("loss");
  494. _draw = heroCount.getInt("draw");
  495. }
  496. boolean color = true;
  497. final StringBuilder fList = new StringBuilder(500);
  498. int counter = 0;
  499. int breakat = 0;
  500. for (int i = ((page - 1) * perpage); i < heroFights.size(); i++)
  501. {
  502. breakat = i;
  503. StatsSet fight = heroFights.get(i);
  504. StringUtil.append(fList, "<tr><td>");
  505. if (color)
  506. {
  507. StringUtil.append(fList, "<table width=270 bgcolor=\"131210\">");
  508. }
  509. else
  510. {
  511. StringUtil.append(fList, "<table width=270>");
  512. }
  513. StringUtil.append(fList, "<tr><td width=220><font color=\"LEVEL\">" + fight.getString("start") + "</font>&nbsp;&nbsp;" + fight.getString("result") + "</td><td width=50 align=right>" + (fight.getInt("classed") > 0 ? "<font color=\"FFFF99\">cls</font>" : "<font color=\"999999\">non-cls<font>") + "</td></tr>");
  514. StringUtil.append(fList, "<tr><td width=220>vs " + fight.getString("oponent") + " (" + fight.getString("oponentclass") + ")</td><td width=50 align=right>(" + fight.getString("time") + ")</td></tr>");
  515. StringUtil.append(fList, "<tr><td colspan=2>&nbsp;</td></tr></table>");
  516. StringUtil.append(fList, "</td></tr>");
  517. color = !color;
  518. counter++;
  519. if (counter >= perpage)
  520. {
  521. break;
  522. }
  523. }
  524. if (breakat < (heroFights.size() - 1))
  525. {
  526. FightReply.replace("%buttprev%", "<button value=\"Prev\" action=\"bypass _match?class=" + heroclass + "&page=" + (page + 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
  527. }
  528. else
  529. {
  530. FightReply.replace("%buttprev%", "");
  531. }
  532. if (page > 1)
  533. {
  534. FightReply.replace("%buttnext%", "<button value=\"Next\" action=\"bypass _match?class=" + heroclass + "&page=" + (page - 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
  535. }
  536. else
  537. {
  538. FightReply.replace("%buttnext%", "");
  539. }
  540. FightReply.replace("%list%", fList.toString());
  541. }
  542. else
  543. {
  544. FightReply.replace("%list%", "");
  545. FightReply.replace("%buttprev%", "");
  546. FightReply.replace("%buttnext%", "");
  547. }
  548. FightReply.replace("%win%", String.valueOf(_win));
  549. FightReply.replace("%draw%", String.valueOf(_draw));
  550. FightReply.replace("%loos%", String.valueOf(_loss));
  551. activeChar.sendPacket(FightReply);
  552. }
  553. }
  554. }
  555. public synchronized void computeNewHeroes(List<StatsSet> newHeroes)
  556. {
  557. updateHeroes(true);
  558. for (Integer objectId : HEROES.keySet())
  559. {
  560. final L2PcInstance player = L2World.getInstance().getPlayer(objectId);
  561. if (player == null)
  562. {
  563. continue;
  564. }
  565. player.setHero(false);
  566. for (int i = 0; i < Inventory.PAPERDOLL_TOTALSLOTS; i++)
  567. {
  568. L2ItemInstance equippedItem = player.getInventory().getPaperdollItem(i);
  569. if ((equippedItem != null) && equippedItem.isHeroItem())
  570. {
  571. player.getInventory().unEquipItemInSlot(i);
  572. }
  573. }
  574. final InventoryUpdate iu = new InventoryUpdate();
  575. for (L2ItemInstance item : player.getInventory().getAvailableItems(false, false, false))
  576. {
  577. if ((item != null) && item.isHeroItem())
  578. {
  579. player.destroyItem("Hero", item, null, true);
  580. iu.addRemovedItem(item);
  581. }
  582. }
  583. if (!iu.getItems().isEmpty())
  584. {
  585. player.sendPacket(iu);
  586. }
  587. player.broadcastUserInfo();
  588. }
  589. deleteItemsInDb();
  590. HEROES.clear();
  591. if (newHeroes.isEmpty())
  592. {
  593. return;
  594. }
  595. for (StatsSet hero : newHeroes)
  596. {
  597. int charId = hero.getInt(Olympiad.CHAR_ID);
  598. if (COMPLETE_HEROS.containsKey(charId))
  599. {
  600. StatsSet oldHero = COMPLETE_HEROS.get(charId);
  601. int count = oldHero.getInt(COUNT);
  602. oldHero.set(COUNT, count + 1);
  603. oldHero.set(PLAYED, 1);
  604. oldHero.set(CLAIMED, false);
  605. HEROES.put(charId, oldHero);
  606. }
  607. else
  608. {
  609. StatsSet newHero = new StatsSet();
  610. newHero.set(Olympiad.CHAR_NAME, hero.getString(Olympiad.CHAR_NAME));
  611. newHero.set(Olympiad.CLASS_ID, hero.getInt(Olympiad.CLASS_ID));
  612. newHero.set(COUNT, 1);
  613. newHero.set(PLAYED, 1);
  614. newHero.set(CLAIMED, false);
  615. HEROES.put(charId, newHero);
  616. }
  617. }
  618. updateHeroes(false);
  619. }
  620. public void updateHeroes(boolean setDefault)
  621. {
  622. try (Connection con = ConnectionFactory.getInstance().getConnection())
  623. {
  624. if (setDefault)
  625. {
  626. try (Statement s = con.createStatement())
  627. {
  628. s.executeUpdate(UPDATE_ALL);
  629. }
  630. }
  631. else
  632. {
  633. StatsSet hero;
  634. int heroId;
  635. for (Entry<Integer, StatsSet> entry : HEROES.entrySet())
  636. {
  637. hero = entry.getValue();
  638. heroId = entry.getKey();
  639. if (!COMPLETE_HEROS.containsKey(heroId))
  640. {
  641. try (PreparedStatement insert = con.prepareStatement(INSERT_HERO))
  642. {
  643. insert.setInt(1, heroId);
  644. insert.setInt(2, hero.getInt(Olympiad.CLASS_ID));
  645. insert.setInt(3, hero.getInt(COUNT));
  646. insert.setInt(4, hero.getInt(PLAYED));
  647. insert.setString(5, String.valueOf(hero.getBoolean(CLAIMED)));
  648. insert.execute();
  649. insert.close();
  650. }
  651. try (PreparedStatement statement = con.prepareStatement(GET_CLAN_ALLY))
  652. {
  653. statement.setInt(1, heroId);
  654. try (ResultSet rset = statement.executeQuery())
  655. {
  656. if (rset.next())
  657. {
  658. int clanId = rset.getInt("clanid");
  659. int allyId = rset.getInt("allyId");
  660. String clanName = "";
  661. String allyName = "";
  662. int clanCrest = 0;
  663. int allyCrest = 0;
  664. if (clanId > 0)
  665. {
  666. clanName = ClanTable.getInstance().getClan(clanId).getName();
  667. clanCrest = ClanTable.getInstance().getClan(clanId).getCrestId();
  668. if (allyId > 0)
  669. {
  670. allyName = ClanTable.getInstance().getClan(clanId).getAllyName();
  671. allyCrest = ClanTable.getInstance().getClan(clanId).getAllyCrestId();
  672. }
  673. }
  674. hero.set(CLAN_CREST, clanCrest);
  675. hero.set(CLAN_NAME, clanName);
  676. hero.set(ALLY_CREST, allyCrest);
  677. hero.set(ALLY_NAME, allyName);
  678. }
  679. }
  680. }
  681. HEROES.put(heroId, hero);
  682. COMPLETE_HEROS.put(heroId, hero);
  683. }
  684. else
  685. {
  686. try (PreparedStatement statement = con.prepareStatement(UPDATE_HERO))
  687. {
  688. statement.setInt(1, hero.getInt(COUNT));
  689. statement.setInt(2, hero.getInt(PLAYED));
  690. statement.setString(3, String.valueOf(hero.getBoolean(CLAIMED)));
  691. statement.setInt(4, heroId);
  692. statement.execute();
  693. }
  694. }
  695. }
  696. }
  697. }
  698. catch (SQLException e)
  699. {
  700. _log.warning("Hero System: Couldnt update Heroes: " + e.getMessage());
  701. }
  702. }
  703. public void setHeroGained(int charId)
  704. {
  705. setDiaryData(charId, ACTION_HERO_GAINED, 0);
  706. }
  707. public void setRBkilled(int charId, int npcId)
  708. {
  709. setDiaryData(charId, ACTION_RAID_KILLED, npcId);
  710. final L2NpcTemplate template = NpcData.getInstance().getTemplate(npcId);
  711. final List<StatsSet> list = HERO_DIARY.get(charId);
  712. if ((list != null) && (template != null))
  713. {
  714. // Prepare new data
  715. final StatsSet diaryEntry = new StatsSet();
  716. final String date = (new SimpleDateFormat("yyyy-MM-dd HH")).format(new Date(System.currentTimeMillis()));
  717. diaryEntry.set("date", date);
  718. diaryEntry.set("action", template.getName() + " was defeated");
  719. // Add to old list
  720. list.add(diaryEntry);
  721. }
  722. }
  723. public void setCastleTaken(int charId, int castleId)
  724. {
  725. setDiaryData(charId, ACTION_CASTLE_TAKEN, castleId);
  726. final Castle castle = CastleManager.getInstance().getCastleById(castleId);
  727. final List<StatsSet> list = HERO_DIARY.get(charId);
  728. if ((list != null) && (castle != null))
  729. {
  730. // Prepare new data
  731. final StatsSet diaryEntry = new StatsSet();
  732. final String date = (new SimpleDateFormat("yyyy-MM-dd HH")).format(new Date(System.currentTimeMillis()));
  733. diaryEntry.set("date", date);
  734. diaryEntry.set("action", castle.getName() + " Castle was successfuly taken");
  735. // Add to old list
  736. list.add(diaryEntry);
  737. }
  738. }
  739. public void setDiaryData(int charId, int action, int param)
  740. {
  741. try (Connection con = ConnectionFactory.getInstance().getConnection();
  742. PreparedStatement ps = con.prepareStatement("INSERT INTO heroes_diary (charId, time, action, param) values(?,?,?,?)"))
  743. {
  744. ps.setInt(1, charId);
  745. ps.setLong(2, System.currentTimeMillis());
  746. ps.setInt(3, action);
  747. ps.setInt(4, param);
  748. ps.execute();
  749. }
  750. catch (SQLException e)
  751. {
  752. _log.severe("SQL exception while saving DiaryData: " + e.getMessage());
  753. }
  754. }
  755. /**
  756. * Set new hero message for hero
  757. * @param player the player instance
  758. * @param message String to set
  759. */
  760. public void setHeroMessage(L2PcInstance player, String message)
  761. {
  762. HERO_MESSAGE.put(player.getObjectId(), message);
  763. }
  764. /**
  765. * Update hero message in database
  766. * @param charId character objid
  767. */
  768. public void saveHeroMessage(int charId)
  769. {
  770. if (HERO_MESSAGE.containsKey(charId))
  771. {
  772. return;
  773. }
  774. try (Connection con = ConnectionFactory.getInstance().getConnection();
  775. PreparedStatement ps = con.prepareStatement("UPDATE heroes SET message=? WHERE charId=?;"))
  776. {
  777. ps.setString(1, HERO_MESSAGE.get(charId));
  778. ps.setInt(2, charId);
  779. ps.execute();
  780. }
  781. catch (SQLException e)
  782. {
  783. _log.severe("SQL exception while saving HeroMessage:" + e.getMessage());
  784. }
  785. }
  786. private void deleteItemsInDb()
  787. {
  788. try (Connection con = ConnectionFactory.getInstance().getConnection();
  789. Statement s = con.createStatement())
  790. {
  791. s.executeUpdate(DELETE_ITEMS);
  792. }
  793. catch (SQLException e)
  794. {
  795. _log.warning("Heroes: " + e.getMessage());
  796. }
  797. }
  798. /**
  799. * Saving task for {@link Hero}<BR>
  800. * Save all hero messages to DB.
  801. */
  802. public void shutdown()
  803. {
  804. HERO_MESSAGE.keySet().forEach(c -> saveHeroMessage(c));
  805. }
  806. /**
  807. * Verifies if the given object ID belongs to a claimed hero.
  808. * @param objectId the player's object ID to verify
  809. * @return {@code true} if there are heros and the player is in the list, {@code false} otherwise
  810. */
  811. public boolean isHero(int objectId)
  812. {
  813. return HEROES.containsKey(objectId) && HEROES.get(objectId).getBoolean(CLAIMED);
  814. }
  815. /**
  816. * Verifies if the given object ID belongs to an unclaimed hero.
  817. * @param objectId the player's object ID to verify
  818. * @return {@code true} if player is unclaimed hero
  819. */
  820. public boolean isUnclaimedHero(int objectId)
  821. {
  822. return HEROES.containsKey(objectId) && !HEROES.get(objectId).getBoolean(CLAIMED);
  823. }
  824. /**
  825. * Claims the hero status for the given player.
  826. * @param player the player to become hero
  827. */
  828. public void claimHero(L2PcInstance player)
  829. {
  830. StatsSet hero = HEROES.get(player.getObjectId());
  831. if (hero == null)
  832. {
  833. hero = new StatsSet();
  834. HEROES.put(player.getObjectId(), hero);
  835. }
  836. hero.set(CLAIMED, true);
  837. final L2Clan clan = player.getClan();
  838. if ((clan != null) && (clan.getLevel() >= 5))
  839. {
  840. clan.addReputationScore(Config.HERO_POINTS, true);
  841. final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.CLAN_MEMBER_C1_BECAME_HERO_AND_GAINED_S2_REPUTATION_POINTS);
  842. sm.addString(CharNameTable.getInstance().getNameById(player.getObjectId()));
  843. sm.addInt(Config.HERO_POINTS);
  844. clan.broadcastToOnlineMembers(sm);
  845. }
  846. player.setHero(true);
  847. player.broadcastPacket(new SocialAction(player.getObjectId(), 20016)); // Hero Animation
  848. player.sendPacket(new UserInfo(player));
  849. player.sendPacket(new ExBrExtraUserInfo(player));
  850. player.broadcastUserInfo();
  851. // Set Gained hero and reload data
  852. setHeroGained(player.getObjectId());
  853. loadFights(player.getObjectId());
  854. loadDiary(player.getObjectId());
  855. HERO_MESSAGE.put(player.getObjectId(), "");
  856. updateHeroes(false);
  857. }
  858. public static Hero getInstance()
  859. {
  860. return SingletonHolder.INSTANCE;
  861. }
  862. private static class SingletonHolder
  863. {
  864. protected static final Hero INSTANCE = new Hero();
  865. }
  866. }