Merge remote-tracking branch 'upstream/master' into slayer-v2

This commit is contained in:
Owain van Brakel
2019-07-26 00:58:06 +02:00
124 changed files with 1681 additions and 843 deletions

View File

@@ -35,6 +35,9 @@ import net.runelite.http.api.RuneLiteAPI;
@Slf4j
public class RuneLiteProperties
{
private static final String DISCORD_APP_ID = "409416265891971072";
private static final String DISCORD_APP_ID_PLUS = "560644885250572289";
private final Properties properties = new Properties();
private final RuneLitePlusConfig runeLitePlusConfig;
@@ -78,7 +81,19 @@ public class RuneLiteProperties
public String getDiscordAppId()
{
return "560644885250572289";
if (this.runeLitePlusConfig == null)
{
return properties.getProperty(DISCORD_APP_ID);
}
if (this.runeLitePlusConfig.customPresence())
{
return properties.getProperty(DISCORD_APP_ID_PLUS);
}
else
{
return properties.getProperty(DISCORD_APP_ID);
}
}
public String getDiscordInvite()

View File

@@ -43,7 +43,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.nio.channels.FileLock;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
@@ -108,7 +108,7 @@ public class ConfigManager
final Properties properties = new Properties();
try (FileInputStream in = new FileInputStream(propertiesFile))
{
properties.load(new InputStreamReader(in, Charset.forName("UTF-8")));
properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
}
catch (Exception e)
{
@@ -116,7 +116,7 @@ public class ConfigManager
return;
}
final Map<String, String> copy = (Map) ImmutableMap.copyOf(this.properties);
@SuppressWarnings("unchecked") final Map<String, String> copy = (Map) ImmutableMap.copyOf(this.properties);
copy.forEach((groupAndKey, value) ->
{
if (!properties.containsKey(groupAndKey))
@@ -160,7 +160,7 @@ public class ConfigManager
try (FileInputStream in = new FileInputStream(SETTINGS_FILE))
{
properties.load(new InputStreamReader(in, Charset.forName("UTF-8")));
properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
}
catch (FileNotFoundException ex)
{
@@ -174,7 +174,7 @@ public class ConfigManager
try
{
Map<String, String> copy = (Map) ImmutableMap.copyOf(properties);
@SuppressWarnings("unchecked") Map<String, String> copy = (Map) ImmutableMap.copyOf(properties);
copy.forEach((groupAndKey, value) ->
{
final String[] split = groupAndKey.split("\\.", 2);
@@ -212,7 +212,7 @@ public class ConfigManager
try
{
properties.store(new OutputStreamWriter(out, Charset.forName("UTF-8")), "RuneLite configuration");
properties.store(new OutputStreamWriter(out, StandardCharsets.UTF_8), "RuneLite configuration");
}
finally
{
@@ -235,6 +235,7 @@ public class ConfigManager
eventBus.post(ConfigChanged.class, configChanged);
}
@SuppressWarnings("unchecked")
public <T> T getConfig(Class<T> clazz)
{
if (!Modifier.isPublic(clazz.getModifiers()))
@@ -263,6 +264,7 @@ public class ConfigManager
return properties.getProperty(propertyKey);
}
@SuppressWarnings("unchecked")
public <T> T getConfiguration(String groupName, String key, Class<T> clazz)
{
String value = getConfiguration(groupName, key);
@@ -464,6 +466,7 @@ public class ConfigManager
}
}
@SuppressWarnings("unchecked")
static Object stringToObject(String str, Class<?> type)
{
if (type == boolean.class || type == Boolean.class)
@@ -633,22 +636,34 @@ public class ConfigManager
newestFile = STANDARD_SETTINGS_FILE;
for (File profileDir : PROFILES_DIR.listFiles())
{
if (!profileDir.isDirectory())
{
continue;
}
File[] profileDirFiles = PROFILES_DIR.listFiles();
for (File settings : profileDir.listFiles())
if (profileDirFiles != null)
{
for (File profileDir : profileDirFiles)
{
if (!settings.getName().equals(STANDARD_SETTINGS_FILE_NAME) ||
settings.lastModified() < newestFile.lastModified())
if (!profileDir.isDirectory())
{
continue;
}
newestFile = settings;
File[] settingsFiles = profileDir.listFiles();
if (settingsFiles == null)
{
continue;
}
for (File settings : settingsFiles)
{
if (!settings.getName().equals(STANDARD_SETTINGS_FILE_NAME) ||
settings.lastModified() < newestFile.lastModified())
{
continue;
}
newestFile = settings;
}
}
}

View File

@@ -43,6 +43,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -410,6 +411,7 @@ public class ItemManager
* @param itemId item id
* @return item composition
*/
@Nonnull
public ItemDefinition getItemDefinition(int itemId)
{
assert client.isClientThread() : "getItemDefinition must be called on client thread";

View File

@@ -38,7 +38,7 @@ import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.AnimationID;
import net.runelite.api.Client;
import net.runelite.api.Item;
import net.runelite.api.TileItem;
import net.runelite.api.ItemID;
import net.runelite.api.NPC;
import net.runelite.api.NpcID;
@@ -163,7 +163,7 @@ public class LootManager
private void onItemSpawned(ItemSpawned itemSpawned)
{
final Item item = itemSpawned.getItem();
final TileItem item = itemSpawned.getItem();
final Tile tile = itemSpawned.getTile();
final LocalPoint location = tile.getLocalLocation();
final int packed = location.getSceneX() << 8 | location.getSceneY();
@@ -173,14 +173,14 @@ public class LootManager
private void onItemDespawned(ItemDespawned itemDespawned)
{
final Item item = itemDespawned.getItem();
final TileItem item = itemDespawned.getItem();
final LocalPoint location = itemDespawned.getTile().getLocalLocation();
log.debug("Item despawn {} ({}) location {},{}", item.getId(), item.getQuantity(), location);
}
private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged)
{
final Item item = itemQuantityChanged.getItem();
final TileItem item = itemQuantityChanged.getItem();
final Tile tile = itemQuantityChanged.getTile();
final LocalPoint location = tile.getLocalLocation();
final int packed = location.getSceneX() << 8 | location.getSceneY();

View File

@@ -0,0 +1,314 @@
/*
* Copyright (c) 2019, Ron Young <https://github.com/raiyni>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (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.game.chatbox;
import com.google.common.primitives.Ints;
import com.google.inject.Inject;
import java.awt.event.KeyEvent;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;
import javax.inject.Singleton;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.ItemDefinition;
import net.runelite.api.widgets.ItemQuantityMode;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetTextAlignment;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.game.ItemManager;
@Singleton
public class ChatboxItemSearch extends ChatboxTextInput
{
private static final int ICON_HEIGHT = 32;
private static final int ICON_WIDTH = 36;
private static final int PADDING = 6;
private static final int MAX_RESULTS = 24;
private static final int FONT_SIZE = 16;
private static final int HOVERED_OPACITY = 128;
private final ChatboxPanelManager chatboxPanelManager;
private final ItemManager itemManager;
private final Client client;
private Map<Integer, ItemDefinition> results = new LinkedHashMap<>();
private String tooltipText;
private int index = -1;
@Getter
private Consumer<Integer> onItemSelected;
@Inject
private ChatboxItemSearch(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread,
ItemManager itemManager, Client client)
{
super(chatboxPanelManager, clientThread);
this.chatboxPanelManager = chatboxPanelManager;
this.itemManager = itemManager;
this.client = client;
lines(1);
prompt("Item Search");
onChanged(searchString ->
clientThread.invokeLater(() ->
{
filterResults();
update();
}));
}
@Override
protected void update()
{
Widget container = chatboxPanelManager.getContainerWidget();
container.deleteAllChildren();
Widget promptWidget = container.createChild(-1, WidgetType.TEXT);
promptWidget.setText(getPrompt());
promptWidget.setTextColor(0x800000);
promptWidget.setFontId(getFontID());
promptWidget.setOriginalX(0);
promptWidget.setOriginalY(5);
promptWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
promptWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
promptWidget.setOriginalHeight(FONT_SIZE);
promptWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
promptWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
promptWidget.setWidthMode(WidgetSizeMode.MINUS);
promptWidget.revalidate();
buildEdit(0, 5 + FONT_SIZE, container.getWidth(), FONT_SIZE);
Widget separator = container.createChild(-1, WidgetType.LINE);
separator.setOriginalX(0);
separator.setOriginalY(8 + (FONT_SIZE * 2));
separator.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
separator.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
separator.setOriginalHeight(0);
separator.setOriginalWidth(16);
separator.setWidthMode(WidgetSizeMode.MINUS);
separator.setTextColor(0x666666);
separator.revalidate();
int x = PADDING;
int y = PADDING * 3;
int idx = 0;
for (ItemDefinition itemDefinition : results.values())
{
Widget item = container.createChild(-1, WidgetType.GRAPHIC);
item.setXPositionMode(WidgetPositionMode.ABSOLUTE_LEFT);
item.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
item.setOriginalX(x);
item.setOriginalY(y + FONT_SIZE * 2);
item.setOriginalHeight(ICON_HEIGHT);
item.setOriginalWidth(ICON_WIDTH);
item.setName("<col=ff9040>" + itemDefinition.getName());
item.setItemId(itemDefinition.getId());
item.setItemQuantity(10000);
item.setItemQuantityMode(ItemQuantityMode.NEVER);
item.setBorderType(1);
item.setAction(0, tooltipText);
item.setHasListener(true);
if (index == idx)
{
item.setOpacity(HOVERED_OPACITY);
}
else
{
item.setOnMouseOverListener((JavaScriptCallback) ev -> item.setOpacity(HOVERED_OPACITY));
item.setOnMouseLeaveListener((JavaScriptCallback) ev -> item.setOpacity(0));
}
item.setOnOpListener((JavaScriptCallback) ev ->
{
if (onItemSelected != null)
{
onItemSelected.accept(itemDefinition.getId());
}
chatboxPanelManager.close();
});
x += ICON_WIDTH + PADDING;
if (x + ICON_WIDTH >= container.getWidth())
{
y += ICON_HEIGHT + PADDING;
x = PADDING;
}
item.revalidate();
++idx;
}
}
@Override
public void keyPressed(KeyEvent ev)
{
switch (ev.getKeyCode())
{
case KeyEvent.VK_ENTER:
ev.consume();
if (index > -1)
{
if (onItemSelected != null)
{
onItemSelected.accept(results.keySet().toArray(new Integer[results.size()])[index]);
}
chatboxPanelManager.close();
}
break;
case KeyEvent.VK_TAB:
case KeyEvent.VK_RIGHT:
ev.consume();
if (!results.isEmpty())
{
index++;
if (index >= results.size())
{
index = 0;
}
clientThread.invokeLater(this::update);
}
break;
case KeyEvent.VK_LEFT:
ev.consume();
if (!results.isEmpty())
{
index--;
if (index < 0)
{
index = results.size() - 1;
}
clientThread.invokeLater(this::update);
}
break;
case KeyEvent.VK_UP:
ev.consume();
if (results.size() >= (MAX_RESULTS / 2))
{
index -= MAX_RESULTS / 2;
if (index < 0)
{
if (results.size() == MAX_RESULTS)
{
index += results.size();
}
else
{
index += MAX_RESULTS;
}
index = Ints.constrainToRange(index, 0, results.size() - 1);
}
clientThread.invokeLater(this::update);
}
break;
case KeyEvent.VK_DOWN:
ev.consume();
if (results.size() >= (MAX_RESULTS / 2))
{
index += MAX_RESULTS / 2;
if (index >= MAX_RESULTS)
{
if (results.size() == MAX_RESULTS)
{
index -= results.size();
}
else
{
index -= MAX_RESULTS;
}
index = Ints.constrainToRange(index, 0, results.size() - 1);
}
clientThread.invokeLater(this::update);
}
break;
default:
super.keyPressed(ev);
}
}
@Override
protected void close()
{
// Clear search string when closed
value("");
results.clear();
index = -1;
super.close();
}
@Override
@Deprecated
public ChatboxTextInput onDone(Consumer<String> onDone)
{
throw new UnsupportedOperationException();
}
private void filterResults()
{
results.clear();
index = -1;
String search = getValue().toLowerCase();
if (search.isEmpty())
{
return;
}
for (int i = 0; i < client.getItemCount() && results.size() < MAX_RESULTS; i++)
{
ItemDefinition itemComposition = itemManager.getItemDefinition(itemManager.canonicalize(i));
String name = itemComposition.getName();
// The client assigns "null" to item names of items it doesn't know about
if (!name.equals("null") && name.toLowerCase().contains(search))
{
// This may already be in the map due to canonicalize mapping the item to something we've already seen
results.putIfAbsent(itemComposition.getId(), itemComposition);
}
}
}
public ChatboxItemSearch onItemSelected(Consumer<Integer> onItemSelected)
{
this.onItemSelected = onItemSelected;
return this;
}
public ChatboxItemSearch tooltipText(final String text)
{
tooltipText = text;
return this;
}
}

View File

@@ -67,7 +67,7 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse
private static final Pattern BREAK_MATCHER = Pattern.compile("[^a-zA-Z0-9']");
private final ChatboxPanelManager chatboxPanelManager;
private final ClientThread clientThread;
protected final ClientThread clientThread;
private static IntPredicate getDefaultCharValidator()
{

View File

@@ -118,6 +118,9 @@ public class PluginManager
this.configManager = configManager;
this.executor = executor;
this.sceneTileManager = sceneTileManager;
eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen);
eventBus.subscribe(SessionClose.class, this, this::onSessionClose);
}
public void watch()
@@ -171,7 +174,7 @@ public class PluginManager
return null;
}
public List<Config> getPluginConfigProxies()
private List<Config> getPluginConfigProxies()
{
List<Injector> injectors = new ArrayList<>();
injectors.add(RuneLite.getInjector());
@@ -224,6 +227,7 @@ public class PluginManager
}
}
@SuppressWarnings("unchecked")
List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException
{
MutableGraph<Class<? extends Plugin>> graph = GraphBuilder
@@ -266,7 +270,7 @@ public class PluginManager
continue;
}
Class<Plugin> pluginClass = (Class<Plugin>) clazz;
@SuppressWarnings("unchecked") Class<Plugin> pluginClass = (Class<Plugin>) clazz;
graph.addNode(pluginClass);
}
@@ -428,13 +432,14 @@ public class PluginManager
if (value != null)
{
return Boolean.valueOf(value);
return Boolean.parseBoolean(value);
}
final PluginDescriptor pluginDescriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
return pluginDescriptor == null || pluginDescriptor.enabledByDefault();
}
@SuppressWarnings("unchecked")
private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz) throws PluginInstantiationException
{
PluginDependency[] pluginDependencies = clazz.getAnnotationsByType(PluginDependency.class);

View File

@@ -37,7 +37,6 @@ import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Item;
import net.runelite.api.ItemID;
import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET;
import net.runelite.api.MenuAction;
@@ -46,6 +45,7 @@ import net.runelite.api.Player;
import net.runelite.api.Skill;
import static net.runelite.api.Skill.AGILITY;
import net.runelite.api.Tile;
import net.runelite.api.TileItem;
import net.runelite.api.TileObject;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.BoostedLevelChanged;
@@ -321,7 +321,7 @@ public class AgilityPlugin extends Plugin
return;
}
final Item item = itemSpawned.getItem();
final TileItem item = itemSpawned.getItem();
final Tile tile = itemSpawned.getTile();
if (item.getId() == ItemID.MARK_OF_GRACE)

View File

@@ -85,7 +85,7 @@ public class BankSearch
// selecting/changing tab
if (closeInput)
{
client.runScript(ScriptID.RESET_CHATBOX_INPUT);
client.runScript(ScriptID.RESET_CHATBOX_INPUT, 0, 0);
}
client.setVar(VarClientInt.INPUT_TYPE, inputType.getType());

View File

@@ -78,6 +78,7 @@ import net.runelite.api.widgets.WidgetType;
import net.runelite.client.Notifier;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.chatbox.ChatboxItemSearch;
import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.plugins.banktags.BankTagsConfig;
import net.runelite.client.plugins.banktags.BankTagsPlugin;
@@ -113,6 +114,7 @@ public class TabInterface
private static final int SCROLL_TICK = 500;
private static final int INCINERATOR_WIDTH = 48;
private static final int INCINERATOR_HEIGHT = 39;
private static TagTab iconToSet;
private final Client client;
private final ClientThread clientThread;
@@ -126,10 +128,10 @@ public class TabInterface
private final Rectangle bounds = new Rectangle();
private final Rectangle canvasBounds = new Rectangle();
private ChatboxItemSearch searchProvider;
private TagTab activeTab;
private int maxTabs;
private int currentTabIndex;
private TagTab iconToSet = null;
private Instant startScroll = Instant.now();
private String rememberedSearch;
private boolean waitSearchTick;
@@ -156,7 +158,8 @@ public class TabInterface
final ChatboxPanelManager chatboxPanelManager,
final BankTagsConfig config,
final Notifier notifier,
final BankSearch bankSearch)
final BankSearch bankSearch,
final ChatboxItemSearch searchProvider)
{
this.client = client;
this.clientThread = clientThread;
@@ -167,6 +170,7 @@ public class TabInterface
this.config = config;
this.notifier = notifier;
this.bankSearch = bankSearch;
this.searchProvider = searchProvider;
}
public boolean isActive()
@@ -333,7 +337,7 @@ public class TabInterface
{
bankSearch.reset(true);
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT, 0, 0));
}
else
{
@@ -343,7 +347,20 @@ public class TabInterface
client.playSoundEffect(SoundEffectID.UI_BOOP);
break;
case Tab.CHANGE_ICON:
iconToSet = tabManager.find(Text.removeTags(event.getOpbase()));
final String tag = Text.removeTags(event.getOpbase());
searchProvider
.tooltipText(CHANGE_ICON + " (" + tag + ")")
.onItemSelected((itemId) ->
{
TagTab iconToSet = tabManager.find(tag);
if (iconToSet != null)
{
iconToSet.setIconItemId(itemId);
iconToSet.getIcon().setItemId(itemId);
tabManager.setIcon(iconToSet.getTag(), itemId + "");
}
})
.build();
break;
case Tab.DELETE_TAB:
String target = Text.standardize(event.getOpbase());
@@ -526,12 +543,6 @@ public class TabInterface
entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries);
client.setMenuEntries(entries);
}
else if (iconToSet != null && (entry.getOption().startsWith("Withdraw-") || entry.getOption().equals("Release")))
{
// TODO: Do not replace every withdraw option with change icon option
entry.setOption(CHANGE_ICON + " (" + iconToSet.getTag() + ")");
client.setMenuEntries(entries);
}
else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId()
&& event.getOption().equals("Deposit inventory"))
{

View File

@@ -27,12 +27,15 @@ package net.runelite.client.plugins.chatboxperformance;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client;
import net.runelite.api.events.WidgetPositioned;
import net.runelite.api.GameState;
import net.runelite.api.ScriptID;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetSizeMode;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
@@ -47,50 +50,39 @@ public class ChatboxPerformancePlugin extends Plugin
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private EventBus eventBus;
@Override
protected void startUp() throws Exception
public void startUp()
{
eventBus.subscribe(WidgetPositioned.class, this, this::onWidgetPositioned);
eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent);
if (client.getGameState() == GameState.LOGGED_IN)
{
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
}
}
@Override
protected void shutDown() throws Exception
public void shutDown()
{
if (client.getGameState() == GameState.LOGGED_IN)
{
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
}
eventBus.unregister(this);
}
private void onWidgetPositioned(WidgetPositioned event)
private void onScriptCallbackEvent(ScriptCallbackEvent ev)
{
if (!areWidgetsFixed())
if (!"chatboxBackgroundBuilt".equals(ev.getEventName()))
{
fixChatbox();
}
}
private boolean areWidgetsFixed()
{
Widget widget = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND);
if (widget == null)
{
return true;
return;
}
Widget[] widgets = widget.getChildren();
if (widgets != null && widgets.length > 0)
{
Widget last = widgets[widgets.length - 1];
return last != null && last.getOpacity() < 254;
}
return false;
}
private void fixChatbox()
{
fixDarkBackground();
fixWhiteLines(true);
fixWhiteLines(false);

View File

@@ -34,6 +34,6 @@ class JagexPrintableCharMatcher extends CharMatcher
// Characters which are printable
return (c >= 32 && c <= 126)
|| c == 128
|| (c >= 161 && c <= 255);
|| (c >= 160 && c <= 255);
}
}

View File

@@ -119,6 +119,7 @@ public class ClanChatPlugin extends Plugin
private List<String> chats = new ArrayList<>();
@SuppressWarnings("unchecked")
public static CopyOnWriteArrayList<Player> getClanMembers()
{
return (CopyOnWriteArrayList<Player>) clanMembers.clone();

View File

@@ -203,7 +203,7 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc
.leftColor(TITLED_CONTENT_COLOR)
.build());
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build());
panelComponent.getChildren().add(LineComponent.builder().left("Location:").build());
panelComponent.getChildren().add(LineComponent.builder()
.left(getArea())
.leftColor(TITLED_CONTENT_COLOR)

View File

@@ -85,7 +85,7 @@ public class CipherClue extends ClueScroll implements TextClueScroll, NpcClueScr
.leftColor(TITLED_CONTENT_COLOR)
.build());
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build());
panelComponent.getChildren().add(LineComponent.builder().left("Location:").build());
panelComponent.getChildren().add(LineComponent.builder()
.left(getArea())
.leftColor(TITLED_CONTENT_COLOR)

View File

@@ -160,7 +160,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat
else
{
panelComponent.getChildren().add(LineComponent.builder()
.left("Possible areas:")
.left("Possible locations:")
.build());
final Map<HotColdArea, Integer> locationCounts = new EnumMap<>(HotColdArea.class);

View File

@@ -61,7 +61,7 @@ public class MusicClue extends ClueScroll implements NpcClueScroll
.leftColor(TITLED_CONTENT_COLOR)
.build());
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build());
panelComponent.getChildren().add(LineComponent.builder().left("Location:").build());
panelComponent.getChildren().add(LineComponent.builder()
.left("Falador Park")
.leftColor(TITLED_CONTENT_COLOR)

View File

@@ -526,6 +526,7 @@ public class ConfigPanel extends PluginPanel
openGroupConfigPanel(listItem, config, cd, false);
}
@SuppressWarnings("unchecked")
private void openGroupConfigPanel(PluginListItem listItem, Config config, ConfigDescriptor cd, boolean refresh)
{
showingPluginList = false;
@@ -657,10 +658,10 @@ public class ConfigPanel extends PluginPanel
}
else if (cid2.getType().isEnum())
{
Class<? extends Enum> type = (Class<? extends Enum>) cid2.getType();
@SuppressWarnings("unchecked") Class<? extends Enum> type = (Class<? extends Enum>) cid2.getType();
try
{
Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName()));
@SuppressWarnings("unchecked") Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName()));
if (!cid.getItem().unhideValue().equals(""))
{
show = selectedItem.toString().equals(cid.getItem().unhideValue());
@@ -1307,7 +1308,7 @@ public class ConfigPanel extends PluginPanel
return new Dimension(PANEL_WIDTH + SCROLLBAR_WIDTH, super.getPreferredSize().height);
}
private class FixedWidthPanel extends JPanel
private static class FixedWidthPanel extends JPanel
{
@Override
public Dimension getPreferredSize()

View File

@@ -44,8 +44,8 @@ import net.runelite.api.DecorativeObject;
import net.runelite.api.DynamicObject;
import net.runelite.api.GameObject;
import net.runelite.api.GraphicsObject;
import net.runelite.api.TileItem;
import net.runelite.api.GroundObject;
import net.runelite.api.Item;
import net.runelite.api.ItemLayer;
import net.runelite.api.NPC;
import net.runelite.api.NPCDefinition;
@@ -285,9 +285,9 @@ class DevToolsOverlay extends Overlay
if (player.getLocalLocation().distanceTo(itemLayer.getLocalLocation()) <= MAX_DISTANCE)
{
Node current = itemLayer.getBottom();
while (current instanceof Item)
while (current instanceof TileItem)
{
Item item = (Item) current;
TileItem item = (TileItem) current;
OverlayUtil.renderTileOverlay(graphics, itemLayer, "ID: " + item.getId() + " Qty:" + item.getQuantity(), RED);
current = current.getNext();
}

View File

@@ -67,6 +67,7 @@ public class WidgetField<T>
return MessageFormatter.format("{}", value).getMessage();
}
@SuppressWarnings("unchecked")
void setValue(Widget widget, Object inValue)
{
Object value = null;

View File

@@ -57,6 +57,7 @@ import net.runelite.client.util.ImageUtil;
public class EmojiPlugin extends Plugin
{
private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>");
private static final Pattern WHITESPACE_REGEXP = Pattern.compile("[\\s\\u00A0]");
@Inject
private Client client;
@@ -182,9 +183,9 @@ public class EmojiPlugin extends Plugin
}
@Nullable
private String updateMessage(final String message)
String updateMessage(final String message)
{
final String[] messageWords = message.split(" ");
final String[] messageWords = WHITESPACE_REGEXP.split(message);
boolean editedMessage = false;
for (int i = 0; i < messageWords.length; i++)

View File

@@ -281,6 +281,7 @@ public interface GroundItemsConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "itemHighlightMode",
name = "Item Highlight Mode",
@@ -616,11 +617,11 @@ public interface GroundItemsConfig extends Config
}
@ConfigItem(
keyName = "showTimer",
name = "Show ground item tick countdown timer",
description = "Shows how many ticks left until disappearing.",
position = 48,
parent = "miscStub"
keyName = "showTimer",
name = "Show ground item tick countdown timer",
description = "Shows how many ticks left until disappearing.",
position = 48,
parent = "miscStub"
)
default boolean showTimer()
{

View File

@@ -52,7 +52,6 @@ import lombok.Getter;
import lombok.Setter;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.Item;
import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemID;
import net.runelite.api.ItemLayer;
@@ -62,16 +61,17 @@ import net.runelite.api.Node;
import net.runelite.api.Player;
import net.runelite.api.Scene;
import net.runelite.api.Tile;
import net.runelite.api.TileItem;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.FocusChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.ItemDespawned;
import net.runelite.api.events.ItemQuantityChanged;
import net.runelite.api.events.ItemSpawned;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.GameTick;
import net.runelite.client.Notifier;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus;
@@ -105,9 +105,10 @@ import net.runelite.client.util.Text;
@Singleton
public class GroundItemsPlugin extends Plugin
{
@Getter(AccessLevel.PUBLIC)
public static final Map<GroundItem.GroundItemKey, GroundItem> collectedGroundItems = new LinkedHashMap<>();
// ItemID for coins
private static final int COINS = ItemID.COINS_995;
// items stay on the ground for 30 mins in an instance
private static final int INSTANCE_DURATION_MILLIS = 45 * 60 * 1000;
private static final int INSTANCE_DURATION_TICKS = (int) floor(30 * 60 / 0.6);
@@ -119,7 +120,6 @@ public class GroundItemsPlugin extends Plugin
private static final int DEATH_DURATION_TICKS = (int) floor(60 * 60 / 0.6);
private static final int NORMAL_DURATION_MILLIS = 60 * 1000;
private static final int NORMAL_DURATION_TICKS = (int) floor(60 / 0.6);
// Ground item menu options
private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId();
private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId();
@@ -129,65 +129,45 @@ public class GroundItemsPlugin extends Plugin
private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId();
private static final int WALK = MenuAction.WALK.getId();
private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId();
private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE);
private final Map<Integer, Color> priceChecks = new LinkedHashMap<>();
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private Map.Entry<Rectangle, GroundItem> textBoxBounds;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private Map.Entry<Rectangle, GroundItem> hiddenBoxBounds;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private Map.Entry<Rectangle, GroundItem> highlightBoxBounds;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private boolean hotKeyPressed;
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private boolean hideAll;
private List<String> hiddenItemList = new CopyOnWriteArrayList<>();
private List<String> highlightedItemsList = new CopyOnWriteArrayList<>();
@Inject
private GroundItemInputListener inputListener;
@Inject
private MouseManager mouseManager;
@Inject
private KeyManager keyManager;
@Inject
private Client client;
@Inject
private ItemManager itemManager;
@Inject
private OverlayManager overlayManager;
@Inject
private GroundItemsConfig config;
@Inject
private GroundItemsOverlay overlay;
@Inject
private Notifier notifier;
@Inject
private EventBus eventBus;
@Getter(AccessLevel.PUBLIC)
public static final Map<GroundItem.GroundItemKey, GroundItem> collectedGroundItems = new LinkedHashMap<>();
private final Map<Integer, Color> priceChecks = new LinkedHashMap<>();
private LoadingCache<String, Boolean> highlightedItems;
private LoadingCache<String, Boolean> hiddenItems;
@@ -323,7 +303,7 @@ public class GroundItemsPlugin extends Plugin
private void onItemSpawned(ItemSpawned itemSpawned)
{
Item item = itemSpawned.getItem();
TileItem item = itemSpawned.getItem();
Tile tile = itemSpawned.getTile();
GroundItem groundItem = buildGroundItem(tile, item);
@@ -348,7 +328,7 @@ public class GroundItemsPlugin extends Plugin
private void onItemDespawned(ItemDespawned itemDespawned)
{
Item item = itemDespawned.getItem();
TileItem item = itemDespawned.getItem();
Tile tile = itemDespawned.getTile();
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
@@ -370,7 +350,7 @@ public class GroundItemsPlugin extends Plugin
private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged)
{
Item item = itemQuantityChanged.getItem();
TileItem item = itemQuantityChanged.getItem();
Tile tile = itemQuantityChanged.getTile();
int oldQuantity = itemQuantityChanged.getOldQuantity();
int newQuantity = itemQuantityChanged.getNewQuantity();
@@ -441,7 +421,7 @@ public class GroundItemsPlugin extends Plugin
}
}
private void sendLootNotification(String itemName, String message)
private void sendLootNotification(String itemName, String message)
{
String notification = "[" + client.getLocalPlayer().getName() + "] " +
"Received a " + message + " item: " + itemName;
@@ -462,7 +442,7 @@ public class GroundItemsPlugin extends Plugin
{
int menuType = menuEntry.getType();
if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION
|| menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM)
|| menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM)
{
for (MenuEntryWithCount entryWCount : newEntries)
{
@@ -484,13 +464,13 @@ public class GroundItemsPlugin extends Plugin
{
final int aMenuType = a.getEntry().getType();
if (aMenuType == FIRST_OPTION || aMenuType == SECOND_OPTION || aMenuType == THIRD_OPTION
|| aMenuType == FOURTH_OPTION || aMenuType == FIFTH_OPTION || aMenuType == EXAMINE_ITEM
|| aMenuType == WALK)
|| aMenuType == FOURTH_OPTION || aMenuType == FIFTH_OPTION || aMenuType == EXAMINE_ITEM
|| aMenuType == WALK)
{ // only check for item related menu types, so we don't sort other stuff
final int bMenuType = b.getEntry().getType();
if (bMenuType == FIRST_OPTION || bMenuType == SECOND_OPTION || bMenuType == THIRD_OPTION
|| bMenuType == FOURTH_OPTION || bMenuType == FIFTH_OPTION || bMenuType == EXAMINE_ITEM
|| bMenuType == WALK)
|| bMenuType == FOURTH_OPTION || bMenuType == FIFTH_OPTION || bMenuType == EXAMINE_ITEM
|| bMenuType == WALK)
{
final MenuEntry aEntry = a.getEntry();
final int aId = aEntry.getIdentifier();
@@ -579,7 +559,7 @@ public class GroundItemsPlugin extends Plugin
}
}
private GroundItem buildGroundItem(final Tile tile, final Item item)
private GroundItem buildGroundItem(final Tile tile, final TileItem item)
{
// Collect the data for the item
final int itemId = item.getId();
@@ -711,9 +691,9 @@ public class GroundItemsPlugin extends Plugin
int quantity = 1;
Node current = itemLayer.getBottom();
while (current instanceof Item)
while (current instanceof TileItem)
{
Item item = (Item) current;
TileItem item = (TileItem) current;
if (item.getId() == itemId)
{
quantity = item.getQuantity();
@@ -878,8 +858,8 @@ public class GroundItemsPlugin extends Plugin
// Explicit highlight takes priority over implicit hide
return isExplicitHidden || (!isExplicitHighlight && canBeHidden && underGe && underHa)
? this.hiddenColor
: null;
? this.hiddenColor
: null;
}
private int getGePriceFromItemId(int itemId)

View File

@@ -34,5 +34,5 @@ public enum PriceDisplayMode
HA,
GE,
BOTH,
OFF;
OFF
}

View File

@@ -34,5 +34,5 @@ public enum ValueCalculationMode
{
HA, // calc highlight by HA value
GE, // calc by GE
HIGHEST;
HIGHEST
}

View File

@@ -190,6 +190,7 @@ public class GroundMarkerPlugin extends Plugin
* @param points
* @return
*/
@SuppressWarnings("unchecked")
private Collection<GroundMarkerWorldPoint> translateToWorld(Collection<GroundMarkerPoint> points)
{
if (points.isEmpty())
@@ -299,38 +300,38 @@ public class GroundMarkerPlugin extends Plugin
if (hotKeyPressed && event.getOption().equals(WALK_HERE))
{
MenuEntry[] menuEntries = client.getMenuEntries();
int lastIndex = menuEntries.length;
menuEntries = Arrays.copyOf(menuEntries, lastIndex + 4);
int lastIndex = menuEntries.length;
menuEntries = Arrays.copyOf(menuEntries, lastIndex + 4);
final Tile tile = client.getSelectedSceneTile();
if (tile == null)
{
return;
}
final WorldPoint loc = WorldPoint.fromLocalInstance(client, tile.getLocalLocation());
final int regionId = loc.getRegionID();
final Tile tile = client.getSelectedSceneTile();
if (tile == null)
{
return;
}
final WorldPoint loc = WorldPoint.fromLocalInstance(client, tile.getLocalLocation());
final int regionId = loc.getRegionID();
for (int i = 4; i > 0; i--)
{
MenuEntry menuEntry = menuEntries[lastIndex] = new MenuEntry();
for (int i = 4; i > 0; i--)
{
MenuEntry menuEntry = menuEntries[lastIndex] = new MenuEntry();
final GroundMarkerPoint point = new GroundMarkerPoint(regionId, loc.getRegionX(), loc.getRegionY(), client.getPlane(), i);
final Optional<GroundMarkerPoint> stream = getPoints(regionId).stream().filter(x -> x.equals(point)).findAny();
final String option = (stream.isPresent() && stream.get().getGroup() == i) ? UNMARK : MARK;
menuEntry.setOption(ColorUtil.prependColorTag(Text.removeTags(option + (i == 1 ? "" : " (Group " + i + ")")), getColor(i)));
menuEntry.setTarget(event.getTarget());
menuEntry.setType(MenuAction.RUNELITE.getId());
lastIndex++;
}
final GroundMarkerPoint point = new GroundMarkerPoint(regionId, loc.getRegionX(), loc.getRegionY(), client.getPlane(), i);
final Optional<GroundMarkerPoint> stream = getPoints(regionId).stream().filter(x -> x.equals(point)).findAny();
final String option = (stream.isPresent() && stream.get().getGroup() == i) ? UNMARK : MARK;
menuEntry.setOption(ColorUtil.prependColorTag(Text.removeTags(option + (i == 1 ? "" : " (Group " + i + ")")), getColor(i)));
menuEntry.setTarget(event.getTarget());
menuEntry.setType(MenuAction.RUNELITE.getId());
lastIndex++;
}
client.setMenuEntries(menuEntries);
}
}
private void onMenuOptionClicked(MenuOptionClicked event)
{
if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() || (!event.getOption().contains(MARK) && !event.getOption().contains(UNMARK)))
if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() ||
!(event.getOption().equals(MARK) || event.getOption().equals(UNMARK)))
{
return;
}

View File

@@ -53,14 +53,6 @@ enum HealthbarOverride implements SpriteOverride
FRONT_140PX(HEALTHBAR_DEFAULT_FRONT_140PX, "front_90px.png"),
FRONT_160PX(HEALTHBAR_DEFAULT_FRONT_160PX, "front_90px.png");
@Getter(AccessLevel.PUBLIC)
private final int spriteId;
private final String fileName;
@Getter(AccessLevel.PACKAGE)
private int padding = 1;
private static final Map<Integer, HealthbarOverride> MAP;
static
@@ -75,6 +67,12 @@ enum HealthbarOverride implements SpriteOverride
MAP = builder.build();
}
@Getter(AccessLevel.PUBLIC)
private final int spriteId;
private final String fileName;
@Getter(AccessLevel.PACKAGE)
private int padding = 1;
static HealthbarOverride get(int spriteID)
{
return MAP.get(spriteID);

View File

@@ -34,8 +34,8 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.HealthBar;
import net.runelite.api.SpriteID;
import net.runelite.api.Sprite;
import net.runelite.api.SpriteID;
import net.runelite.api.events.BeforeMenuRender;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;

View File

@@ -98,7 +98,7 @@ class InventoryViewerOverlay extends Overlay
public Dimension render(Graphics2D graphics)
{
if (plugin.isHideWhenInvOpen()
&& client.getVar(VarClientInt.PLAYER_INVENTORY_OPENED) == 3)
&& client.getVar(VarClientInt.PLAYER_INTERFACE_CONTAINER_OPENED) == 3)
{
return null;
}

View File

@@ -714,7 +714,7 @@ public class LootTrackerPlugin extends Plugin
break;
}
int killCount = Integer.valueOf(m.group(1));
int killCount = Integer.parseInt(m.group(1));
killCountMap.put(eventType.toUpperCase(), killCount);
return;
}
@@ -755,11 +755,12 @@ public class LootTrackerPlugin extends Plugin
if (boss.find())
{
String bossName = boss.group(1);
int killCount = Integer.valueOf(boss.group(2));
int killCount = Integer.parseInt(boss.group(2));
killCountMap.put(bossName.toUpperCase(), killCount);
}
}
@SuppressWarnings("unchecked")
public void onItemContainerChanged(ItemContainerChanged event)
{
if (pvpDeath && RESPAWN_REGIONS.contains(client.getLocalPlayer().getWorldLocation().getRegionID()))
@@ -849,7 +850,7 @@ public class LootTrackerPlugin extends Plugin
}
}
public void deleteLocalRecords()
void deleteLocalRecords()
{
try
{
@@ -960,7 +961,7 @@ public class LootTrackerPlugin extends Plugin
* @param name - The String name of the record to toggle the hidden status of
* @param ignore - true to ignore, false to remove
*/
public void toggleNPC(String name, boolean ignore)
void toggleNPC(String name, boolean ignore)
{
final Set<String> ignoredNPCSet = new HashSet<>(ignoredNPCs);
if (ignore)
@@ -981,7 +982,7 @@ public class LootTrackerPlugin extends Plugin
* @param name - The String of the name to check
* @return - true if it is being ignored, false otherwise
*/
public boolean isIgnoredNPC(String name)
boolean isIgnoredNPC(String name)
{
return ignoredNPCs.contains(name);
}

View File

@@ -291,6 +291,78 @@ public class AlchemyRoom extends MTARoom
&& player.getWorldLocation().getPlane() == 2;
}
@Override
public void under(Graphics2D graphics)
{
if (!getConfig().alchemy() || best == null || !inside())
{
return;
}
boolean found = false;
for (Cupboard cupboard : cupboards)
{
if (cupboard == null)
{
continue;
}
GameObject object = cupboard.gameObject;
AlchemyItem alchemyItem = cupboard.alchemyItem;
if (alchemyItem == AlchemyItem.EMPTY)
{
continue;
}
if (alchemyItem.equals(best))
{
client.setHintArrow(object.getWorldLocation());
found = true;
}
BufferedImage image = itemManager.getImage(alchemyItem.getId());
Point canvasLoc = Perspective.getCanvasImageLocation(client, object.getLocalLocation(), image, IMAGE_Z_OFFSET);
if (canvasLoc != null)
{
graphics.drawImage(image, canvasLoc.getX(), canvasLoc.getY(), null);
}
}
if (!found && suggestion != null)
{
client.setHintArrow(suggestion.gameObject.getWorldLocation());
}
}
@Override
public void over(Graphics2D graphics)
{
if (!inside() || !config.alchemy() || best == null)
{
return;
}
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
if (inventory.isHidden())
{
return;
}
for (WidgetItem item : inventory.getWidgetItems())
{
if (item.getId() != best.getId())
{
continue;
}
drawItem(graphics, item);
}
}
private AlchemyItem getBest()
{
for (int i = 0; i < INFO_LENGTH; i++)
@@ -357,53 +429,6 @@ public class AlchemyRoom extends MTARoom
}
}
@Override
public void under(Graphics2D graphics)
{
if (!getConfig().alchemy() || best == null || !inside())
{
return;
}
boolean found = false;
for (Cupboard cupboard : cupboards)
{
if (cupboard == null)
{
continue;
}
GameObject object = cupboard.gameObject;
AlchemyItem alchemyItem = cupboard.alchemyItem;
if (alchemyItem == AlchemyItem.EMPTY)
{
continue;
}
if (alchemyItem.equals(best))
{
client.setHintArrow(object.getWorldLocation());
found = true;
}
BufferedImage image = itemManager.getImage(alchemyItem.getId());
Point canvasLoc = Perspective.getCanvasImageLocation(client, object.getLocalLocation(), image, IMAGE_Z_OFFSET);
if (canvasLoc != null)
{
graphics.drawImage(image, canvasLoc.getX(), canvasLoc.getY(), null);
}
}
if (!found && suggestion != null)
{
client.setHintArrow(suggestion.gameObject.getWorldLocation());
}
}
private Cupboard getSuggestion()
{
// check if a cupboard has the best item in it
@@ -443,32 +468,6 @@ public class AlchemyRoom extends MTARoom
return nearest;
}
@Override
public void over(Graphics2D graphics)
{
if (!inside() || !config.alchemy() || best == null)
{
return;
}
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
if (inventory.isHidden())
{
return;
}
for (WidgetItem item : inventory.getWidgetItems())
{
if (item.getId() != best.getId())
{
continue;
}
drawItem(graphics, item);
}
}
private void drawItem(Graphics2D graphics, WidgetItem item)
{
Rectangle bounds = item.getCanvasBounds();

View File

@@ -30,10 +30,10 @@ import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.Item;
import net.runelite.api.ItemID;
import net.runelite.api.Player;
import net.runelite.api.Tile;
import net.runelite.api.TileItem;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;
@@ -121,7 +121,7 @@ public class EnchantmentRoom extends MTARoom
private void onItemSpawned(ItemSpawned itemSpawned)
{
final Item item = itemSpawned.getItem();
final TileItem item = itemSpawned.getItem();
final Tile tile = itemSpawned.getTile();
if (item.getId() == ItemID.DRAGONSTONE_6903)
@@ -134,7 +134,7 @@ public class EnchantmentRoom extends MTARoom
private void onItemDespawned(ItemDespawned itemDespawned)
{
final Item item = itemDespawned.getItem();
final TileItem item = itemDespawned.getItem();
final Tile tile = itemDespawned.getTile();
if (item.getId() == ItemID.DRAGONSTONE_6903)

View File

@@ -47,10 +47,8 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
public class GraveyardRoom extends MTARoom
{
private static final int MTA_GRAVEYARD_REGION = 13462;
static final int MIN_SCORE = 16;
private static final int MTA_GRAVEYARD_REGION = 13462;
private final Client client;
private final MTAPlugin plugin;
private final ItemManager itemManager;

View File

@@ -93,6 +93,11 @@ public class TelekineticRoom extends MTARoom
addSubscriptions();
}
private static int manhattan(WorldPoint point1, WorldPoint point2)
{
return Math.abs(point1.getX() - point2.getX()) + Math.abs(point2.getY() - point1.getY());
}
private void addSubscriptions()
{
eventBus.subscribe(GameTick.class, this, this::onGameTick);
@@ -142,8 +147,8 @@ public class TelekineticRoom extends MTARoom
private void onGameTick(GameTick event)
{
if (!config.telekinetic()
|| !inside()
|| client.getGameState() != GameState.LOGGED_IN)
|| !inside()
|| client.getGameState() != GameState.LOGGED_IN)
{
maze = null;
moves.clear();
@@ -285,11 +290,6 @@ public class TelekineticRoom extends MTARoom
return nearest(areaNext, nearestAfter);
}
private static int manhattan(WorldPoint point1, WorldPoint point2)
{
return Math.abs(point1.getX() - point2.getX()) + Math.abs(point2.getY() - point1.getY());
}
private WorldPoint nearest(WorldArea area, WorldPoint worldPoint)
{
int dist = Integer.MAX_VALUE;
@@ -372,7 +372,7 @@ public class TelekineticRoom extends MTARoom
WorldPoint nghbWorld = WorldPoint.fromLocal(client, neighbour);
if (!nghbWorld.equals(next)
&& !closed.contains(nghbWorld))
&& !closed.contains(nghbWorld))
{
int score = scores.get(next) + 1;
@@ -424,10 +424,10 @@ public class TelekineticRoom extends MTARoom
private LocalPoint[] neighbours(LocalPoint point)
{
return new LocalPoint[]
{
neighbour(point, Direction.NORTH), neighbour(point, Direction.SOUTH),
neighbour(point, Direction.EAST), neighbour(point, Direction.WEST)
};
{
neighbour(point, Direction.NORTH), neighbour(point, Direction.SOUTH),
neighbour(point, Direction.EAST), neighbour(point, Direction.WEST)
};
}
private LocalPoint neighbour(LocalPoint point, Direction direction)

View File

@@ -35,11 +35,17 @@ import net.runelite.api.Constants;
public class MapLocations
{
@SuppressWarnings("unchecked")
private static final List<Shape>[] MULTICOMBAT = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] NOT_MULTICOMBAT = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] ROUGH_WILDERNESS = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] WILDERNESS_LEVEL_LINES = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z];
@SuppressWarnings("unchecked")
private static final List<Shape>[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z];
private static Area getArea(List<Shape> shapes)

View File

@@ -87,7 +87,7 @@ public class NpcIndicatorsPlugin extends Plugin
// Option added to NPC menu
private static final String TAG = "Tag";
private static final String UNTAG = "Untag";
private static final String UNTAG = "Un-tag";
private static final Set<MenuAction> NPC_MENU_ACTIONS = ImmutableSet.of(MenuAction.NPC_FIRST_OPTION, MenuAction.NPC_SECOND_OPTION,
MenuAction.NPC_THIRD_OPTION, MenuAction.NPC_FOURTH_OPTION, MenuAction.NPC_FIFTH_OPTION);
@@ -316,7 +316,7 @@ public class NpcIndicatorsPlugin extends Plugin
// Add tag option
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry();
tagEntry.setOption(npcTags.contains(event.getIdentifier()) ? UNTAG : TAG);
tagEntry.setOption(highlightedNpcs.stream().anyMatch(npc -> npc.getIndex() == event.getIdentifier()) ? UNTAG : TAG);
tagEntry.setTarget(event.getTarget());
tagEntry.setParam0(event.getActionParam0());
tagEntry.setParam1(event.getActionParam1());
@@ -328,9 +328,8 @@ public class NpcIndicatorsPlugin extends Plugin
private void onMenuOptionClicked(MenuOptionClicked click)
{
if (click.getMenuAction() != MenuAction.RUNELITE
|| (!click.getOption().equals(TAG)
&& !click.getOption().equals(UNTAG)))
if (click.getMenuAction() != MenuAction.RUNELITE ||
!(click.getOption().equals(TAG) || click.getOption().equals(UNTAG)))
{
return;
}

View File

@@ -247,47 +247,13 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
return;
}
final Tile tile = client.getScene().getTiles()[client.getPlane()][event.getActionParam0()][event.getActionParam1()];
MenuEntry[] menuEntries = client.getMenuEntries();
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry();
String option = MARK;
Scene scene = client.getScene();
Tile[][][] tiles = scene.getTiles();
final int x = event.getActionParam0();
final int y = event.getActionParam1();
final int z = client.getPlane();
final Tile tile = tiles[z][x][y];
final TileObject object = findTileObject(tile, event.getIdentifier());
if (object != null)
{
final ObjectDefinition objectDefinition = client.getObjectDefinition(object.getId());
final String name = objectDefinition.getName();
if (!Strings.isNullOrEmpty(name))
{
final WorldPoint loc = WorldPoint.fromLocalInstance(client, tile.getLocalLocation());
final int regionId = loc.getRegionID();
final ObjectPoint point = new ObjectPoint(
name,
regionId,
loc.getX() & (REGION_SIZE - 1),
loc.getY() & (REGION_SIZE - 1),
client.getPlane());
final Set<ObjectPoint> objectPoints = points.get(regionId);
if (objectPoints != null && objectPoints.contains(point))
{
option = UNMARK;
}
}
}
menuEntry.setOption(option);
menuEntry.setOption(objects.contains(findTileObject(tile, event.getIdentifier())) ? UNMARK : MARK);
menuEntry.setTarget(event.getTarget());
menuEntry.setParam0(event.getActionParam0());
menuEntry.setParam1(event.getActionParam1());
@@ -299,8 +265,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
private void onMenuOptionClicked(MenuOptionClicked event)
{
if (event.getMenuAction() != MenuAction.RUNELITE
|| (!event.getOption().equals(MARK)
&& !event.getOption().equals(UNMARK)))
|| !(event.getOption().equals(MARK) || event.getOption().equals(UNMARK)))
{
return;
}

View File

@@ -824,10 +824,11 @@ public class ScreenshotPlugin extends Plugin
Request request = null;
if (IMGUR_IMAGE_UPLOAD_URL != null)
{
RequestBody body = RequestBody.Companion.create(json, JSON);
request = new Request.Builder()
.url(IMGUR_IMAGE_UPLOAD_URL)
.addHeader("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
.post(RequestBody.create(JSON, json))
.post(body)
.build();
}

View File

@@ -219,6 +219,7 @@ public class ModifyPanel extends JPanel
labelContainer.repaint();
}
@SuppressWarnings("unchecked")
private void updateAdjustContainer()
{
adjustContainer.removeAll();

View File

@@ -76,13 +76,13 @@ import net.runelite.client.eventbus.EventBus;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.worldhopper.ping.Ping;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ExecutorServiceExceptionLogger;
import net.runelite.client.util.HotkeyListener;
import net.runelite.client.util.Text;
import net.runelite.client.util.WorldUtil;
import net.runelite.client.util.ping.Ping;
import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient;
import net.runelite.http.api.worlds.WorldResult;

View File

@@ -1,40 +0,0 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (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.worldhopper.ping;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
interface IPHlpAPI extends Library
{
IPHlpAPI INSTANCE = Native.loadLibrary("IPHlpAPI", IPHlpAPI.class);
Pointer IcmpCreateFile();
boolean IcmpCloseHandle(Pointer handle);
int IcmpSendEcho(Pointer IcmpHandle, int DestinationAddress, Pointer RequestData, short RequestSize, Pointer RequestOptions, IcmpEchoReply ReplyBuffer, int ReplySize, int Timeout);
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (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.worldhopper.ping;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef;
import java.util.Arrays;
import java.util.List;
public class IcmpEchoReply extends Structure
{
private static final int IP_OPTION_INFO_SIZE = 1 + 1 + 1 + 1 + (Native.POINTER_SIZE == 8 ? 12 : 4); // on 64bit vms add 4 byte padding
public static final int SIZE = 4 + 4 + 4 + 2 + 2 + Native.POINTER_SIZE + IP_OPTION_INFO_SIZE;
public WinDef.ULONG address;
public WinDef.ULONG status;
public WinDef.ULONG roundTripTime;
public WinDef.USHORT dataSize;
public WinDef.USHORT reserved;
public WinDef.PVOID data;
public WinDef.UCHAR ttl;
public WinDef.UCHAR tos;
public WinDef.UCHAR flags;
public WinDef.UCHAR optionsSize;
public WinDef.PVOID optionsData;
IcmpEchoReply(final Pointer p)
{
super(p);
}
@Override
protected List<String> getFieldOrder()
{
return Arrays.asList("address", "status", "roundTripTime", "dataSize", "reserved", "data", "ttl", "tos", "flags", "optionsSize", "optionsData");
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (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.worldhopper.ping;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.util.OSType;
import net.runelite.http.api.worlds.World;
@Slf4j
public class Ping
{
private static final String RUNELITE_PING = "RuneLitePing";
private static final int TIMEOUT = 2000;
private static final int PORT = 43594;
public static int ping(World world)
{
try
{
if (OSType.getOSType() == OSType.Windows)
{
return windowsPing(world);
}
return tcpPing(world);
}
catch (IOException ex)
{
log.warn("error pinging", ex);
return -1;
}
}
private static int windowsPing(World world) throws UnknownHostException
{
IPHlpAPI ipHlpAPI = IPHlpAPI.INSTANCE;
Pointer ptr = ipHlpAPI.IcmpCreateFile();
InetAddress inetAddress = InetAddress.getByName(world.getAddress());
byte[] address = inetAddress.getAddress();
String dataStr = RUNELITE_PING;
int dataLength = dataStr.length() + 1;
Pointer data = new Memory(dataLength);
data.setString(0L, dataStr);
IcmpEchoReply icmpEchoReply = new IcmpEchoReply(new Memory(IcmpEchoReply.SIZE + dataLength));
assert icmpEchoReply.size() == IcmpEchoReply.SIZE;
int packed = (address[0] & 0xff) | ((address[1] & 0xff) << 8) | ((address[2] & 0xff) << 16) | ((address[3] & 0xff) << 24);
int ret = ipHlpAPI.IcmpSendEcho(ptr, packed, data, (short) (dataLength), Pointer.NULL, icmpEchoReply, IcmpEchoReply.SIZE + dataLength, TIMEOUT);
if (ret != 1)
{
ipHlpAPI.IcmpCloseHandle(ptr);
return -1;
}
int rtt = Math.toIntExact(icmpEchoReply.roundTripTime.longValue());
ipHlpAPI.IcmpCloseHandle(ptr);
return rtt;
}
private static int tcpPing(World world) throws IOException
{
try (Socket socket = new Socket())
{
socket.setSoTimeout(TIMEOUT);
InetAddress inetAddress = InetAddress.getByName(world.getAddress());
long start = System.nanoTime();
socket.connect(new InetSocketAddress(inetAddress, PORT));
long end = System.nanoTime();
return (int) ((end - start) / 1000000L);
}
}
}

View File

@@ -67,7 +67,7 @@ public class ClientLoader
{
try
{
URL localInjected = new File("./injected-client/target/injected-client-" + RuneLiteAPI.getVersion() + ".jar").toURI().toURL();
URL localInjected = new File("./injected-client/build/libs/injected-client-" + RuneLiteAPI.getVersion() + ".jar").toURI().toURL();
log.info("Using local injected-client");
URLClassLoader classLoader = new URLClassLoader(new URL[]{localInjected});
Class<?> clientClass = classLoader.loadClass("client");

View File

@@ -39,6 +39,7 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.swing.SwingUtilities;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.MenuAction;
@@ -61,6 +62,7 @@ import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.MiscUtils;
@Singleton
@Slf4j
public class OverlayRenderer extends MouseAdapter implements KeyListener
{
private static final int BORDER = 5;
@@ -496,8 +498,23 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
}
subGraphics.translate(point.x, point.y);
final Dimension dimension = MoreObjects.firstNonNull(overlay.render(subGraphics), new Dimension());
subGraphics.dispose();
final Dimension overlayDimension;
try
{
overlayDimension = overlay.render(subGraphics);
}
catch (Exception ex)
{
log.warn("Error during overlay rendering", ex);
return;
}
finally
{
subGraphics.dispose();
}
final Dimension dimension = MoreObjects.firstNonNull(overlayDimension, new Dimension());
overlay.setBounds(new Rectangle(point, dimension));
}

View File

@@ -24,6 +24,7 @@
*/
package net.runelite.client.ui.overlay.components;
import com.google.common.annotations.VisibleForTesting;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
@@ -96,6 +97,7 @@ public class TooltipComponent implements RenderableEntity
char[] chars = line.toCharArray();
int begin = 0;
boolean inTag = false;
for (int j = 0; j < chars.length; j++)
{
if (chars[j] == '<')
@@ -110,8 +112,9 @@ public class TooltipComponent implements RenderableEntity
lineX += metrics.stringWidth(text);
begin = j;
inTag = true;
}
else if (chars[j] == '>')
else if (chars[j] == '>' && inTag)
{
String subLine = line.substring(begin + 1, j);
@@ -148,6 +151,7 @@ public class TooltipComponent implements RenderableEntity
}
begin = j + 1;
inTag = false;
}
}
@@ -162,12 +166,14 @@ public class TooltipComponent implements RenderableEntity
return new Dimension(tooltipWidth + OFFSET * 2, tooltipHeight + OFFSET * 2);
}
private static int calculateTextWidth(FontMetrics metrics, String line)
@VisibleForTesting
static int calculateTextWidth(FontMetrics metrics, String line)
{
char[] chars = line.toCharArray();
int textWidth = 0;
int begin = 0;
boolean inTag = false;
for (int j = 0; j < chars.length; j++)
{
if (chars[j] == '<')
@@ -175,8 +181,9 @@ public class TooltipComponent implements RenderableEntity
textWidth += metrics.stringWidth(line.substring(begin, j));
begin = j;
inTag = true;
}
else if (chars[j] == '>')
else if (chars[j] == '>' && inTag)
{
String subLine = line.substring(begin + 1, j);
@@ -190,6 +197,7 @@ public class TooltipComponent implements RenderableEntity
}
begin = j + 1;
inTag = false;
}
}

View File

@@ -66,6 +66,19 @@ public class TooltipOverlay extends Overlay
return null;
}
try
{
return renderTooltips(graphics, tooltips);
}
finally
{
// Tooltips must always be cleared each frame
tooltipManager.clear();
}
}
private Dimension renderTooltips(Graphics2D graphics, List<Tooltip> tooltips)
{
final Rectangle clientCanvasBounds = new Rectangle(client.getRealDimensions());
final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
final Point mousePosition = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + OFFSET);
@@ -113,7 +126,6 @@ public class TooltipOverlay extends Overlay
newBounds.width = Math.max(newBounds.width, dimension.width);
}
tooltipManager.clear();
return newBounds.getSize();
}
}

View File

@@ -51,6 +51,7 @@ public class DeferredEventBus extends EventBus
pendingEvents.add(new ImmutablePair<>(eventClass, event));
}
@SuppressWarnings("unchecked")
public void replay()
{
int size = pendingEvents.size();

View File

@@ -33,8 +33,8 @@ import javax.inject.Singleton;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.GameState;
import net.runelite.api.TileItem;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
import net.runelite.api.NPC;
import net.runelite.api.Node;
@@ -180,9 +180,9 @@ public class GameEventManager
{
Node current = itemLayer.getBottom();
while (current instanceof Item)
while (current instanceof TileItem)
{
final Item item = (Item) current;
final TileItem item = (TileItem) current;
current = current.getNext();

View File

@@ -52,6 +52,11 @@ import net.runelite.api.Sprite;
@Slf4j
public class ImageUtil
{
static
{
ImageIO.setUseCache(false);
}
/**
* Creates a {@link BufferedImage} from an {@link Image}.
*

View File

@@ -30,7 +30,7 @@ import com.sun.jna.Pointer;
interface IPHlpAPI extends Library
{
IPHlpAPI INSTANCE = Native.loadLibrary("IPHlpAPI", IPHlpAPI.class);
IPHlpAPI INSTANCE = Native.load("IPHlpAPI", IPHlpAPI.class);
Pointer IcmpCreateFile();