runelite-client: use guava service manager for plugins

Seems more robust and the whole client doesn't break if one plugin fails
This commit is contained in:
Adam
2017-04-21 22:37:02 -04:00
parent 345d197171
commit 23dabe982c
11 changed files with 147 additions and 67 deletions

View File

@@ -25,9 +25,13 @@
package net.runelite.client.plugins;
import com.google.common.util.concurrent.AbstractIdleService;
import net.runelite.client.ui.overlay.Overlay;
public abstract class Plugin
public abstract class Plugin extends AbstractIdleService
{
public abstract Overlay getOverlay();
public Overlay getOverlay()
{
return null;
}
}

View File

@@ -24,9 +24,13 @@
*/
package net.runelite.client.plugins;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.Service;
import com.google.common.util.concurrent.ServiceManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import net.runelite.client.RuneLite;
import net.runelite.client.plugins.boosts.Boosts;
import net.runelite.client.plugins.bosstimer.BossTimers;
@@ -45,7 +49,7 @@ public class PluginManager
private static final Logger logger = LoggerFactory.getLogger(PluginManager.class);
private final RuneLite runelite;
private final List<Plugin> plugins = new ArrayList<>();
private ServiceManager manager;
public PluginManager(RuneLite runelite)
{
@@ -54,30 +58,67 @@ public class PluginManager
public void loadAll()
{
load(new Boosts());
load(new OpponentInfo());
load(new FPS());
load(new Hiscore());
load(new BossTimers());
load(new Xtea());
load(new IdleNotifier());
load(new Runecraft());
List<Plugin> plugins = new ArrayList<>();
plugins.add(new Boosts());
plugins.add(new OpponentInfo());
plugins.add(new FPS());
plugins.add(new Hiscore());
plugins.add(new BossTimers());
plugins.add(new Xtea());
plugins.add(new IdleNotifier());
plugins.add(new Runecraft());
if (RuneLite.getOptions().has("developer-mode"))
{
logger.info("Loading developer plugins");
load(new DevTools());
plugins.add(new DevTools());
}
}
private void load(Plugin plugin)
{
plugins.add(plugin);
runelite.getEventBus().register(plugin);
// Add plugin listeners
for (Plugin plugin : plugins)
{
Service.Listener listener = new Service.Listener()
{
@Override
public void running()
{
logger.debug("Plugin {} is now running", plugin);
runelite.getEventBus().register(plugin);
}
@Override
public void stopping(Service.State from)
{
logger.debug("Plugin {} is stopping", plugin);
runelite.getEventBus().unregister(logger);
}
@Override
public void failed(Service.State from, Throwable failure)
{
logger.warn("Plugin {} has failed", plugin, failure);
if (from == Service.State.RUNNING)
{
runelite.getEventBus().unregister(logger);
}
}
};
plugin.addListener(listener, MoreExecutors.directExecutor());
}
manager = new ServiceManager(plugins);
logger.debug("Starting plugins...");
manager.startAsync();
}
public Collection<Plugin> getPlugins()
{
return plugins;
return manager.servicesByState().get(Service.State.RUNNING)
.stream()
.map(s -> (Plugin) s)
.collect(Collectors.toList());
}
}

View File

@@ -37,4 +37,14 @@ public class Boosts extends Plugin
{
return overlay;
}
@Override
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
}
}

View File

@@ -46,6 +46,16 @@ public class BossTimers extends Plugin
private final List<Boss> bosses = loadBossData();
@Override
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
}
@Override
public Overlay getOverlay()
{

View File

@@ -25,10 +25,8 @@
package net.runelite.client.plugins.devtools;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import net.runelite.client.RuneLite;
@@ -60,34 +58,26 @@ public class DevTools extends Plugin
private Font font;
public DevTools()
@Override
protected void startUp() throws Exception
{
navButton.getButton().addActionListener(this::setPluginPanel);
try
{
ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("devtools_icon.png")));
navButton.getButton().setIcon(icon);
}
catch (IOException ex)
{
logger.warn("Unable to load devtools icon", ex);
}
ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("devtools_icon.png")));
navButton.getButton().setIcon(icon);
ui.getNavigationPanel().addNavigation(navButton);
try
{
font = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsStream("runescape.ttf"));
font = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsStream("runescape.ttf"));
font = font.deriveFont(Font.PLAIN, 16);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);
}
catch (FontFormatException | IOException ex)
{
logger.warn("Unable to load font", ex);
}
font = font.deriveFont(Font.PLAIN, 16);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);
}
@Override
protected void shutDown() throws Exception
{
}
@Override

