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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,14 @@ public class Boosts extends Plugin
|
||||
{
|
||||
return overlay;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -37,4 +37,14 @@ public class FPS extends Plugin
|
||||
{
|
||||
return overlay;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -37,4 +37,13 @@ public class Runecraft extends Plugin
|
||||
return overlay;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user