/* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package handlers.admincommandhandlers; import java.io.File; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import com.l2jmobius.gameserver.handler.IAdminCommandHandler; import com.l2jmobius.gameserver.instancemanager.QuestManager; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.events.EventType; import com.l2jmobius.gameserver.model.events.ListenerRegisterType; import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; import com.l2jmobius.gameserver.model.quest.Quest; import com.l2jmobius.gameserver.model.quest.QuestTimer; import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; import com.l2jmobius.gameserver.scripting.ScriptEngineManager; import com.l2jmobius.gameserver.util.Util; public class AdminQuest implements IAdminCommandHandler { public static final Logger LOGGER = Logger.getLogger(AdminQuest.class.getName()); private static final String[] ADMIN_COMMANDS = { "admin_quest_reload", "admin_script_load", "admin_script_unload", "admin_script_dir", "admin_show_quests", "admin_quest_info" }; private static Quest findScript(String script) { if (Util.isDigit(script)) { return QuestManager.getInstance().getQuest(Integer.parseInt(script)); } return QuestManager.getInstance().getQuest(script); } @Override public boolean useAdminCommand(String command, L2PcInstance activeChar) { if (command.startsWith("admin_quest_reload")) { final StringTokenizer st = new StringTokenizer(command); st.nextToken(); // skip command token if (!st.hasMoreTokens()) { activeChar.sendMessage("Usage: //quest_reload or "); return false; } final String script = st.nextToken(); final Quest quest = findScript(script); if (quest == null) { activeChar.sendMessage("The script " + script + " couldn't be found!"); return false; } if (!quest.reload()) { activeChar.sendMessage("Failed to reload " + script + "!"); return false; } activeChar.sendMessage("Script successful reloaded."); } else if (command.startsWith("admin_script_load")) { final StringTokenizer st = new StringTokenizer(command); st.nextToken(); // skip command token if (!st.hasMoreTokens()) { activeChar.sendMessage("Usage: //script_load path/to/script.java"); return false; } final String script = st.nextToken(); try { ScriptEngineManager.getInstance().executeScript(Paths.get(script)); activeChar.sendMessage("Script loaded seccessful!"); } catch (Exception e) { activeChar.sendMessage("Failed to load script!"); LOGGER.log(Level.WARNING, "Failed to load script " + script + "!", e); } } else if (command.startsWith("admin_script_unload")) { final StringTokenizer st = new StringTokenizer(command); st.nextToken(); // skip command token if (!st.hasMoreTokens()) { activeChar.sendMessage("Usage: //script_load path/to/script.java"); return false; } final String script = st.nextToken(); final Quest quest = findScript(script); if (quest == null) { activeChar.sendMessage("The script " + script + " couldn't be found!"); return false; } quest.unload(); activeChar.sendMessage("Script successful unloaded!"); } else if (command.startsWith("admin_script_dir")) { final String[] parts = command.split(" "); if (parts.length == 1) { showDir(null, activeChar); } else { showDir(parts[1], activeChar); } } else if (command.startsWith("admin_show_quests")) { if (activeChar.getTarget() == null) { activeChar.sendMessage("Get a target first."); } else if (!activeChar.getTarget().isCharacter()) { activeChar.sendMessage("Invalid Target."); } else { final L2Character character = (L2Character) activeChar.getTarget(); final StringBuilder sb = new StringBuilder(); final Set questNames = new TreeSet<>(); for (EventType type : EventType.values()) { for (AbstractEventListener listener : character.getListeners(type)) { if (listener.getOwner() instanceof Quest) { final Quest quest = (Quest) listener.getOwner(); if (!questNames.add(quest.getName())) { continue; } sb.append("" + quest.getName() + ""); } } } final NpcHtmlMessage msg = new NpcHtmlMessage(0, 1); msg.setFile(activeChar.getHtmlPrefix(), "data/html/admin/npc-quests.htm"); msg.replace("%quests%", sb.toString()); msg.replace("%objid%", character.getObjectId()); msg.replace("%questName%", ""); activeChar.sendPacket(msg); } } else if (command.startsWith("admin_quest_info ")) { final String questName = command.substring("admin_quest_info ".length()); final Quest quest = QuestManager.getInstance().getQuest(questName); String events = "", npcs = "", items = "", timers = ""; int counter = 0; if (quest == null) { activeChar.sendMessage("Couldn't find quest or script with name " + questName + " !"); return false; } final Set listenerTypes = new TreeSet<>(); for (AbstractEventListener listener : quest.getListeners()) { if (listenerTypes.add(listener.getType())) { events += ", " + listener.getType().name(); counter++; } if (counter > 10) { counter = 0; break; } } final Set npcIds = new TreeSet<>(quest.getRegisteredIds(ListenerRegisterType.NPC)); for (int npcId : npcIds) { npcs += ", " + npcId; counter++; if (counter > 50) { counter = 0; break; } } if (!events.isEmpty()) { events = listenerTypes.size() + ": " + events.substring(2); } if (!npcs.isEmpty()) { npcs = npcIds.size() + ": " + npcs.substring(2); } if (quest.getRegisteredItemIds() != null) { for (int itemId : quest.getRegisteredItemIds()) { items += ", " + itemId; counter++; if (counter > 20) { counter = 0; break; } } items = quest.getRegisteredItemIds().length + ":" + items.substring(2); } for (List list : quest.getQuestTimers().values()) { for (QuestTimer timer : list) { timers += "
" + timer.getName() + ": Active: " + timer.getIsActive() + " Repeatable: " + timer.getIsRepeating() + " Player: " + timer.getPlayer() + " Npc: " + timer.getNpc() + "
"; counter++; if (counter > 10) { break; } } } final StringBuilder sb = new StringBuilder(); sb.append("
ID: " + quest.getId() + "
"); sb.append("
Name: " + quest.getName() + "
"); sb.append("
Path: " + quest.getPath() + "
"); sb.append("
Events: " + events + "
"); if (!npcs.isEmpty()) { sb.append("
NPCs: " + npcs + "
"); } if (!items.isEmpty()) { sb.append("
Items: " + items + "
"); } if (!timers.isEmpty()) { sb.append("
Timers:
"); sb.append(timers); } final NpcHtmlMessage msg = new NpcHtmlMessage(0, 1); msg.setFile(activeChar.getHtmlPrefix(), "data/html/admin/npc-quests.htm"); msg.replace("%quests%", sb.toString()); msg.replace("%questName%", "
Reload " + quest.getName() + " Unload
"); activeChar.sendPacket(msg); } return true; } private void showDir(String dir, L2PcInstance activeChar) { String replace = null; File path; String currentPath = "/"; if ((dir == null) || dir.trim().isEmpty() || dir.contains("..")) { final StringBuilder sb = new StringBuilder(200); path = ScriptEngineManager.SCRIPT_FOLDER.toFile(); final String[] children = path.list(); Arrays.sort(children); for (String c : children) { final File n = new File(path, c); if (n.isHidden() || n.getName().startsWith(".")) { continue; } else if (n.isDirectory()) { sb.append("" + c + ""); } else if (c.endsWith(".java") || c.endsWith(".py")) { sb.append("" + c + ""); } } replace = sb.toString(); } else { path = new File(ScriptEngineManager.SCRIPT_FOLDER.toFile(), dir); if (!path.isDirectory()) { activeChar.sendMessage("Wrong path."); return; } currentPath = dir; final boolean questReducedNames = currentPath.equalsIgnoreCase("quests"); final StringBuilder sb = new StringBuilder(200); sb.append(".."); final String[] children = path.list(); Arrays.sort(children); for (String c : children) { final File n = new File(path, c); if (n.isHidden() || n.getName().startsWith(".")) { continue; } else if (n.isDirectory()) { sb.append("" + (questReducedNames ? getQuestName(c) : c) + ""); } else if (c.endsWith(".java") || c.endsWith(".py")) { sb.append("" + c + ""); } } replace = sb.toString(); if (questReducedNames) { currentPath += " (limited list - HTML too long)"; } } if (replace.length() > 17200) { replace = replace.substring(0, 17200); // packetlimit } final NpcHtmlMessage html = new NpcHtmlMessage(0, 1); html.setFile(activeChar.getHtmlPrefix(), "data/html/admin/scriptdirectory.htm"); html.replace("%path%", currentPath); html.replace("%list%", replace); activeChar.sendPacket(html); } private String getUpPath(String full) { final int index = full.lastIndexOf("/"); if (index == -1) { return ""; } return full.substring(0, index); } private String getQuestName(String full) { return full.split("_")[0]; } @Override public String[] getAdminCommandList() { return ADMIN_COMMANDS; } }