package scripting.npc; import client.MapleClient; import java.util.Map; import java.util.WeakHashMap; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptException; import scripting.AbstractScriptManager; import scripting.ScriptType; import tools.FileoutputUtil; public class NPCScriptManager extends AbstractScriptManager { private static final NPCScriptManager instance = new NPCScriptManager(); private Map<MapleClient, NPCConversationManager> cms = new WeakHashMap(); public static final NPCScriptManager getInstance() { return instance; } public void start(MapleClient c, int npcId) { start(c, npcId, null); } public void start(MapleClient c, int npcId, String npcMode) { try { if (c.getPlayer().isAdmin()) { c.getPlayer().dropMessage(5, "对话NPC:" + npcId + " 模式:" + npcMode); } if (this.cms.containsKey(c)) { dispose(c); return; } Invocable iv; if (npcMode == null) { iv = getInvocable("npc/" + npcId + ".js", c, true); } else { iv = getInvocable("特殊/" + npcMode + ".js", c, true); } ScriptEngine scriptengine = (ScriptEngine) iv; NPCConversationManager cm = new NPCConversationManager(c, npcId, npcMode, ScriptType.NPC, iv); if ((iv == null) || (getInstance() == null)) { if (iv == null) { c.getPlayer().dropMessage(5,"找不到NPC脚本(ID:" + npcId + "), 特殊模式(" + npcMode + "),所在地图(ID:" + c.getPlayer().getMapId() + ")"); } dispose(c); return; } this.cms.put(c, cm); scriptengine.put("cm", cm); c.getPlayer().setConversation(1); c.setClickedNPC(); try { iv.invokeFunction("start", new Object[0]); } catch (NoSuchMethodException nsme) { iv.invokeFunction("action", new Object[]{(byte) 1, (byte) 0, (int) (byte) 0}); } } catch (NoSuchMethodException | ScriptException e) { System.err.println("NPC脚本出错(ID : " + npcId + ")模式:" + npcMode + "错误内容: " + e); FileoutputUtil.log(FileoutputUtil.ScriptEx_Log, "NPC脚本出错(ID : " + npcId + ")模式" + npcMode + ".\r\n错误信息:" + e); dispose(c); notice(c, npcId, npcMode); } } public void action(MapleClient c, byte mode, byte type, int selection) { if (mode != -1) { NPCConversationManager cm = this.cms.get(c); if (cm == null) { return; } try { if (cm.pendingDisposal) { dispose(c); } else { c.setClickedNPC(); cm.getIv().invokeFunction("action", new Object[]{mode, type, selection}); } } catch (NoSuchMethodException | ScriptException e) { int npcId = cm.getNpc(); String npcMode = cm.getScript(); System.err.println("NPC脚本出错(ID : " + npcId + ")模式:" + npcMode + " 错误内容:" + e); FileoutputUtil.log(FileoutputUtil.ScriptEx_Log, "NPC脚本出错(ID : " + npcId + ")模式:" + npcMode + ". \r\n错误信息:" + e); dispose(c); notice(c, npcId, npcMode); } } } public void dispose(MapleClient c) { final NPCConversationManager npccm = cms.get(c); if (npccm != null) { cms.remove(c); if (npccm.getType() == ScriptType.NPC) { if (npccm.getScript() == null) { c.removeScriptEngine("脚本/npc/" + npccm.getNpc() + ".js"); } else { c.removeScriptEngine("脚本/特殊/" + npccm.getScript() + ".js"); } } else if (npccm.getType() == ScriptType.ON_USER_ENTER) { c.removeScriptEngine("脚本/地图/onUserEnter/" + npccm.getScript() + ".js"); } else if (npccm.getType() == ScriptType.ON_FIRST_USER_ENTER) { c.removeScriptEngine("脚本/地图/onFirstUserEnter/" + npccm.getScript() + ".js"); } } if (c.getPlayer() != null && c.getPlayer().getConversation() == 1) { c.getPlayer().setConversation(0); } } public void dispose(NPCConversationManager cm) { if (cm == null) { return; } MapleClient c = cm.getClient(); final NPCConversationManager npccm = cms.get(c); if (npccm != null) { cms.remove(c); if (npccm.getType() == ScriptType.NPC) { if (cm.getScript() == null) { c.removeScriptEngine("脚本/npc/" + cm.getNpc() + ".js"); } else { c.removeScriptEngine("脚本/特殊/" + cm.getScript() + ".js"); } } else if (npccm.getType() == ScriptType.ON_USER_ENTER) { c.removeScriptEngine("脚本/地图/onUserEnter/" + npccm.getScript() + ".js"); } else if (npccm.getType() == ScriptType.ON_FIRST_USER_ENTER) { c.removeScriptEngine("脚本/地图/onFirstUserEnter/" + npccm.getScript() + ".js"); } } if (c.getPlayer() != null && c.getPlayer().getConversation() == 1) { c.getPlayer().setConversation(0); } } public NPCConversationManager getCM(MapleClient c) { return (NPCConversationManager) this.cms.get(c); } private void notice(MapleClient c, int npcId, String npcMode) { c.getPlayer().dropMessage(1, "脚本出错. NPCID: " + npcId + (npcMode != null ? " 模式:" + npcMode : "") + " \n\r当前地图:" + c.getPlayer().getMap().getMapName() + "(" + c.getPlayer().getMapId() + ")"); } public final void onUserEnter(final MapleClient c, final String script) { try { if (c.getPlayer().isShowPacket()) { c.getPlayer().dropMessage(5, "开始地图onUserEnter脚本:" + script + c.getPlayer().getMap().getMapName()); } Invocable iv = getInvocable("地图/onUserEnter/" + script + ".js", c, true); ScriptEngine scriptengine = (ScriptEngine) iv; NPCConversationManager cm = new NPCConversationManager(c, 0, script, ScriptType.ON_USER_ENTER, iv); if (this.cms.containsValue(cm)) { FileoutputUtil.log("无法执行脚本:已有脚本執行-" + cms.containsKey(c) + "脚本名称:" + script + c.getPlayer().getMap().getMapName()); if (c.getPlayer().isShowPacket()) { c.getPlayer().dropMessage(5, "无法执行脚本:已有脚本執行-" + cms.containsKey(c)); } dispose(c); return; } if ((iv == null) || (getInstance() == null)) { if (iv == null) { FileoutputUtil.log("找不到onUserEnter脚本 :(" + script + "),所在地图(ID:" + c.getPlayer().getMapId() + ")"); } dispose(c); return; } this.cms.put(c, cm); scriptengine.put("ms", cm); c.getPlayer().setConversation(1); c.setClickedNPC(); try { iv.invokeFunction("start", new Object[0]); FileoutputUtil.log("开始执行onUserEnter脚本 :(" + script + "), 所在地图(ID:" + c.getPlayer().getMapId() + ")"); } catch (NoSuchMethodException nsme) { iv.invokeFunction("action", new Object[]{(byte) 1, (byte) 0, (int) (byte) 0}); } } catch (NoSuchMethodException | ScriptException e) { System.err.println("执行地图onUserEnter脚本出錯 : " + script + ". 错误内容" + e); FileoutputUtil.log(FileoutputUtil.ScriptEx_Log, "执行地图onUserEnter脚本出錯 : " + script + ".\r\n错误信息:" + e); dispose(c); } } public final void onFirstUserEnter(final MapleClient c, final String script) { try { if (c.getPlayer().isShowPacket()) { c.getPlayer().dropMessage(5, "开始地图onFirstUserEnter脚本:" + script + c.getPlayer().getMap().getMapName()); } if (this.cms.containsKey(c)) { if (c.getPlayer().isShowPacket()) { c.getPlayer().dropMessage(5, "无法执行脚本:已有脚本執行-" + cms.containsKey(c)); } dispose(c); return; } Invocable iv = getInvocable("地图/onFirstUserEnter/" + script + ".js", c, true); ScriptEngine scriptengine = (ScriptEngine) iv; NPCConversationManager cm = new NPCConversationManager(c, 0, script, ScriptType.ON_FIRST_USER_ENTER, iv); if ((iv == null) || (getInstance() == null)) { if (iv == null) { FileoutputUtil.log("找不到onFirstUserEnter脚本 :" + script + ",所在地图(ID:" + c.getPlayer().getMapId() + ")"); } dispose(c); return; } this.cms.put(c, cm); scriptengine.put("ms", cm); c.getPlayer().setConversation(1); c.setClickedNPC(); try { iv.invokeFunction("start", new Object[0]); FileoutputUtil.log("开始执行onFirstUserEnter脚本 :(" + script + "), 所在地图(ID:" + c.getPlayer().getMapId() + ")"); } catch (NoSuchMethodException nsme) { iv.invokeFunction("action", new Object[]{(byte) 1, (byte) 0, (int) (byte) 0}); } } catch (NoSuchMethodException | ScriptException e) { System.err.println("执行地图onFirstUserEnter脚本出錯 : " + script + ". 错误内容" + e); FileoutputUtil.log(FileoutputUtil.ScriptEx_Log, "执行地图onFirstUserEnter脚本出錯 : " + script + ".\r\n错误信息:" + e); dispose(c); } } }