QuestManager.java 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Copyright © 2004-2019 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.instancemanager;
  20. import java.io.File;
  21. import java.util.Map;
  22. import java.util.concurrent.ConcurrentHashMap;
  23. import org.slf4j.Logger;
  24. import org.slf4j.LoggerFactory;
  25. import com.l2jserver.gameserver.config.Config;
  26. import com.l2jserver.gameserver.model.quest.Quest;
  27. import com.l2jserver.gameserver.scripting.ScriptEngineManager;
  28. import com.l2jserver.gameserver.scripting.ScriptManager;
  29. import com.l2jserver.util.Util;
  30. /**
  31. * Quests and scripts manager.
  32. * @author Zoey76
  33. */
  34. public final class QuestManager extends ScriptManager<Quest> {
  35. private static final Logger LOG = LoggerFactory.getLogger(QuestManager.class);
  36. /** Map containing all the quests. */
  37. private final Map<String, Quest> _quests = new ConcurrentHashMap<>();
  38. /** Map containing all the scripts. */
  39. private final Map<String, Quest> _scripts = new ConcurrentHashMap<>();
  40. protected QuestManager() {
  41. // Prevent initialization.
  42. }
  43. public boolean reload(String questFolder) {
  44. final Quest q = getQuest(questFolder);
  45. if (q == null) {
  46. return false;
  47. }
  48. return q.reload();
  49. }
  50. /**
  51. * Reloads a the quest by ID.
  52. * @param questId the ID of the quest to be reloaded
  53. * @return {@code true} if reload was successful, {@code false} otherwise
  54. */
  55. public boolean reload(int questId) {
  56. final Quest q = getQuest(questId);
  57. if (q == null) {
  58. return false;
  59. }
  60. return q.reload();
  61. }
  62. /**
  63. * Reload all quests and scripts.<br>
  64. * Unload all quests and scripts and load scripts.cfg.
  65. */
  66. public void reloadAllScripts() {
  67. LOG.info("Reloading all server scripts.");
  68. // Unload quests.
  69. for (Quest quest : _quests.values()) {
  70. if (quest != null) {
  71. quest.unload(false);
  72. }
  73. }
  74. _quests.clear();
  75. // Unload scripts.
  76. for (Quest script : _scripts.values()) {
  77. if (script != null) {
  78. script.unload(false);
  79. }
  80. }
  81. _scripts.clear();
  82. try {
  83. ScriptEngineManager.getInstance().executeScriptList(new File(Config.DATAPACK_ROOT, "data/scripts.cfg"));
  84. } catch (Exception ex) {
  85. LOG.warn("Failed loading scripts.cfg, no script going to be loaded!", ex);
  86. }
  87. report();
  88. }
  89. public void report() {
  90. LOG.info("Loaded {} quests.", _quests.size());
  91. LOG.info("Loaded {} scripts.", _scripts.size());
  92. }
  93. /**
  94. * Calls {@link Quest#saveGlobalData()} in all quests and scripts.
  95. */
  96. public void save() {
  97. // Save quests.
  98. for (Quest quest : _quests.values()) {
  99. quest.saveGlobalData();
  100. }
  101. // Save scripts.
  102. for (Quest script : _scripts.values()) {
  103. script.saveGlobalData();
  104. }
  105. }
  106. /**
  107. * Gets a quest by name.<br>
  108. * <i>For backwards compatibility, verifies scripts with the given name if the quest is not found.</i>
  109. * @param name the quest name
  110. * @return the quest
  111. */
  112. public Quest getQuest(String name) {
  113. if (_quests.containsKey(name)) {
  114. return _quests.get(name);
  115. }
  116. return _scripts.get(name);
  117. }
  118. /**
  119. * Gets a quest by ID.
  120. * @param questId the ID of the quest to get
  121. * @return if found, the quest, {@code null} otherwise
  122. */
  123. public Quest getQuest(int questId) {
  124. for (Quest q : _quests.values()) {
  125. if (q.getId() == questId) {
  126. return q;
  127. }
  128. }
  129. return null;
  130. }
  131. /**
  132. * Adds a new quest.
  133. * @param quest the quest to be added
  134. */
  135. public void addQuest(Quest quest) {
  136. if (quest == null) {
  137. throw new IllegalArgumentException("Quest argument cannot be null");
  138. }
  139. // FIXME: unloading the old quest at this point is a tad too late.
  140. // the new quest has already initialized itself and read the data, starting
  141. // an unpredictable number of tasks with that data. The old quest will now
  142. // save data which will never be read.
  143. // However, requesting the newQuest to re-read the data is not necessarily a
  144. // good option, since the newQuest may have already started timers, spawned NPCs
  145. // or taken any other action which it might re-take by re-reading the data.
  146. // the current solution properly closes the running tasks of the old quest but
  147. // ignores the data; perhaps the least of all evils...
  148. final Quest old = _quests.put(quest.getName(), quest);
  149. if (old != null) {
  150. old.unload();
  151. LOG.info("Replaced quest {} with a new version.", old);
  152. }
  153. if (Config.ALT_DEV_SHOW_QUESTS_LOAD_IN_LOGS) {
  154. final String questName = quest.getName().contains("_") ? quest.getName().substring(quest.getName().indexOf('_') + 1) : quest.getName();
  155. LOG.info("Loaded quest {}.", Util.splitWords(questName));
  156. }
  157. }
  158. /**
  159. * Removes a script.
  160. * @param script the script to remove
  161. * @return {@code true} if the script was removed, {@code false} otherwise
  162. */
  163. public boolean removeScript(Quest script) {
  164. if (_quests.containsKey(script.getName())) {
  165. _quests.remove(script.getName());
  166. return true;
  167. } else if (_scripts.containsKey(script.getName())) {
  168. _scripts.remove(script.getName());
  169. return true;
  170. }
  171. return false;
  172. }
  173. public Map<String, Quest> getQuests() {
  174. return _quests;
  175. }
  176. @Override
  177. public boolean unload(Quest ms) {
  178. ms.saveGlobalData();
  179. return removeScript(ms);
  180. }
  181. @Override
  182. public String getScriptManagerName() {
  183. return getClass().getSimpleName();
  184. }
  185. /**
  186. * Gets all the registered scripts.
  187. * @return all the scripts
  188. */
  189. @Override
  190. public Map<String, Quest> getScripts() {
  191. return _scripts;
  192. }
  193. /**
  194. * Adds a script.
  195. * @param script the script to be added
  196. */
  197. public void addScript(Quest script) {
  198. final Quest old = _scripts.put(script.getClass().getSimpleName(), script);
  199. if (old != null) {
  200. old.unload();
  201. LOG.info("Replaced script {} with a new version.", old);
  202. }
  203. if (Config.ALT_DEV_SHOW_SCRIPTS_LOAD_IN_LOGS) {
  204. LOG.info("Loaded script {}.", Util.splitWords(script.getClass().getSimpleName()));
  205. }
  206. }
  207. public static QuestManager getInstance() {
  208. return SingletonHolder.INSTANCE;
  209. }
  210. private static class SingletonHolder {
  211. protected static final QuestManager INSTANCE = new QuestManager();
  212. }
  213. }