AutoChatHandler.java 27 KB

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