/* Copyright 2012 Jan Ove Saltvedt This file is part of KBot. KBot 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. KBot 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 KBot. If not, see <http://www.gnu.org/licenses/>. */ package com.kbotpro.handlers; import com.kbotpro.scriptsystem.runnable.*; import com.kbotpro.scriptsystem.runnable.Service; import com.kbotpro.scriptsystem.Methods; import com.kbotpro.debuggers.*; import com.kbotpro.ui.BotPanel; import com.kbotpro.various.StaticStorage; import com.kbotpro.bot.BotEnvironment; import org.apache.log4j.Logger; import javax.swing.*; import java.util.List; import java.util.ArrayList; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; import java.awt.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Created by IntelliJ IDEA. * User: Jan Ove Saltvedt * Date: Oct 9, 2009 * Time: 3:55:57 PM * To change this template use File | Settings | File Templates. */ public class DebuggerManager implements ServiceCallback { public List<Container> debuggers = new ArrayList<Container>(); private ItemListener itemListener = new ItemListener() { /** * Invoked when an item has been selected or deselected by the user. * The code written for this method performs the operations * that need to occur when an item is selected (or deselected). */ public void itemStateChanged(ItemEvent e) { final JCheckBoxMenuItem source = (JCheckBoxMenuItem) e.getSource(); if(e.getStateChange() != ItemEvent.SELECTED && e.getStateChange() != ItemEvent.DESELECTED){ return; } BotPanel botPanel = StaticStorage.mainForm.getOpenedBotPanel(); if (botPanel == null) { JOptionPane.showMessageDialog(null, "No bot selected."); EventQueue.invokeLater(new Runnable() { public void run() { } }); return; } if (botPanel.botEnvironment == null) { JOptionPane.showMessageDialog(null, "This bot has not started yet."); EventQueue.invokeLater(new Runnable() { public void run() { } }); return; } for (Container container : debuggers) { if (container.menuItem == source) { if(e.getStateChange() == ItemEvent.SELECTED){ startDebugger(container.debugger); } else if(e.getStateChange() == ItemEvent.DESELECTED){ stopDebugger(container.debugger); } break; } } } }; private BotEnvironment botEnvironment; public DebuggerManager(BotEnvironment botEnvironment) { this.botEnvironment = botEnvironment; loadDebuggers(); } public void loadDebuggers() { List<Container> debuggers = new ArrayList<Container>(); addDebugger(debuggers, new NPCDebugger()); addDebugger(debuggers, new PlayerDebugger()); addDebugger(debuggers, new MyPlayerDebugger()); addDebugger(debuggers, new ObjectDebugger()); addDebugger(debuggers, new MenuDebugger()); addDebugger(debuggers, new InterfaceDebugger()); addDebugger(debuggers, new SettingsDebugger()); addDebugger(debuggers, new GameDebugger()); addDebugger(debuggers, new InventoryDebugger()); addDebugger(debuggers, new MouseDebugger()); addDebugger(debuggers, new GroundItemDebugger()); addDebugger(debuggers, new RenderDataDebugger()); addDebugger(debuggers, new MinimapDebugger()); addDebugger(debuggers, new MapDebugger()); addDebugger(debuggers, new MinimapHookTest()); JMenu debuggersMenu = StaticStorage.mainForm.debuggersMenu; debuggersMenu.removeAll(); this.debuggers = debuggers; } private void addDebugger(List<Container> debuggers, Debugger debugger) { Container container; container = new Container(); container.debugger = debugger; container.menuItem = new JCheckBoxMenuItem(container.debugger.getName()); container.menuItem.addItemListener(itemListener); container.menuItem.setVisible(true); debuggers.add(container); } /** * Should be called when the bot's tab is selected */ public void updateMenu(){ JMenu debuggersMenu = StaticStorage.mainForm.debuggersMenu; for(Container container: debuggers){ if(container.running){ container.menuItem.setSelected(true); } } debuggersMenu.removeAll(); for(Container dContainer: debuggers){ debuggersMenu.add(dContainer.menuItem); } debuggersMenu.updateUI(); } public void startDebugger(final Debugger debugger) { EventQueue.invokeLater(new Runnable() { public void run() { if (debugger.canStart()) { // Reflect setBotEnv() try { Method registeMethod = Methods.class.getDeclaredMethod("registerInternal", new Class<?>[]{BotEnvironment.class}); registeMethod.setAccessible(true); // This method is private so we set it by a little reflection hack registeMethod.invoke(debugger, botEnvironment); Method getService = Debugger.class.getDeclaredMethod("getService"); getService.setAccessible(true); Service service = (Service) getService.invoke(debugger); service.setCallback(DebuggerManager.this); service.sStart(); botEnvironment.log.log("Started "+debugger.getName()); } catch (IllegalAccessException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } catch (InvocationTargetException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } catch (NoSuchMethodException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } } } }); } public void stopDebugger(final Debugger debugger) { EventQueue.invokeLater(new Runnable() { public void run() { try { Method getService = Debugger.class.getDeclaredMethod("getService"); getService.setAccessible(true); Service service = (Service) getService.invoke(debugger); service.sStop(); } catch (IllegalAccessException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } catch (InvocationTargetException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } catch (NoSuchMethodException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } } }); } /** * Callback to update the service state. * * @param state state to be set * @param instance */ public void setState(State state, Object instance) { if(instance instanceof Debugger){ for(Container container: debuggers){ if(instance == container.debugger){ if(state == State.ACTIVE){ container.menuItem.setSelected(true); container.running = true; } else if(state == State.DEAD){ container.menuItem.setSelected(false); try { Method deregisterMethod = Methods.class.getDeclaredMethod("deregisterInternal"); deregisterMethod.setAccessible(true); // This method is private so we set it by a little reflection hack deregisterMethod.invoke(container.debugger); } catch (NoSuchMethodException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } catch (InvocationTargetException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } catch (IllegalAccessException e) { Logger.getRootLogger().error("Exception: ", e); //To change body of catch statement use File | Settings | File Templates. } container.menuItem.setSelected(false); container.running = false; } } } } } public void disableAll() { for(Container container: debuggers){ if(container.running){ stopDebugger(container.debugger); } } } public void disposeResources() { botEnvironment = null; debuggers = null; } private class Container { public Debugger debugger; public JCheckBoxMenuItem menuItem; public boolean running = false; } }