View File

@@ -37,4 +37,14 @@ public class FPS extends Plugin
{
return overlay;
}
@Override
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
}
}

View File

@@ -26,7 +26,6 @@ package net.runelite.client.plugins.hiscore;
import com.google.common.eventbus.Subscribe;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.concurrent.ScheduledExecutorService;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
@@ -35,7 +34,6 @@ import net.runelite.client.events.PlayerMenuOptionClicked;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.overlay.Overlay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,19 +49,13 @@ public class Hiscore extends Plugin
private final RuneLite runeLite = RuneLite.getRunelite();
private final ClientUI ui = runeLite.getGui();
public Hiscore()
@Override
protected void startUp() throws Exception
{
navButton.getButton().addActionListener(this::setPluginPanel);
try
{
ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("hiscore.gif")));
navButton.getButton().setIcon(icon);
}
catch (IOException ex)
{
logger.warn(null, ex);
}
ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("hiscore.gif")));
navButton.getButton().setIcon(icon);
ui.getNavigationPanel().addNavigation(navButton);
@@ -71,9 +63,8 @@ public class Hiscore extends Plugin
}
@Override
public Overlay getOverlay()
protected void shutDown() throws Exception
{
return null;
}
private void setPluginPanel(ActionEvent e)

View File

@@ -30,6 +30,7 @@ import java.awt.TrayIcon;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import static net.runelite.api.AnimationID.*;
import net.runelite.api.Client;
@@ -37,7 +38,6 @@ import net.runelite.api.GameState;
import net.runelite.client.RuneLite;
import net.runelite.client.events.AnimationChanged;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.ui.overlay.Overlay;
public class IdleNotifier extends Plugin
{
@@ -48,19 +48,21 @@ public class IdleNotifier extends Plugin
private final Client client = RuneLite.getClient();
private final TrayIcon trayIcon = RuneLite.getTrayIcon();
private ScheduledFuture<?> future;
private Instant lastAnimating;
private boolean notifyIdle = false;
@Override
public Overlay getOverlay()
{
return null;
}
public IdleNotifier()
protected void startUp() throws Exception
{
ScheduledExecutorService executor = RuneLite.getRunelite().getExecutor();
executor.scheduleAtFixedRate(this::checkIdle, CHECK_INTERVAL, CHECK_INTERVAL, TimeUnit.SECONDS);
future = executor.scheduleAtFixedRate(this::checkIdle, CHECK_INTERVAL, CHECK_INTERVAL, TimeUnit.SECONDS);
}
@Override
protected void shutDown() throws Exception
{
future.cancel(true);
}
@Subscribe
@@ -124,7 +126,7 @@ public class IdleNotifier extends Plugin
private void checkIdle()
{
if (notifyIdle && client.getLocalPlayer().getAnimation() == IDLE
&& Instant.now().compareTo(lastAnimating.plus(WAIT_DURATION)) >= 0)
&& Instant.now().compareTo(lastAnimating.plus(WAIT_DURATION)) >= 0)
{
trayIcon.displayMessage("RuneLite", "You are now idle.", TrayIcon.MessageType.NONE);

View File

@@ -22,7 +22,6 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.opponentinfo;
import com.google.common.reflect.TypeToken;
@@ -44,6 +43,16 @@ public class OpponentInfo extends Plugin
return overlay;
}
@Override
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
}
public static Map<String, Integer> loadNpcHealth()
{
Gson gson = new Gson();

View File

@@ -37,4 +37,13 @@ public class Runecraft extends Plugin
return overlay;
}
@Override
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
}
}

View File

@@ -51,9 +51,13 @@ public class Xtea extends Plugin
private final Set<Integer> sentRegions = new HashSet<>();
@Override
public Overlay getOverlay()
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
return null;
}
@Subscribe