plugins: Fix menu concurrency issues (#1444)

* Cleanup comparables a bit

* Make shift walker add entries on client tick

* Make climb up + down add entries on clienttick

* remove try catch
This commit is contained in:
Lucwousin
2019-08-24 19:54:35 +02:00
committed by Ganom
parent 19fcf15420
commit 275d3c7144
11 changed files with 314 additions and 74 deletions

View File

@@ -29,6 +29,7 @@ import joptsimple.internal.Strings;
import lombok.EqualsAndHashCode;
import net.runelite.api.MenuEntry;
import net.runelite.client.util.Text;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
public class BaseComparableEntry extends AbstractComparableEntry
@@ -51,9 +52,9 @@ public class BaseComparableEntry extends AbstractComparableEntry
public boolean matches(@Nonnull MenuEntry entry)
{
String opt = entry.getStandardizedOption();
String opt = entry.getOption();
if (strictOption && !opt.equals(option) || !strictOption && !opt.contains(option))
if (strictOption && !StringUtils.equalsIgnoreCase(opt, option) || !strictOption && !StringUtils.containsIgnoreCase(opt, option))
{
return false;
}

View File

@@ -7,6 +7,7 @@ import net.runelite.api.Client;
import net.runelite.api.ItemDefinition;
import net.runelite.api.MenuEntry;
import net.runelite.client.util.Text;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
@Getter
@@ -28,7 +29,7 @@ abstract class ItemComparableEntry extends AbstractComparableEntry
assert client.isClientThread() : "You can only create these on the clientthread";
this.target = Text.standardize(itemName);
this.option = Text.standardize(option);
this.option = option;
short[] tmp = this.itemIds = new short[16];
@@ -38,7 +39,7 @@ abstract class ItemComparableEntry extends AbstractComparableEntry
for (short i = 0; i < itemCount; i++)
{
ItemDefinition def = client.getItemDefinition(i);
if (def.getNote() != -1 || !def.getName().toLowerCase().contains(target))
if (def.getNote() != -1 || !StringUtils.containsIgnoreCase(def.getName(), target))
{
continue;
}
@@ -46,7 +47,7 @@ abstract class ItemComparableEntry extends AbstractComparableEntry
boolean notValid = true;
for (String opt : def.getInventoryActions())
{
if (opt != null && Text.standardize(opt).contains(option))
if (opt != null && StringUtils.containsIgnoreCase(opt, option))
{
notValid = false;
break;
@@ -75,7 +76,7 @@ abstract class ItemComparableEntry extends AbstractComparableEntry
public boolean matches(MenuEntry entry)
{
if (!this.option.contains(Text.standardize(entry.getOption())))
if (!StringUtils.containsIgnoreCase(entry.getOption(), this.option))
{
return false;
}

View File

@@ -34,7 +34,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -808,49 +807,43 @@ public class MenuManager
private void indexPriorityEntries(MenuEntry[] entries, int menuOptionCount)
{
// create a array of priority entries so we can sort those
try
{
final SortMapping[] prios = new SortMapping[entries.length - menuOptionCount];
final SortMapping[] prios = new SortMapping[entries.length - menuOptionCount];
int prioAmt = 0;
for (int i = 0; i < menuOptionCount; i++)
int prioAmt = 0;
for (int i = 0; i < menuOptionCount; i++)
{
final MenuEntry entry = entries[i];
for (AbstractComparableEntry prio : priorityEntries)
{
final MenuEntry entry = entries[i];
for (AbstractComparableEntry prio : priorityEntries)
if (!prio.matches(entry))
{
if (!prio.matches(entry))
{
continue;
}
final SortMapping map = new SortMapping(prio.getPriority(), entry);
prios[prioAmt++] = map;
entries[i] = null;
break;
continue;
}
final SortMapping map = new SortMapping(prio.getPriority(), entry);
prios[prioAmt++] = map;
entries[i] = null;
break;
}
if (prioAmt == 0)
{
return;
}
// Sort em!
Arrays.sort(prios, 0, prioAmt);
int i;
// Just place them after the standard entries. clientmixin ignores null entries
for (i = 0; i < prioAmt; i++)
{
entries[menuOptionCount + i] = prios[i].entry;
}
firstEntry = entries[menuOptionCount + i - 1];
}
catch (ConcurrentModificationException ignored)
if (prioAmt == 0)
{
//true band aid :)
return;
}
// Sort em!
Arrays.sort(prios, 0, prioAmt);
int i;
// Just place them after the standard entries. clientmixin ignores null entries
for (i = 0; i < prioAmt; i++)
{
entries[menuOptionCount + i] = prios[i].entry;
}
firstEntry = entries[menuOptionCount + i - 1];
}
private void indexSwapEntries(MenuEntry[] entries, int menuOptionCount)

View File

@@ -2,17 +2,18 @@ package net.runelite.client.plugins.menuentryswapper;
import lombok.EqualsAndHashCode;
import net.runelite.api.MenuEntry;
import net.runelite.api.util.Text;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.menus.AbstractComparableEntry;
import net.runelite.client.util.Text;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
public class BankComparableEntry extends AbstractComparableEntry
{
public BankComparableEntry(String option, String itemName, boolean strictTarget)
{
this.setOption(Text.standardize(option));
this.setOption(option);
this.setTarget(Text.standardize(itemName));
this.setStrictTarget(strictTarget);
}
@@ -26,11 +27,11 @@ public class BankComparableEntry extends AbstractComparableEntry
return false;
}
if (isStrictTarget() && Text.standardize(entry.getTarget()).equals(this.getTarget()))
if (isStrictTarget() && !Text.standardize(entry.getTarget()).equals(this.getTarget()))
{
return false;
}
return Text.standardize(entry.getOption()).contains(this.getOption()) && Text.standardize(entry.getTarget()).contains(this.getTarget());
return StringUtils.containsIgnoreCase(entry.getOption(), this.getOption()) && Text.standardize(entry.getTarget()).contains(this.getTarget());
}
}

View File

@@ -13,7 +13,7 @@ public class EquipmentComparableEntry extends AbstractComparableEntry
{
public EquipmentComparableEntry(String option, String itemName)
{
this.setOption(Text.standardize(option));
this.setOption(option);
this.setTarget(Text.standardize(itemName));
}

View File

@@ -6,13 +6,14 @@ import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.menus.AbstractComparableEntry;
import net.runelite.client.util.Text;
import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
public class InventoryComparableEntry extends AbstractComparableEntry
{
public InventoryComparableEntry(String option, String itemName, boolean strictTarget)
{
this.setOption(Text.standardize(option));
this.setOption(option);
this.setTarget(Text.standardize(itemName));
this.setStrictTarget(strictTarget);
}
@@ -31,6 +32,6 @@ public class InventoryComparableEntry extends AbstractComparableEntry
return false;
}
return Text.standardize(entry.getOption()).contains(this.getOption()) && Text.standardize(entry.getTarget()).contains(this.getTarget());
return StringUtils.containsIgnoreCase(entry.getOption(), this.getOption()) && Text.standardize(entry.getTarget()).contains(this.getTarget());
}
}

View File

@@ -58,6 +58,7 @@ import net.runelite.api.Varbits;
import static net.runelite.api.Varbits.BUILDING_MODE;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.MenuEntryAdded;
@@ -115,6 +116,8 @@ import org.apache.commons.lang3.ArrayUtils;
public class MenuEntrySwapperPlugin extends Plugin
{
private static final String CONFIG_GROUP = "shiftclick";
private static final String SHIFT = "menuentryswapper shift";
private static final String CONTROL = "menuentryswapper control";
private static final int PURO_PURO_REGION_ID = 10307;
private static final Set<MenuOpcode> NPC_MENU_TYPES = ImmutableSet.of(
MenuOpcode.NPC_FIRST_OPTION, MenuOpcode.NPC_SECOND_OPTION, MenuOpcode.NPC_THIRD_OPTION,
@@ -1434,6 +1437,11 @@ public class MenuEntrySwapperPlugin extends Plugin
}
void startShift()
{
eventBus.subscribe(ClientTick.class, SHIFT, this::addShift);
}
private void addShift(ClientTick event)
{
loadCustomSwaps(this.configCustomShiftSwaps, customShiftSwaps);
@@ -1443,12 +1451,19 @@ public class MenuEntrySwapperPlugin extends Plugin
}
menuManager.addPriorityEntry("climb-up").setPriority(100);
eventBus.unregister(SHIFT);
}
void stopShift()
{
eventBus.subscribe(ClientTick.class, SHIFT, this::remShift);
}
private void remShift(ClientTick event)
{
menuManager.removePriorityEntry("climb-up");
loadCustomSwaps("", customShiftSwaps);
eventBus.unregister(SHIFT);
}
void startControl()
@@ -1458,12 +1473,24 @@ public class MenuEntrySwapperPlugin extends Plugin
return;
}
eventBus.subscribe(ClientTick.class, CONTROL, this::addControl);
}
private void addControl(ClientTick event)
{
menuManager.addPriorityEntry("climb-down").setPriority(100);
eventBus.unregister(CONTROL);
}
void stopControl()
{
eventBus.subscribe(ClientTick.class, CONTROL, this::remControl);
}
private void remControl(ClientTick event)
{
menuManager.removePriorityEntry("climb-down");
eventBus.unregister(CONTROL);
}
private void setCastOptions(boolean force)

View File

@@ -27,11 +27,15 @@ package net.runelite.client.plugins.shiftwalker;
import com.google.inject.Provides;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.MenuEntry;
import net.runelite.api.MenuOpcode;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.FocusChanged;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.input.KeyManager;
import net.runelite.client.menus.AbstractComparableEntry;
import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
@@ -51,8 +55,76 @@ import net.runelite.client.plugins.PluginType;
public class ShiftWalkerPlugin extends Plugin
{
private static final String WALK_HERE = "Walk here";
private static final String TAKE = "Take";
private static final AbstractComparableEntry WALK = new AbstractComparableEntry()
{
private final int hash = "WALK".hashCode() * 79 + getPriority();
@Override
public int hashCode()
{
return hash;
}
@Override
public boolean equals(Object entry)
{
return entry.getClass() == this.getClass() && entry.hashCode() == this.hashCode();
}
@Override
public int getPriority()
{
return 99;
}
@Override
public boolean matches(MenuEntry entry)
{
return
entry.getOpcode() == MenuOpcode.WALK.getId() ||
entry.getOpcode() == MenuOpcode.WALK.getId() + MenuOpcode.MENU_ACTION_DEPRIORITIZE_OFFSET;
}
};
private static final AbstractComparableEntry TAKE = new AbstractComparableEntry()
{
private final int hash = "TAKE".hashCode() * 79 + getPriority();
@Override
public int hashCode()
{
return hash;
}
@Override
public boolean equals(Object entry)
{
return entry.getClass() == this.getClass() && entry.hashCode() == this.hashCode();
}
@Override
public int getPriority()
{
return 100;
}
@Override
public boolean matches(MenuEntry entry)
{
int opcode = entry.getOpcode();
if (opcode > MenuOpcode.MENU_ACTION_DEPRIORITIZE_OFFSET)
{
opcode -= MenuOpcode.MENU_ACTION_DEPRIORITIZE_OFFSET;
}
return
opcode >= MenuOpcode.GROUND_ITEM_FIRST_OPTION.getId() &&
opcode <= MenuOpcode.GROUND_ITEM_FIFTH_OPTION.getId();
}
};
private static final String EVENTBUS_THING = "shiftwalker_shift";
@Inject
private ShiftWalkerConfig config;
@@ -111,22 +183,34 @@ public class ShiftWalkerPlugin extends Plugin
}
void startPrioritizing()
{
eventBus.subscribe(ClientTick.class, EVENTBUS_THING, this::addEntries);
}
private void addEntries(ClientTick event)
{
if (this.shiftLoot)
{
menuManager.addPriorityEntry(TAKE).setPriority(100);
menuManager.addPriorityEntry(TAKE);
}
if (this.shiftWalk)
{
menuManager.addPriorityEntry(WALK_HERE).setPriority(90);
}
menuManager.addPriorityEntry(WALK);
}
eventBus.unregister(EVENTBUS_THING);
}
void stopPrioritizing()
{
eventBus.subscribe(ClientTick.class, EVENTBUS_THING, this::remEntries);
}
private void remEntries(ClientTick c)
{
menuManager.removePriorityEntry(TAKE);
menuManager.removePriorityEntry(WALK_HERE);
menuManager.removePriorityEntry(WALK);
eventBus.unregister(EVENTBUS_THING);
}
private void onConfigChanged(ConfigChanged event)
@@ -136,7 +220,13 @@ public class ShiftWalkerPlugin extends Plugin
return;
}
this.shiftWalk = config.shiftWalk();
this.shiftLoot = config.shiftLoot();
if ("shiftWalk".equals(event.getKey()))
{
this.shiftWalk = "true".equals(event.getNewValue());
}
else
{
this.shiftLoot = "true".equals(event.getNewValue());
}
}
}