AutoChatHandler.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package com.l2jserver.gameserver.model;
  16. import java.sql.Connection;
  17. import java.sql.PreparedStatement;
  18. import java.sql.ResultSet;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.concurrent.ScheduledFuture;
  22. import java.util.logging.Level;
  23. import java.util.logging.Logger;
  24. import com.l2jserver.Config;
  25. import com.l2jserver.L2DatabaseFactory;
  26. import com.l2jserver.gameserver.SevenSigns;
  27. import com.l2jserver.gameserver.ThreadPoolManager;
  28. import com.l2jserver.gameserver.model.actor.L2Character;
  29. import com.l2jserver.gameserver.model.actor.L2Npc;
  30. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  31. import com.l2jserver.gameserver.model.actor.instance.L2DefenderInstance;
  32. import com.l2jserver.gameserver.network.clientpackets.Say2;
  33. import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
  34. import com.l2jserver.util.Rnd;
  35. import javolution.util.FastList;
  36. import javolution.util.FastMap;
  37. /**
  38. * Auto Chat Handler
  39. *
  40. * Allows NPCs to automatically send messages to nearby players
  41. * at a set time interval.
  42. *
  43. * @author Tempy
  44. */
  45. public class AutoChatHandler implements SpawnListener
  46. {
  47. protected static final Logger _log = Logger.getLogger(AutoChatHandler.class.getName());
  48. private static final long DEFAULT_CHAT_DELAY = 30000; // 30 secs by default
  49. protected Map<Integer, AutoChatInstance> _registeredChats;
  50. private AutoChatHandler()
  51. {
  52. _registeredChats = new FastMap<Integer, AutoChatInstance>();
  53. restoreChatData();
  54. L2Spawn.addSpawnListener(this);
  55. }
  56. private void restoreChatData()
  57. {
  58. int numLoaded = 0;
  59. Connection con = null;
  60. PreparedStatement statement = null;
  61. PreparedStatement statement2 = null;
  62. ResultSet rs = null;
  63. ResultSet rs2 = null;
  64. try
  65. {
  66. con = L2DatabaseFactory.getInstance().getConnection();
  67. statement = con.prepareStatement("SELECT * FROM auto_chat ORDER BY groupId ASC");
  68. rs = statement.executeQuery();
  69. statement2 = con.prepareStatement("SELECT * FROM auto_chat_text WHERE groupId=?");
  70. while (rs.next())
  71. {
  72. numLoaded++;
  73. statement2.setInt(1, rs.getInt("groupId"));
  74. rs2 = statement2.executeQuery();
  75. statement2.clearParameters();
  76. rs2.last();
  77. String[] chatTexts = new String[rs2.getRow()];
  78. int i = 0;
  79. rs2.beforeFirst();
  80. while (rs2.next())
  81. {
  82. chatTexts[i++] = rs2.getString("chatText");
  83. }
  84. registerGlobalChat(rs.getInt("npcId"), chatTexts, rs.getLong("chatDelay"));
  85. }
  86. statement2.close();
  87. rs.close();
  88. statement.close();
  89. if (Config.DEBUG)
  90. _log.info("AutoChatHandler: Loaded " + numLoaded + " chat group(s) from the database.");
  91. }
  92. catch (Exception e)
  93. {
  94. _log.log(Level.WARNING, "AutoSpawnHandler: Could not restore chat data: " + e.getMessage(), e);
  95. }
  96. finally
  97. {
  98. L2DatabaseFactory.close(con);
  99. }
  100. }
  101. public void reload()
  102. {
  103. // unregister all registered spawns
  104. for (AutoChatInstance aci : _registeredChats.values())
  105. {
  106. if (aci != null)
  107. {
  108. // clear timer
  109. if (aci._chatTask != null)
  110. aci._chatTask.cancel(true);
  111. this.removeChat(aci);
  112. }
  113. }
  114. // create clean list
  115. _registeredChats = new FastMap<Integer, AutoChatInstance>();
  116. // load
  117. restoreChatData();
  118. }
  119. public static AutoChatHandler getInstance()
  120. {
  121. return SingletonHolder._instance;
  122. }
  123. public int size()
  124. {
  125. return _registeredChats.size();
  126. }
  127. /**
  128. * Registers a globally active auto chat for ALL instances of the given NPC ID.
  129. * <BR>
  130. * Returns the associated auto chat instance.
  131. *
  132. * @param int npcId
  133. * @param String[] chatTexts
  134. * @param int chatDelay (-1 = default delay)
  135. * @return AutoChatInstance chatInst
  136. */
  137. public AutoChatInstance registerGlobalChat(int npcId, String[] chatTexts, long chatDelay)
  138. {
  139. return registerChat(npcId, null, chatTexts, chatDelay);
  140. }
  141. /**
  142. * Registers a NON globally-active auto chat for the given NPC instance, and adds to the currently
  143. * assigned chat instance for this NPC ID, otherwise creates a new instance if
  144. * a previous one is not found.
  145. * <BR>
  146. * Returns the associated auto chat instance.
  147. *
  148. * @param L2Npc npcInst
  149. * @param String[] chatTexts
  150. * @param int chatDelay (-1 = default delay)
  151. * @return AutoChatInstance chatInst
  152. */
  153. public AutoChatInstance registerChat(L2Npc npcInst, String[] chatTexts, long chatDelay)
  154. {
  155. return registerChat(npcInst.getNpcId(), npcInst, chatTexts, chatDelay);
  156. }
  157. private final AutoChatInstance registerChat(int npcId, L2Npc npcInst, String[] chatTexts, long chatDelay)
  158. {
  159. AutoChatInstance chatInst = null;
  160. if (chatDelay < 0)
  161. chatDelay = DEFAULT_CHAT_DELAY;
  162. if (_registeredChats.containsKey(npcId))
  163. chatInst = _registeredChats.get(npcId);
  164. else
  165. chatInst = new AutoChatInstance(npcId, chatTexts, chatDelay, (npcInst == null));
  166. if (npcInst != null)
  167. chatInst.addChatDefinition(npcInst);
  168. _registeredChats.put(npcId, chatInst);
  169. return chatInst;
  170. }
  171. /**
  172. * Removes and cancels ALL auto chat definition for the given NPC ID,
  173. * and removes its chat instance if it exists.
  174. *
  175. * @param int npcId
  176. * @return boolean removedSuccessfully
  177. */
  178. public boolean removeChat(int npcId)
  179. {
  180. AutoChatInstance chatInst = _registeredChats.get(npcId);
  181. return removeChat(chatInst);
  182. }
  183. /**
  184. * Removes and cancels ALL auto chats for the given chat instance.
  185. *
  186. * @param AutoChatInstance chatInst
  187. * @return boolean removedSuccessfully
  188. */
  189. public boolean removeChat(AutoChatInstance chatInst)
  190. {
  191. if (chatInst == null)
  192. return false;
  193. _registeredChats.remove(chatInst.getNPCId());
  194. chatInst.setActive(false);
  195. if (Config.DEBUG)
  196. _log.info("AutoChatHandler: Removed auto chat for NPC ID " + chatInst.getNPCId());
  197. return true;
  198. }
  199. /**
  200. * Returns the associated auto chat instance either by the given NPC ID
  201. * or object ID.
  202. *
  203. * @param int id
  204. * @param boolean byObjectId
  205. * @return AutoChatInstance chatInst
  206. */
  207. public AutoChatInstance getAutoChatInstance(int id, boolean byObjectId)
  208. {
  209. if (!byObjectId)
  210. return _registeredChats.get(id);
  211. else
  212. for (AutoChatInstance chatInst : _registeredChats.values())
  213. if (chatInst.getChatDefinition(id) != null)
  214. return chatInst;
  215. return null;
  216. }
  217. /**
  218. * Sets the active state of all auto chat instances to that specified,
  219. * and cancels the scheduled chat task if necessary.
  220. *
  221. * @param boolean isActive
  222. */
  223. public void setAutoChatActive(boolean isActive)
  224. {
  225. for (AutoChatInstance chatInst : _registeredChats.values())
  226. chatInst.setActive(isActive);
  227. }
  228. /**
  229. * Used in conjunction with a SpawnListener, this method is called every time
  230. * an NPC is spawned in the world.
  231. * <BR><BR>
  232. * If an auto chat instance is set to be "global", all instances matching the registered
  233. * NPC ID will be added to that chat instance.
  234. */
  235. public void npcSpawned(L2Npc npc)
  236. {
  237. synchronized (_registeredChats)
  238. {
  239. if (npc == null)
  240. return;
  241. int npcId = npc.getNpcId();
  242. if (_registeredChats.containsKey(npcId))
  243. {
  244. AutoChatInstance chatInst = _registeredChats.get(npcId);
  245. if (chatInst != null && chatInst.isGlobal())
  246. chatInst.addChatDefinition(npc);
  247. }
  248. }
  249. }
  250. /**
  251. * Auto Chat Instance
  252. * <BR><BR>
  253. * Manages the auto chat instances for a specific registered NPC ID.
  254. *
  255. * @author Tempy
  256. */
  257. public class AutoChatInstance
  258. {
  259. protected int _npcId;
  260. private long _defaultDelay = DEFAULT_CHAT_DELAY;
  261. private String[] _defaultTexts;
  262. private boolean _defaultRandom = false;
  263. private boolean _globalChat = false;
  264. private boolean _isActive;
  265. private Map<Integer, AutoChatDefinition> _chatDefinitions = new FastMap<Integer, AutoChatDefinition>();
  266. protected ScheduledFuture<?> _chatTask;
  267. protected AutoChatInstance(int npcId, String[] chatTexts, long chatDelay, boolean isGlobal)
  268. {
  269. _defaultTexts = chatTexts;
  270. _npcId = npcId;
  271. _defaultDelay = chatDelay;
  272. _globalChat = isGlobal;
  273. if (Config.DEBUG)
  274. _log.info("AutoChatHandler: Registered auto chat for NPC ID " + _npcId + " (Global Chat = " + _globalChat + ").");
  275. setActive(true);
  276. }
  277. protected AutoChatDefinition getChatDefinition(int objectId)
  278. {
  279. return _chatDefinitions.get(objectId);
  280. }
  281. protected AutoChatDefinition[] getChatDefinitions()
  282. {
  283. return _chatDefinitions.values().toArray(new AutoChatDefinition[_chatDefinitions.values().size()]);
  284. }
  285. /**
  286. * Defines an auto chat for an instance matching this auto chat instance's registered NPC ID,
  287. * and launches the scheduled chat task.
  288. * <BR>
  289. * Returns the object ID for the NPC instance, with which to refer
  290. * to the created chat definition.
  291. * <BR>
  292. * <B>Note</B>: Uses pre-defined default values for texts and chat delays from the chat instance.
  293. *
  294. * @param L2Npc npcInst
  295. * @return int objectId
  296. */
  297. public int addChatDefinition(L2Npc npcInst)
  298. {
  299. return addChatDefinition(npcInst, null, 0);
  300. }
  301. /**
  302. * Defines an auto chat for an instance matching this auto chat instance's registered NPC ID,
  303. * and launches the scheduled chat task.
  304. * <BR>
  305. * Returns the object ID for the NPC instance, with which to refer
  306. * to the created chat definition.
  307. *
  308. * @param L2Npc npcInst
  309. * @param String[] chatTexts
  310. * @param int chatDelay
  311. * @return int objectId
  312. */
  313. public int addChatDefinition(L2Npc npcInst, String[] chatTexts, long chatDelay)
  314. {
  315. int objectId = npcInst.getObjectId();
  316. AutoChatDefinition chatDef = new AutoChatDefinition(this, npcInst, chatTexts, chatDelay);
  317. if (npcInst instanceof L2DefenderInstance)
  318. chatDef.setRandomChat(true);
  319. _chatDefinitions.put(objectId, chatDef);
  320. return objectId;
  321. }
  322. /**
  323. * Removes a chat definition specified by the given object ID.
  324. *
  325. * @param int objectId
  326. * @return boolean removedSuccessfully
  327. */
  328. public boolean removeChatDefinition(int objectId)
  329. {
  330. if (!_chatDefinitions.containsKey(objectId))
  331. return false;
  332. AutoChatDefinition chatDefinition = _chatDefinitions.get(objectId);
  333. chatDefinition.setActive(false);
  334. _chatDefinitions.remove(objectId);
  335. return true;
  336. }
  337. /**
  338. * Tests if this auto chat instance is active.
  339. *
  340. * @return boolean isActive
  341. */
  342. public boolean isActive()
  343. {
  344. return _isActive;
  345. }
  346. /**
  347. * Tests if this auto chat instance applies to
  348. * ALL currently spawned instances of the registered NPC ID.
  349. *
  350. * @return boolean isGlobal
  351. */
  352. public boolean isGlobal()
  353. {
  354. return _globalChat;
  355. }
  356. /**
  357. * Tests if random order is the DEFAULT for new chat definitions.
  358. *
  359. * @return boolean isRandom
  360. */
  361. public boolean isDefaultRandom()
  362. {
  363. return _defaultRandom;
  364. }
  365. /**
  366. * Tests if the auto chat definition given by its object ID is set to be random.
  367. *
  368. * @return boolean isRandom
  369. */
  370. public boolean isRandomChat(int objectId)
  371. {
  372. if (!_chatDefinitions.containsKey(objectId))
  373. return false;
  374. return _chatDefinitions.get(objectId).isRandomChat();
  375. }
  376. /**
  377. * Returns the ID of the NPC type managed by this auto chat instance.
  378. *
  379. * @return int npcId
  380. */
  381. public int getNPCId()
  382. {
  383. return _npcId;
  384. }
  385. /**
  386. * Returns the number of auto chat definitions stored for this instance.
  387. *
  388. * @return int definitionCount
  389. */
  390. public int getDefinitionCount()
  391. {
  392. return _chatDefinitions.size();
  393. }
  394. /**
  395. * Returns a list of all NPC instances handled by this auto chat instance.
  396. *
  397. * @return L2NpcInstance[] npcInsts
  398. */
  399. public L2Npc[] getNPCInstanceList()
  400. {
  401. List<L2Npc> npcInsts = new FastList<L2Npc>();
  402. for (AutoChatDefinition chatDefinition : _chatDefinitions.values())
  403. npcInsts.add(chatDefinition._npcInstance);
  404. return npcInsts.toArray(new L2Npc[npcInsts.size()]);
  405. }
  406. /**
  407. * A series of methods used to get and set default values for new chat definitions.
  408. */
  409. public long getDefaultDelay()
  410. {
  411. return _defaultDelay;
  412. }
  413. public String[] getDefaultTexts()
  414. {
  415. return _defaultTexts;
  416. }
  417. public void setDefaultChatDelay(long delayValue)
  418. {
  419. _defaultDelay = delayValue;
  420. }
  421. public void setDefaultChatTexts(String[] textsValue)
  422. {
  423. _defaultTexts = textsValue;
  424. }
  425. public void setDefaultRandom(boolean randValue)
  426. {
  427. _defaultRandom = randValue;
  428. }
  429. /**
  430. * Sets a specific chat delay for the specified auto chat definition given by its object ID.
  431. *
  432. * @param int objectId
  433. * @param long delayValue
  434. */
  435. public void setChatDelay(int objectId, long delayValue)
  436. {
  437. AutoChatDefinition chatDef = getChatDefinition(objectId);
  438. if (chatDef != null)
  439. chatDef.setChatDelay(delayValue);
  440. }
  441. /**
  442. * Sets a specific set of chat texts for the specified auto chat definition given by its object ID.
  443. *
  444. * @param int objectId
  445. * @param String[] textsValue
  446. */
  447. public void setChatTexts(int objectId, String[] textsValue)
  448. {
  449. AutoChatDefinition chatDef = getChatDefinition(objectId);
  450. if (chatDef != null)
  451. chatDef.setChatTexts(textsValue);
  452. }
  453. /**
  454. * Sets specifically to use random chat order for the auto chat definition given by its object ID.
  455. *
  456. * @param int objectId
  457. * @param boolean randValue
  458. */
  459. public void setRandomChat(int objectId, boolean randValue)
  460. {
  461. AutoChatDefinition chatDef = getChatDefinition(objectId);
  462. if (chatDef != null)
  463. chatDef.setRandomChat(randValue);
  464. }
  465. /**
  466. * Sets the activity of ALL auto chat definitions handled by this chat instance.
  467. *
  468. * @param boolean isActive
  469. */
  470. public void setActive(boolean activeValue)
  471. {
  472. if (_isActive == activeValue)
  473. return;
  474. _isActive = activeValue;
  475. if (!isGlobal())
  476. {
  477. for (AutoChatDefinition chatDefinition : _chatDefinitions.values())
  478. chatDefinition.setActive(activeValue);
  479. return;
  480. }
  481. if (isActive())
  482. {
  483. AutoChatRunner acr = new AutoChatRunner(_npcId, -1);
  484. _chatTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(acr, _defaultDelay, _defaultDelay);
  485. }
  486. else
  487. {
  488. _chatTask.cancel(false);
  489. }
  490. }
  491. /**
  492. * Auto Chat Definition
  493. * <BR><BR>
  494. * Stores information about specific chat data for an instance of the NPC ID
  495. * specified by the containing auto chat instance.
  496. * <BR>
  497. * Each NPC instance of this type should be stored in a subsequent AutoChatDefinition class.
  498. *
  499. * @author Tempy
  500. */
  501. private class AutoChatDefinition
  502. {
  503. protected int _chatIndex = 0;
  504. protected L2Npc _npcInstance;
  505. protected AutoChatInstance _chatInstance;
  506. private long _chatDelay = 0;
  507. private String[] _chatTexts = null;
  508. private boolean _isActiveDefinition;
  509. private boolean _randomChat;
  510. protected AutoChatDefinition(AutoChatInstance chatInst, L2Npc npcInst, String[] chatTexts, long chatDelay)
  511. {
  512. _npcInstance = npcInst;
  513. _chatInstance = chatInst;
  514. _randomChat = chatInst.isDefaultRandom();
  515. _chatDelay = chatDelay;
  516. _chatTexts = chatTexts;
  517. if (Config.DEBUG)
  518. _log.info("AutoChatHandler: Chat definition added for NPC ID " + _npcInstance.getNpcId() + " (Object ID = "
  519. + _npcInstance.getObjectId() + ").");
  520. // If global chat isn't enabled for the parent instance,
  521. // then handle the chat task locally.
  522. if (!chatInst.isGlobal())
  523. setActive(true);
  524. }
  525. protected String[] getChatTexts()
  526. {
  527. if (_chatTexts != null)
  528. return _chatTexts;
  529. else
  530. return _chatInstance.getDefaultTexts();
  531. }
  532. private long getChatDelay()
  533. {
  534. if (_chatDelay > 0)
  535. return _chatDelay;
  536. else
  537. return _chatInstance.getDefaultDelay();
  538. }
  539. private boolean isActive()
  540. {
  541. return _isActiveDefinition;
  542. }
  543. boolean isRandomChat()
  544. {
  545. return _randomChat;
  546. }
  547. void setRandomChat(boolean randValue)
  548. {
  549. _randomChat = randValue;
  550. }
  551. void setChatDelay(long delayValue)
  552. {
  553. _chatDelay = delayValue;
  554. }
  555. void setChatTexts(String[] textsValue)
  556. {
  557. _chatTexts = textsValue;
  558. }
  559. void setActive(boolean activeValue)
  560. {
  561. if (isActive() == activeValue)
  562. return;
  563. if (activeValue)
  564. {
  565. AutoChatRunner acr = new AutoChatRunner(_npcId, _npcInstance.getObjectId());
  566. if (getChatDelay() == 0)
  567. // Schedule it set to 5Ms, isn't error, if use 0 sometine
  568. // chatDefinition return null in AutoChatRunner
  569. _chatTask = ThreadPoolManager.getInstance().scheduleGeneral(acr, 5);
  570. else
  571. _chatTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(acr, getChatDelay(), getChatDelay());
  572. }
  573. else
  574. {
  575. _chatTask.cancel(false);
  576. }
  577. _isActiveDefinition = activeValue;
  578. }
  579. }
  580. /**
  581. * Auto Chat Runner
  582. * <BR><BR>
  583. * Represents the auto chat scheduled task for each chat instance.
  584. *
  585. * @author Tempy
  586. */
  587. private class AutoChatRunner implements Runnable
  588. {
  589. private int _runnerNpcId;
  590. private int _objectId;
  591. protected AutoChatRunner(int pNpcId, int pObjectId)
  592. {
  593. _runnerNpcId = pNpcId;
  594. _objectId = pObjectId;
  595. }
  596. public synchronized void run()
  597. {
  598. AutoChatInstance chatInst = _registeredChats.get(_runnerNpcId);
  599. AutoChatDefinition[] chatDefinitions;
  600. if (chatInst.isGlobal())
  601. {
  602. chatDefinitions = chatInst.getChatDefinitions();
  603. }
  604. else
  605. {
  606. AutoChatDefinition chatDef = chatInst.getChatDefinition(_objectId);
  607. if (chatDef == null)
  608. {
  609. _log.warning("AutoChatHandler: Auto chat definition is NULL for NPC ID " + _npcId + ".");
  610. return;
  611. }
  612. chatDefinitions = new AutoChatDefinition[] { chatDef };
  613. }
  614. if (Config.DEBUG)
  615. _log.info("AutoChatHandler: Running auto chat for " + chatDefinitions.length + " instances of NPC ID " + _npcId + "."
  616. + " (Global Chat = " + chatInst.isGlobal() + ")");
  617. for (AutoChatDefinition chatDef : chatDefinitions)
  618. {
  619. try
  620. {
  621. L2Npc chatNpc = chatDef._npcInstance;
  622. List<L2PcInstance> nearbyPlayers = new FastList<L2PcInstance>();
  623. List<L2PcInstance> nearbyGMs = new FastList<L2PcInstance>();
  624. for (L2Character player : chatNpc.getKnownList().getKnownCharactersInRadius(1500))
  625. {
  626. if (!(player instanceof L2PcInstance))
  627. continue;
  628. if (((L2PcInstance) player).isGM())
  629. nearbyGMs.add((L2PcInstance) player);
  630. else
  631. nearbyPlayers.add((L2PcInstance) player);
  632. }
  633. int maxIndex = chatDef.getChatTexts().length;
  634. int lastIndex = Rnd.nextInt(maxIndex);
  635. String creatureName = chatNpc.getName();
  636. String text;
  637. if (!chatDef.isRandomChat())
  638. {
  639. lastIndex = chatDef._chatIndex + 1;
  640. if (lastIndex == maxIndex)
  641. lastIndex = 0;
  642. chatDef._chatIndex = lastIndex;
  643. }
  644. text = chatDef.getChatTexts()[lastIndex];
  645. if (text == null)
  646. return;
  647. if (!nearbyPlayers.isEmpty())
  648. {
  649. int randomPlayerIndex = Rnd.nextInt(nearbyPlayers.size());
  650. L2PcInstance randomPlayer = nearbyPlayers.get(randomPlayerIndex);
  651. final int winningCabal = SevenSigns.getInstance().getCabalHighestScore();
  652. int losingCabal = SevenSigns.CABAL_NULL;
  653. if (winningCabal == SevenSigns.CABAL_DAWN)
  654. losingCabal = SevenSigns.CABAL_DUSK;
  655. else if (winningCabal == SevenSigns.CABAL_DUSK)
  656. losingCabal = SevenSigns.CABAL_DAWN;
  657. if (text.indexOf("%player_random%") > -1)
  658. text = text.replaceAll("%player_random%", randomPlayer.getName());
  659. if (text.indexOf("%player_cabal_winner%") > -1)
  660. {
  661. for (L2PcInstance nearbyPlayer : nearbyPlayers)
  662. {
  663. if (SevenSigns.getInstance().getPlayerCabal(nearbyPlayer.getObjectId()) == winningCabal)
  664. {
  665. text = text.replaceAll("%player_cabal_winner%", nearbyPlayer.getName());
  666. break;
  667. }
  668. }
  669. }
  670. if (text.indexOf("%player_cabal_loser%") > -1)
  671. {
  672. for (L2PcInstance nearbyPlayer : nearbyPlayers)
  673. {
  674. if (SevenSigns.getInstance().getPlayerCabal(nearbyPlayer.getObjectId()) == losingCabal)
  675. {
  676. text = text.replaceAll("%player_cabal_loser%", nearbyPlayer.getName());
  677. break;
  678. }
  679. }
  680. }
  681. }
  682. if (text == null)
  683. return;
  684. if (text.contains("%player_cabal_loser%") || text.contains("%player_cabal_winner%")
  685. || text.contains("%player_random%"))
  686. return;
  687. CreatureSay cs = new CreatureSay(chatNpc.getObjectId(), Say2.ALL, creatureName, text);
  688. for (L2PcInstance nearbyPlayer : nearbyPlayers)
  689. nearbyPlayer.sendPacket(cs);
  690. for (L2PcInstance nearbyGM : nearbyGMs)
  691. nearbyGM.sendPacket(cs);
  692. if (Config.DEBUG)
  693. _log.fine("AutoChatHandler: Chat propogation for object ID " + chatNpc.getObjectId() + " (" + creatureName
  694. + ") with text '" + text + "' sent to " + nearbyPlayers.size() + " nearby players.");
  695. }
  696. catch (Exception e)
  697. {
  698. _log.log(Level.WARNING, "Exception on AutoChatRunner.run(): " + e.getMessage(), e);
  699. return;
  700. }
  701. }
  702. }
  703. }
  704. }
  705. @SuppressWarnings("synthetic-access")
  706. private static class SingletonHolder
  707. {
  708. protected static final AutoChatHandler _instance = new AutoChatHandler();
  709. }
  710. }