PetitionManager.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  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.instancemanager;
  16. import java.text.SimpleDateFormat;
  17. import java.util.Date;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.logging.Logger;
  21. import javolution.text.TextBuilder;
  22. import javolution.util.FastList;
  23. import javolution.util.FastMap;
  24. import net.sf.l2j.Config;
  25. import net.sf.l2j.gameserver.GmListTable;
  26. import net.sf.l2j.gameserver.idfactory.IdFactory;
  27. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  28. import net.sf.l2j.gameserver.network.SystemMessageId;
  29. import net.sf.l2j.gameserver.network.clientpackets.Say2;
  30. import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
  31. import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket;
  32. import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
  33. import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
  34. /**
  35. * Petition Manager
  36. *
  37. * @author Tempy
  38. *
  39. */
  40. public final class PetitionManager
  41. {
  42. protected static final Logger _log = Logger.getLogger(PetitionManager.class.getName());
  43. private static PetitionManager _instance;
  44. private Map<Integer, Petition> _pendingPetitions;
  45. private Map<Integer, Petition> _completedPetitions;
  46. private static enum PetitionState
  47. {
  48. Pending,
  49. Responder_Cancel,
  50. Responder_Missing,
  51. Responder_Reject,
  52. Responder_Complete,
  53. Petitioner_Cancel,
  54. Petitioner_Missing,
  55. In_Process,
  56. Completed
  57. }
  58. private static enum PetitionType
  59. {
  60. Immobility,
  61. Recovery_Related,
  62. Bug_Report,
  63. Quest_Related,
  64. Bad_User,
  65. Suggestions,
  66. Game_Tip,
  67. Operation_Related,
  68. Other
  69. }
  70. public static PetitionManager getInstance()
  71. {
  72. if (_instance == null)
  73. {
  74. _log.info("Initializing PetitionManager");
  75. _instance = new PetitionManager();
  76. }
  77. return _instance;
  78. }
  79. private class Petition
  80. {
  81. private long _submitTime = System.currentTimeMillis();
  82. private long _endTime = -1;
  83. private int _id;
  84. private PetitionType _type;
  85. private PetitionState _state = PetitionState.Pending;
  86. private String _content;
  87. private List<CreatureSay> _messageLog = new FastList<CreatureSay>();
  88. private L2PcInstance _petitioner;
  89. private L2PcInstance _responder;
  90. public Petition(L2PcInstance petitioner, String petitionText, int petitionType)
  91. {
  92. petitionType--;
  93. _id = IdFactory.getInstance().getNextId();
  94. if(petitionType >= PetitionType.values().length)
  95. {
  96. _log.warning("PetitionManager:Petition : invalid petition type (received type was +1) : "+ petitionType);
  97. }
  98. _type = PetitionType.values()[petitionType];
  99. _content = petitionText;
  100. _petitioner = petitioner;
  101. }
  102. protected boolean addLogMessage(CreatureSay cs)
  103. {
  104. return _messageLog.add(cs);
  105. }
  106. protected List<CreatureSay> getLogMessages()
  107. {
  108. return _messageLog;
  109. }
  110. public boolean endPetitionConsultation(PetitionState endState)
  111. {
  112. setState(endState);
  113. _endTime = System.currentTimeMillis();
  114. if (getResponder() != null && getResponder().isOnline() == 1)
  115. {
  116. if (endState == PetitionState.Responder_Reject)
  117. {
  118. getPetitioner().sendMessage("Your petition was rejected. Please try again later.");
  119. }
  120. else
  121. {
  122. // Ending petition consultation with <Player>.
  123. SystemMessage sm = new SystemMessage(SystemMessageId.PETITION_ENDED_WITH_S1);
  124. sm.addString(getPetitioner().getName());
  125. getResponder().sendPacket(sm);
  126. if (endState == PetitionState.Petitioner_Cancel)
  127. {
  128. // Receipt No. <ID> petition cancelled.
  129. sm = new SystemMessage(SystemMessageId.RECENT_NO_S1_CANCELED);
  130. sm.addNumber(getId());
  131. getResponder().sendPacket(sm);
  132. }
  133. }
  134. }
  135. // End petition consultation and inform them, if they are still online.
  136. if (getPetitioner() != null && getPetitioner().isOnline() == 1)
  137. getPetitioner().sendPacket(new SystemMessage(SystemMessageId.THIS_END_THE_PETITION_PLEASE_PROVIDE_FEEDBACK));
  138. getCompletedPetitions().put(getId(), this);
  139. return (getPendingPetitions().remove(getId()) != null);
  140. }
  141. public String getContent()
  142. {
  143. return _content;
  144. }
  145. public int getId()
  146. {
  147. return _id;
  148. }
  149. public L2PcInstance getPetitioner()
  150. {
  151. return _petitioner;
  152. }
  153. public L2PcInstance getResponder()
  154. {
  155. return _responder;
  156. }
  157. public long getEndTime()
  158. {
  159. return _endTime;
  160. }
  161. public long getSubmitTime()
  162. {
  163. return _submitTime;
  164. }
  165. public PetitionState getState()
  166. {
  167. return _state;
  168. }
  169. public String getTypeAsString()
  170. {
  171. return _type.toString().replace("_", " ");
  172. }
  173. public void sendPetitionerPacket(L2GameServerPacket responsePacket)
  174. {
  175. if (getPetitioner() == null || getPetitioner().isOnline() == 0)
  176. {
  177. // Allows petitioners to see the results of their petition when
  178. // they log back into the game.
  179. //endPetitionConsultation(PetitionState.Petitioner_Missing);
  180. return;
  181. }
  182. getPetitioner().sendPacket(responsePacket);
  183. }
  184. public void sendResponderPacket(L2GameServerPacket responsePacket)
  185. {
  186. if (getResponder() == null || getResponder().isOnline() == 0)
  187. {
  188. endPetitionConsultation(PetitionState.Responder_Missing);
  189. return;
  190. }
  191. getResponder().sendPacket(responsePacket);
  192. }
  193. public void setState(PetitionState state)
  194. {
  195. _state = state;
  196. }
  197. public void setResponder(L2PcInstance respondingAdmin)
  198. {
  199. if (getResponder() != null)
  200. return;
  201. _responder = respondingAdmin;
  202. }
  203. }
  204. private PetitionManager()
  205. {
  206. _pendingPetitions = new FastMap<Integer, Petition>();
  207. _completedPetitions = new FastMap<Integer, Petition>();
  208. }
  209. public void clearCompletedPetitions()
  210. {
  211. int numPetitions = getPendingPetitionCount();
  212. getCompletedPetitions().clear();
  213. _log.info("PetitionManager: Completed petition data cleared. " + numPetitions + " petition(s) removed.");
  214. }
  215. public void clearPendingPetitions()
  216. {
  217. int numPetitions = getPendingPetitionCount();
  218. getPendingPetitions().clear();
  219. _log.info("PetitionManager: Pending petition queue cleared. " + numPetitions + " petition(s) removed.");
  220. }
  221. public boolean acceptPetition(L2PcInstance respondingAdmin, int petitionId)
  222. {
  223. if (!isValidPetition(petitionId))
  224. return false;
  225. Petition currPetition = getPendingPetitions().get(petitionId);
  226. if (currPetition.getResponder() != null)
  227. return false;
  228. currPetition.setResponder(respondingAdmin);
  229. currPetition.setState(PetitionState.In_Process);
  230. // Petition application accepted. (Send to Petitioner)
  231. currPetition.sendPetitionerPacket(new SystemMessage(SystemMessageId.PETITION_APP_ACCEPTED));
  232. // Petition application accepted. Reciept No. is <ID>
  233. SystemMessage sm = new SystemMessage(SystemMessageId.PETITION_ACCEPTED_RECENT_NO_S1);
  234. sm.addNumber(currPetition.getId());
  235. currPetition.sendResponderPacket(sm);
  236. // Petition consultation with <Player> underway.
  237. sm = new SystemMessage(SystemMessageId.PETITION_WITH_S1_UNDER_WAY);
  238. sm.addString(currPetition.getPetitioner().getName());
  239. currPetition.sendResponderPacket(sm);
  240. return true;
  241. }
  242. public boolean cancelActivePetition(L2PcInstance player)
  243. {
  244. for (Petition currPetition : getPendingPetitions().values())
  245. {
  246. if (currPetition.getPetitioner() != null && currPetition.getPetitioner().getObjectId() == player.getObjectId())
  247. return (currPetition.endPetitionConsultation(PetitionState.Petitioner_Cancel));
  248. if (currPetition.getResponder() != null && currPetition.getResponder().getObjectId() == player.getObjectId())
  249. return (currPetition.endPetitionConsultation(PetitionState.Responder_Cancel));
  250. }
  251. return false;
  252. }
  253. public void checkPetitionMessages(L2PcInstance petitioner)
  254. {
  255. if (petitioner != null)
  256. for (Petition currPetition : getPendingPetitions().values())
  257. {
  258. if (currPetition == null)
  259. continue;
  260. if (currPetition.getPetitioner() != null && currPetition.getPetitioner().getObjectId() == petitioner.getObjectId())
  261. {
  262. for (CreatureSay logMessage : currPetition.getLogMessages())
  263. petitioner.sendPacket(logMessage);
  264. return;
  265. }
  266. }
  267. }
  268. public boolean endActivePetition(L2PcInstance player)
  269. {
  270. if (!player.isGM())
  271. return false;
  272. for (Petition currPetition : getPendingPetitions().values())
  273. {
  274. if (currPetition == null)
  275. continue;
  276. if (currPetition.getResponder() != null && currPetition.getResponder().getObjectId() == player.getObjectId())
  277. return (currPetition.endPetitionConsultation(PetitionState.Completed));
  278. }
  279. return false;
  280. }
  281. protected Map<Integer, Petition> getCompletedPetitions()
  282. {
  283. return _completedPetitions;
  284. }
  285. protected Map<Integer, Petition> getPendingPetitions()
  286. {
  287. return _pendingPetitions;
  288. }
  289. public int getPendingPetitionCount()
  290. {
  291. return getPendingPetitions().size();
  292. }
  293. public int getPlayerTotalPetitionCount(L2PcInstance player)
  294. {
  295. if (player == null)
  296. return 0;
  297. int petitionCount = 0;
  298. for (Petition currPetition : getPendingPetitions().values())
  299. {
  300. if (currPetition == null)
  301. continue;
  302. if (currPetition.getPetitioner() != null && currPetition.getPetitioner().getObjectId() == player.getObjectId())
  303. petitionCount++;
  304. }
  305. for (Petition currPetition : getCompletedPetitions().values())
  306. {
  307. if (currPetition == null)
  308. continue;
  309. if (currPetition.getPetitioner() != null && currPetition.getPetitioner().getObjectId() == player.getObjectId())
  310. petitionCount++;
  311. }
  312. return petitionCount;
  313. }
  314. public boolean isPetitionInProcess()
  315. {
  316. for (Petition currPetition : getPendingPetitions().values())
  317. {
  318. if (currPetition == null)
  319. continue;
  320. if (currPetition.getState() == PetitionState.In_Process)
  321. return true;
  322. }
  323. return false;
  324. }
  325. public boolean isPetitionInProcess(int petitionId)
  326. {
  327. if (!isValidPetition(petitionId))
  328. return false;
  329. Petition currPetition = getPendingPetitions().get(petitionId);
  330. return (currPetition.getState() == PetitionState.In_Process);
  331. }
  332. public boolean isPlayerInConsultation(L2PcInstance player)
  333. {
  334. if (player != null)
  335. for (Petition currPetition : getPendingPetitions().values())
  336. {
  337. if (currPetition == null)
  338. continue;
  339. if (currPetition.getState() != PetitionState.In_Process)
  340. continue;
  341. if ((currPetition.getPetitioner() != null && currPetition.getPetitioner().getObjectId() == player.getObjectId()) ||
  342. (currPetition.getResponder() != null && currPetition.getResponder().getObjectId() == player.getObjectId()))
  343. return true;
  344. }
  345. return false;
  346. }
  347. public boolean isPetitioningAllowed()
  348. {
  349. return Config.PETITIONING_ALLOWED;
  350. }
  351. public boolean isPlayerPetitionPending(L2PcInstance petitioner)
  352. {
  353. if (petitioner != null)
  354. for (Petition currPetition : getPendingPetitions().values())
  355. {
  356. if (currPetition == null)
  357. continue;
  358. if (currPetition.getPetitioner() != null && currPetition.getPetitioner().getObjectId() == petitioner.getObjectId())
  359. return true;
  360. }
  361. return false;
  362. }
  363. private boolean isValidPetition(int petitionId)
  364. {
  365. return getPendingPetitions().containsKey(petitionId);
  366. }
  367. public boolean rejectPetition(L2PcInstance respondingAdmin, int petitionId)
  368. {
  369. if (!isValidPetition(petitionId))
  370. return false;
  371. Petition currPetition = getPendingPetitions().get(petitionId);
  372. if (currPetition.getResponder() != null)
  373. return false;
  374. currPetition.setResponder(respondingAdmin);
  375. return (currPetition.endPetitionConsultation(PetitionState.Responder_Reject));
  376. }
  377. public boolean sendActivePetitionMessage(L2PcInstance player, String messageText)
  378. {
  379. //if (!isPlayerInConsultation(player))
  380. //return false;
  381. CreatureSay cs;
  382. for (Petition currPetition : getPendingPetitions().values())
  383. {
  384. if (currPetition == null)
  385. continue;
  386. if (currPetition.getPetitioner() != null && currPetition.getPetitioner().getObjectId() == player.getObjectId())
  387. {
  388. cs = new CreatureSay(player.getObjectId(), Say2.PETITION_PLAYER, player.getName(), messageText);
  389. currPetition.addLogMessage(cs);
  390. currPetition.sendResponderPacket(cs);
  391. currPetition.sendPetitionerPacket(cs);
  392. return true;
  393. }
  394. if (currPetition.getResponder() != null && currPetition.getResponder().getObjectId() == player.getObjectId())
  395. {
  396. cs = new CreatureSay(player.getObjectId(), Say2.PETITION_GM, player.getName(), messageText);
  397. currPetition.addLogMessage(cs);
  398. currPetition.sendResponderPacket(cs);
  399. currPetition.sendPetitionerPacket(cs);
  400. return true;
  401. }
  402. }
  403. return false;
  404. }
  405. public void sendPendingPetitionList(L2PcInstance activeChar)
  406. {
  407. TextBuilder htmlContent = new TextBuilder("<html><body>" +
  408. "<center><font color=\"LEVEL\">Current Petitions</font><br><table width=\"300\">");
  409. SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM HH:mm z");
  410. if (getPendingPetitionCount() == 0)
  411. htmlContent.append("<tr><td colspan=\"4\">There are no currently pending petitions.</td></tr>");
  412. else
  413. htmlContent.append("<tr><td></td><td><font color=\"999999\">Petitioner</font></td>" +
  414. "<td><font color=\"999999\">Petition Type</font></td><td><font color=\"999999\">Submitted</font></td></tr>");
  415. for (Petition currPetition : getPendingPetitions().values())
  416. {
  417. if (currPetition == null)
  418. continue;
  419. htmlContent.append("<tr><td>");
  420. if (currPetition.getState() != PetitionState.In_Process)
  421. htmlContent.append("<button value=\"View\" action=\"bypass -h admin_view_petition " + currPetition.getId() + "\" " +
  422. "width=\"40\" height=\"15\" back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
  423. else
  424. htmlContent.append("<font color=\"999999\">In Process</font>");
  425. htmlContent.append("</td><td>" + currPetition.getPetitioner().getName() +
  426. "</td><td>" + currPetition.getTypeAsString() + "</td><td>" +
  427. dateFormat.format(new Date(currPetition.getSubmitTime())) + "</td></tr>");
  428. }
  429. htmlContent.append("</table><br><button value=\"Refresh\" action=\"bypass -h admin_view_petitions\" width=\"50\" " +
  430. "height=\"15\" back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"><br><button value=\"Back\" action=\"bypass -h admin_admin\" " +
  431. "width=\"40\" height=\"15\" back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></center></body></html>");
  432. NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
  433. htmlMsg.setHtml(htmlContent.toString());
  434. activeChar.sendPacket(htmlMsg);
  435. }
  436. public int submitPetition(L2PcInstance petitioner, String petitionText, int petitionType)
  437. {
  438. // Create a new petition instance and add it to the list of pending petitions.
  439. Petition newPetition = new Petition(petitioner, petitionText, petitionType);
  440. int newPetitionId = newPetition.getId();
  441. getPendingPetitions().put(newPetitionId, newPetition);
  442. // Notify all GMs that a new petition has been submitted.
  443. String msgContent = petitioner.getName() + " has submitted a new petition."; //(ID: " + newPetitionId + ").";
  444. GmListTable.broadcastToGMs(new CreatureSay(petitioner.getObjectId(), 17, "Petition System", msgContent));
  445. return newPetitionId;
  446. }
  447. public void viewPetition(L2PcInstance activeChar, int petitionId)
  448. {
  449. if (!activeChar.isGM())
  450. return;
  451. if (!isValidPetition(petitionId))
  452. return;
  453. Petition currPetition = getPendingPetitions().get(petitionId);
  454. TextBuilder htmlContent = new TextBuilder("<html><body>");
  455. SimpleDateFormat dateFormat = new SimpleDateFormat("EEE dd MMM HH:mm z");
  456. htmlContent.append("<center><br><font color=\"LEVEL\">Petition #" + currPetition.getId() + "</font><br1>");
  457. htmlContent.append("<img src=\"L2UI.SquareGray\" width=\"200\" height=\"1\"></center><br>");
  458. htmlContent.append("Submit Time: " + dateFormat.format(new Date(currPetition.getSubmitTime())) + "<br1>");
  459. htmlContent.append("Petitioner: " + currPetition.getPetitioner().getName() + "<br1>");
  460. htmlContent.append("Petition Type: " + currPetition.getTypeAsString() + "<br>" + currPetition.getContent() + "<br>");
  461. htmlContent.append("<center><button value=\"Accept\" action=\"bypass -h admin_accept_petition " + currPetition.getId() + "\"" +
  462. "width=\"50\" height=\"15\" back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"><br1>");
  463. htmlContent.append("<button value=\"Reject\" action=\"bypass -h admin_reject_petition " + currPetition.getId() + "\" " +
  464. "width=\"50\" height=\"15\" back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"><br>");
  465. htmlContent.append("<button value=\"Back\" action=\"bypass -h admin_view_petitions\" width=\"40\" height=\"15\" back=\"L2UI_ct1.button_df\" " +
  466. "fore=\"L2UI_ct1.button_df\"></center>");
  467. htmlContent.append("</body></html>");
  468. NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
  469. htmlMsg.setHtml(htmlContent.toString());
  470. activeChar.sendPacket(htmlMsg);
  471. }
  472. }