Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-09-03 20:42:14 +02:00
20 changed files with 304 additions and 20 deletions

View File

@@ -40,4 +40,5 @@ public class LootRecord
private Object metadata; private Object metadata;
private Collection<GameItem> drops; private Collection<GameItem> drops;
private Instant time; private Instant time;
private Integer world;
} }

View File

@@ -44,12 +44,16 @@ import lombok.RequiredArgsConstructor;
import lombok.Value; import lombok.Value;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.util.ReflectUtil; import net.runelite.client.util.ReflectUtil;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@ThreadSafe @ThreadSafe
public class EventBus public class EventBus
{ {
private static final Marker DEDUPLICATE = MarkerFactory.getMarker("DEDUPLICATE");
@Value @Value
public static class Subscriber public static class Subscriber
{ {
@@ -82,7 +86,7 @@ public class EventBus
*/ */
public EventBus() public EventBus()
{ {
this((e) -> log.warn("Uncaught exception in event subscriber", e)); this((e) -> log.warn(DEDUPLICATE, "Uncaught exception in event subscriber", e));
} }
/** /**

View File

@@ -196,6 +196,7 @@ public enum ItemMapping
ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF, HOLY_SANGUINESTI_STAFF_UNCHARGED, HOLY_SANGUINESTI_STAFF), ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF, HOLY_SANGUINESTI_STAFF_UNCHARGED, HOLY_SANGUINESTI_STAFF),
ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR, HOLY_SCYTHE_OF_VITUR_UNCHARGED, HOLY_SCYTHE_OF_VITUR, SANGUINE_SCYTHE_OF_VITUR_UNCHARGED, SANGUINE_SCYTHE_OF_VITUR), ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR, HOLY_SCYTHE_OF_VITUR_UNCHARGED, HOLY_SCYTHE_OF_VITUR, SANGUINE_SCYTHE_OF_VITUR_UNCHARGED, SANGUINE_SCYTHE_OF_VITUR),
ITEM_TOME_OF_FIRE(TOME_OF_FIRE_EMPTY, TOME_OF_FIRE), ITEM_TOME_OF_FIRE(TOME_OF_FIRE_EMPTY, TOME_OF_FIRE),
ITEM_TOME_OF_WATER(TOME_OF_WATER_EMPTY, TOME_OF_WATER),
ITEM_CRAWS_BOW(CRAWS_BOW_U, CRAWS_BOW), ITEM_CRAWS_BOW(CRAWS_BOW_U, CRAWS_BOW),
ITEM_VIGGORAS_CHAINMACE(VIGGORAS_CHAINMACE_U, VIGGORAS_CHAINMACE), ITEM_VIGGORAS_CHAINMACE(VIGGORAS_CHAINMACE_U, VIGGORAS_CHAINMACE),
ITEM_THAMMARONS_SCEPTRE(THAMMARONS_SCEPTRE_U, THAMMARONS_SCEPTRE), ITEM_THAMMARONS_SCEPTRE(THAMMARONS_SCEPTRE_U, THAMMARONS_SCEPTRE),
@@ -255,6 +256,7 @@ public enum ItemMapping
ITEM_VOLATILE_ORB(VOLATILE_ORB, VOLATILE_NIGHTMARE_STAFF), ITEM_VOLATILE_ORB(VOLATILE_ORB, VOLATILE_NIGHTMARE_STAFF),
ITEM_NIGHTMARE_STAFF(NIGHTMARE_STAFF, ELDRITCH_NIGHTMARE_STAFF, HARMONISED_NIGHTMARE_STAFF, VOLATILE_NIGHTMARE_STAFF), ITEM_NIGHTMARE_STAFF(NIGHTMARE_STAFF, ELDRITCH_NIGHTMARE_STAFF, HARMONISED_NIGHTMARE_STAFF, VOLATILE_NIGHTMARE_STAFF),
ITEM_GHARZI_RAPIER(GHRAZI_RAPIER, HOLY_GHRAZI_RAPIER), ITEM_GHARZI_RAPIER(GHRAZI_RAPIER, HOLY_GHRAZI_RAPIER),
ITEM_MASTER_SCROLL_BOOK(MASTER_SCROLL_BOOK_EMPTY, MASTER_SCROLL_BOOK),
// Trouver Parchment // Trouver Parchment
ITEM_TROUVER_PARCHMENT( ITEM_TROUVER_PARCHMENT(

View File

@@ -50,6 +50,7 @@ import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import net.runelite.api.ItemID;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager; import net.runelite.client.ui.FontManager;
@@ -375,8 +376,32 @@ class LootTrackerBox extends JPanel
final long gePrice = item.getTotalGePrice(); final long gePrice = item.getTotalGePrice();
final long haPrice = item.getTotalHaPrice(); final long haPrice = item.getTotalHaPrice();
final String ignoredLabel = item.isIgnored() ? " - Ignored" : ""; final String ignoredLabel = item.isIgnored() ? " - Ignored" : "";
return "<html>" + name + " x " + quantity + ignoredLabel final StringBuilder sb = new StringBuilder("<html>");
+ "<br>GE: " + QuantityFormatter.quantityToStackSize(gePrice) sb.append(name).append(" x ").append(QuantityFormatter.formatNumber(quantity)).append(ignoredLabel);
+ "<br>HA: " + QuantityFormatter.quantityToStackSize(haPrice) + "</html>"; if (item.getId() == ItemID.COINS_995)
{
sb.append("</html>");
return sb.toString();
}
sb.append("<br>GE: ").append(QuantityFormatter.quantityToStackSize(gePrice));
if (quantity > 1)
{
sb.append(" (").append(QuantityFormatter.quantityToStackSize(item.getGePrice())).append(" ea)");
}
if (item.getId() == ItemID.PLATINUM_TOKEN)
{
sb.append("</html>");
return sb.toString();
}
sb.append("<br>HA: ").append(QuantityFormatter.quantityToStackSize(haPrice));
if (quantity > 1)
{
sb.append(" (").append(QuantityFormatter.quantityToStackSize(item.getHaPrice())).append(" ea)");
}
sb.append("</html>");
return sb.toString();
} }
} }

View File

@@ -74,6 +74,7 @@ import net.runelite.api.ObjectID;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Skill; import net.runelite.api.Skill;
import net.runelite.api.SpriteID; import net.runelite.api.SpriteID;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
@@ -479,7 +480,7 @@ public class LootTrackerPlugin extends Plugin
if (config.saveLoot()) if (config.saveLoot())
{ {
LootRecord lootRecord = new LootRecord(name, type, metadata, toGameItems(items), Instant.now()); LootRecord lootRecord = new LootRecord(name, type, metadata, toGameItems(items), Instant.now(), getLootWorldId());
synchronized (queuedLoots) synchronized (queuedLoots)
{ {
queuedLoots.add(lootRecord); queuedLoots.add(lootRecord);
@@ -489,6 +490,12 @@ public class LootTrackerPlugin extends Plugin
eventBus.post(new LootReceived(name, combatLevel, type, items)); eventBus.post(new LootReceived(name, combatLevel, type, items));
} }
private Integer getLootWorldId()
{
// For the wiki to determine drop rates based on dmm brackets
return client.getWorldType().contains(WorldType.SEASONAL) ? client.getWorld() : null;
}
@Subscribe @Subscribe
public void onNpcLootReceived(final NpcLootReceived npcLootReceived) public void onNpcLootReceived(final NpcLootReceived npcLootReceived)
{ {

View File

@@ -50,6 +50,10 @@ import static net.runelite.api.ObjectID.ORE_VEIN_26661;
import static net.runelite.api.ObjectID.ORE_VEIN_26662; import static net.runelite.api.ObjectID.ORE_VEIN_26662;
import static net.runelite.api.ObjectID.ORE_VEIN_26663; import static net.runelite.api.ObjectID.ORE_VEIN_26663;
import static net.runelite.api.ObjectID.ORE_VEIN_26664; import static net.runelite.api.ObjectID.ORE_VEIN_26664;
import static net.runelite.api.ObjectID.ROCKS_41547;
import static net.runelite.api.ObjectID.ROCKS_41548;
import static net.runelite.api.ObjectID.ROCKS_41549;
import static net.runelite.api.ObjectID.ROCKS_41550;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.WallObject; import net.runelite.api.WallObject;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@@ -79,12 +83,12 @@ import net.runelite.client.ui.overlay.OverlayMenuEntry;
@PluginDependency(XpTrackerPlugin.class) @PluginDependency(XpTrackerPlugin.class)
public class MiningPlugin extends Plugin public class MiningPlugin extends Plugin
{ {
private static final Pattern MINING_PATERN = Pattern.compile( private static final Pattern MINING_PATTERN = Pattern.compile(
"You " + "You " +
"(?:manage to|just)" + "(?:manage to|just)" +
" (?:mined?|quarry) " + " (?:mined?|quarry) " +
"(?:some|an?) " + "(?:some|an?) " +
"(?:copper|tin|clay|iron|silver|coal|gold|mithril|adamantite|runeite|amethyst|sandstone|granite|Opal|piece of Jade|Red Topaz|Emerald|Sapphire|Ruby|Diamond)" + "(?:copper|tin|clay|iron|silver|coal|gold|mithril|adamantite|runeite|amethyst|sandstone|granite|barronite shards|barronite deposit|Opal|piece of Jade|Red Topaz|Emerald|Sapphire|Ruby|Diamond)" +
"(?:\\.|!)"); "(?:\\.|!)");
@Inject @Inject
@@ -343,10 +347,20 @@ public class MiningPlugin extends Plugin
respawns.add(rockRespawn); respawns.add(rockRespawn);
break; break;
} }
case ROCKS_41549: // Depleted barronite vein
case ROCKS_41550: // Depleted barronite vein
{
Rock rock = Rock.BARRONITE;
RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(region).toMillis(), rock.getZOffset());
respawns.add(rockRespawn);
break;
}
case ORE_VEIN_26661: // Motherlode vein case ORE_VEIN_26661: // Motherlode vein
case ORE_VEIN_26662: // Motherlode vein case ORE_VEIN_26662: // Motherlode vein
case ORE_VEIN_26663: // Motherlode vein case ORE_VEIN_26663: // Motherlode vein
case ORE_VEIN_26664: // Motherlode vein case ORE_VEIN_26664: // Motherlode vein
case ROCKS_41547: // Barronite vein
case ROCKS_41548: // Barronite vein
{ {
// If the vein respawns before the timer is up, remove it // If the vein respawns before the timer is up, remove it
final WorldPoint point = object.getWorldLocation(); final WorldPoint point = object.getWorldLocation();
@@ -361,7 +375,7 @@ public class MiningPlugin extends Plugin
{ {
if (event.getType() == ChatMessageType.SPAM || event.getType() == ChatMessageType.GAMEMESSAGE) if (event.getType() == ChatMessageType.SPAM || event.getType() == ChatMessageType.GAMEMESSAGE)
{ {
if (MINING_PATERN.matcher(event.getMessage()).matches()) if (MINING_PATTERN.matcher(event.getMessage()).matches())
{ {
if (session == null) if (session == null)
{ {

View File

@@ -97,7 +97,8 @@ enum Rock
EFH_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33255), EFH_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33255),
TE_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33256), TE_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33256),
BASALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33257), BASALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33257),
DAEYALT_ESSENCE(Duration.of(MiningRocksOverlay.DAEYALT_MAX_RESPAWN_TIME, GAME_TICKS), 0, DAEYALT_ESSENCE_39095); DAEYALT_ESSENCE(Duration.of(MiningRocksOverlay.DAEYALT_MAX_RESPAWN_TIME, GAME_TICKS), 0, DAEYALT_ESSENCE_39095),
BARRONITE(Duration.of(89, GAME_TICKS), 140);
private static final int WILDERNESS_RESOURCE_AREA = 12605; private static final int WILDERNESS_RESOURCE_AREA = 12605;
private static final int MISCELLANIA = 10044; private static final int MISCELLANIA = 10044;

View File

@@ -46,6 +46,7 @@ import static net.runelite.api.Constants.ROOF_FLAG_HOVERED;
import static net.runelite.api.Constants.ROOF_FLAG_POSITION; import static net.runelite.api.Constants.ROOF_FLAG_POSITION;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.Tile; import net.runelite.api.Tile;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
@@ -246,14 +247,17 @@ public class RoofRemovalPlugin extends Plugin
continue; continue;
} }
int regionID = tile.getWorldLocation().getRegionID() << 2 | z; // Properly account for instances shifting worldpoints around
final WorldPoint wp = WorldPoint.fromLocalInstance(client, tile.getLocalLocation(), tile.getPlane());
int regionID = wp.getRegionID() << 2 | z;
if (!overrides.containsKey(regionID)) if (!overrides.containsKey(regionID))
{ {
continue; continue;
} }
int rx = tile.getWorldLocation().getRegionX(); int rx = wp.getRegionX();
int ry = tile.getWorldLocation().getRegionY(); int ry = wp.getRegionY();
long[] region = overrides.get(regionID); long[] region = overrides.get(regionID);
if ((region[ry] & (1L << rx)) != 0) if ((region[ry] & (1L << rx)) != 0)
{ {

View File

@@ -61,6 +61,8 @@ enum MiningSiteLocation
BLAST_MINE_WEST(new WorldPoint(1471, 3865, 0), new Rock(22, Ore.HARD_ROCK)), BLAST_MINE_WEST(new WorldPoint(1471, 3865, 0), new Rock(22, Ore.HARD_ROCK)),
BRIMHAVEN_NORTH(new WorldPoint(2732, 3225, 0), new Rock(10, Ore.GOLD)), BRIMHAVEN_NORTH(new WorldPoint(2732, 3225, 0), new Rock(10, Ore.GOLD)),
BRIMHAVEN_SOUTH_(new WorldPoint(2743, 3150, 0), new Rock(6, Ore.GOLD)), BRIMHAVEN_SOUTH_(new WorldPoint(2743, 3150, 0), new Rock(6, Ore.GOLD)),
CAMDOZAAL_MINES_EAST(new WorldPoint(2934, 5811, 0), new Rock(8, Ore.BARRONITE), new Rock(1, Ore.CLAY), new Rock(2, Ore.TIN), new Rock(1, Ore.COPPER)),
CAMDOZAAL_MINES_WEST(new WorldPoint(2914, 5811, 0), new Rock(10, Ore.BARRONITE), new Rock(2, Ore.COPPER), new Rock(2, Ore.CLAY), new Rock(1, Ore.TIN)),
CENTRAL_FREMENIK_ISLES(new WorldPoint(2374, 3850, 0), new Rock(7, Ore.COAL), new Rock(1, Ore.RUNITE)), CENTRAL_FREMENIK_ISLES(new WorldPoint(2374, 3850, 0), new Rock(7, Ore.COAL), new Rock(1, Ore.RUNITE)),
CITHAREDE_ABBEY(new WorldPoint(3400, 3170, 0), new Rock(3, Ore.IRON), new Rock (3, Ore.COAL)), CITHAREDE_ABBEY(new WorldPoint(3400, 3170, 0), new Rock(3, Ore.IRON), new Rock (3, Ore.COAL)),
COAL_TRUCKS(new WorldPoint(2580, 3484, 0), new Rock(18, Ore.COAL)), COAL_TRUCKS(new WorldPoint(2580, 3484, 0), new Rock(18, Ore.COAL)),
@@ -238,6 +240,7 @@ enum MiningSiteLocation
TIN("Tin"), TIN("Tin"),
LIMESTONE("Limestone"), LIMESTONE("Limestone"),
BLURITE("Blurite"), BLURITE("Blurite"),
BARRONITE("Barronite"),
IRON("Iron"), IRON("Iron"),
ELEMENTAL("Elemental"), ELEMENTAL("Elemental"),
SILVER("Silver"), SILVER("Silver"),

View File

@@ -63,6 +63,7 @@ public class XpGlobesOverlay extends Overlay
private static final int MINIMUM_STEP = 10; private static final int MINIMUM_STEP = 10;
private static final int PROGRESS_RADIUS_START = 90; private static final int PROGRESS_RADIUS_START = 90;
private static final int PROGRESS_RADIUS_REMAINDER = 0; private static final int PROGRESS_RADIUS_REMAINDER = 0;
private static final int PROGRESS_BACKGROUND_SIZE = 5;
private static final int TOOLTIP_RECT_SIZE_X = 150; private static final int TOOLTIP_RECT_SIZE_X = 150;
private static final Color DARK_OVERLAY_COLOR = new Color(0, 0, 0, 180); private static final Color DARK_OVERLAY_COLOR = new Color(0, 0, 0, 180);
static final String FLIP_ACTION = "Flip"; static final String FLIP_ACTION = "Flip";
@@ -108,31 +109,34 @@ public class XpGlobesOverlay extends Overlay
return null; return null;
} }
int curDrawPosition = 0; // The progress arc is drawn either side of the perimeter of the background. This value accounts for that
// when calculating draw positions and overall size of the overlay
final int progressArcOffset = (int) Math.ceil(Math.max(PROGRESS_BACKGROUND_SIZE, config.progressArcStrokeWidth()) / 2.0);
int curDrawPosition = progressArcOffset;
for (final XpGlobe xpGlobe : xpGlobes) for (final XpGlobe xpGlobe : xpGlobes)
{ {
int startXp = xpTrackerService.getStartGoalXp(xpGlobe.getSkill()); int startXp = xpTrackerService.getStartGoalXp(xpGlobe.getSkill());
int goalXp = xpTrackerService.getEndGoalXp(xpGlobe.getSkill()); int goalXp = xpTrackerService.getEndGoalXp(xpGlobe.getSkill());
if (config.alignOrbsVertically()) if (config.alignOrbsVertically())
{ {
renderProgressCircle(graphics, xpGlobe, startXp, goalXp, 0, curDrawPosition, getBounds()); renderProgressCircle(graphics, xpGlobe, startXp, goalXp, progressArcOffset, curDrawPosition, getBounds());
} }
else else
{ {
renderProgressCircle(graphics, xpGlobe, startXp, goalXp, curDrawPosition, 0, getBounds()); renderProgressCircle(graphics, xpGlobe, startXp, goalXp, curDrawPosition, progressArcOffset, getBounds());
} }
curDrawPosition += MINIMUM_STEP + config.xpOrbSize(); curDrawPosition += MINIMUM_STEP + config.xpOrbSize();
} }
// Get length of markers // Get length of markers
final int markersLength = (queueSize * (config.xpOrbSize())) + ((MINIMUM_STEP) * (queueSize - 1)); final int markersLength = (queueSize * (config.xpOrbSize() + progressArcOffset)) + ((MINIMUM_STEP) * (queueSize - 1));
if (config.alignOrbsVertically()) if (config.alignOrbsVertically())
{ {
return new Dimension(config.xpOrbSize(), markersLength); return new Dimension(config.xpOrbSize() + progressArcOffset * 2, markersLength);
} }
else else
{ {
return new Dimension(markersLength, config.xpOrbSize()); return new Dimension(markersLength, config.xpOrbSize() + progressArcOffset * 2);
} }
} }
@@ -184,7 +188,7 @@ public class XpGlobesOverlay extends Overlay
x, y, x, y,
config.xpOrbSize(), config.xpOrbSize(), config.xpOrbSize(), config.xpOrbSize(),
PROGRESS_RADIUS_REMAINDER, radiusToGoalXp, PROGRESS_RADIUS_REMAINDER, radiusToGoalXp,
5, PROGRESS_BACKGROUND_SIZE,
config.progressOrbOutLineColor() config.progressOrbOutLineColor()
); );
drawProgressArc( drawProgressArc(

View File

@@ -69,11 +69,14 @@ import net.runelite.client.ui.JagexColors;
import net.runelite.client.ui.overlay.tooltip.Tooltip; import net.runelite.client.ui.overlay.tooltip.Tooltip;
import net.runelite.client.ui.overlay.tooltip.TooltipManager; import net.runelite.client.ui.overlay.tooltip.TooltipManager;
import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ColorUtil;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
@Singleton @Singleton
@Slf4j @Slf4j
public class OverlayRenderer extends MouseAdapter implements KeyListener public class OverlayRenderer extends MouseAdapter implements KeyListener
{ {
private static final Marker DEDUPLICATE = MarkerFactory.getMarker("DEDUPLICATE");
private static final int BORDER = 5; private static final int BORDER = 5;
private static final int BORDER_TOP = BORDER + 15; private static final int BORDER_TOP = BORDER + 15;
private static final int PADDING = 2; private static final int PADDING = 2;
@@ -786,7 +789,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
} }
catch (Exception ex) catch (Exception ex)
{ {
log.warn("Error during overlay rendering", ex); log.warn(DEDUPLICATE, "Error during overlay rendering", ex);
return; return;
} }

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2021, 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.util;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.core.spi.FilterReply;
import java.util.Deque;
import java.util.concurrent.ConcurrentLinkedDeque;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
public class DeduplicationFilter extends TurboFilter
{
private static final Marker deduplicateMarker = MarkerFactory.getMarker("DEDUPLICATE");
private static final int CACHE_SIZE = 8;
private static final int DUPLICATE_LOG_COUNT = 1000;
@RequiredArgsConstructor
@EqualsAndHashCode(exclude = {"count"})
private static class LogException
{
private final String message;
private final StackTraceElement[] stackTraceElements;
private volatile int count;
}
private final Deque<LogException> cache = new ConcurrentLinkedDeque<>();
@Override
public void stop()
{
cache.clear();
super.stop();
}
@Override
public FilterReply decide(Marker marker, Logger logger, Level level, String s, Object[] objects, Throwable throwable)
{
if (marker != deduplicateMarker || logger.isDebugEnabled() || throwable == null)
{
return FilterReply.NEUTRAL;
}
LogException logException = new LogException(s, throwable.getStackTrace());
for (LogException e : cache)
{
if (logException.equals(e))
{
// this iinc is not atomic, but doesn't matter in practice
if (++e.count % DUPLICATE_LOG_COUNT == 0)
{
logger.warn("following log message logged " + DUPLICATE_LOG_COUNT + " times!");
return FilterReply.NEUTRAL;
}
return FilterReply.DENY;
}
}
synchronized (cache)
{
if (cache.size() >= CACHE_SIZE)
{
cache.pop();
}
cache.push(logException);
}
return FilterReply.NEUTRAL;
}
}

View File

@@ -24,6 +24,8 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--> -->
<configuration scan="true"> <configuration scan="true">
<turboFilter class="net.runelite.client.util.DeduplicationFilter"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</Pattern> <Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</Pattern>

View File

@@ -3260,5 +3260,15 @@
"z1": 1, "z1": 1,
"z2": 2 "z2": 2
} }
],
"10290": [ // Ardougne Monastery
{
"rx1": 43,
"ry1": 17,
"rx2": 49,
"ry2": 17,
"z1": 0,
"z2": 0
}
] ]
} }

View File

@@ -78,6 +78,12 @@
"name": "Baked Potato", "name": "Baked Potato",
"xp": 15 "xp": 15
}, },
{
"level": 7,
"icon": 25654,
"name": "Guppy",
"xp": 12
},
{ {
"level": 8, "level": 8,
"icon": 2048, "icon": 2048,
@@ -228,6 +234,12 @@
"name": "Cup of tea", "name": "Cup of tea",
"xp": 52 "xp": 52
}, },
{
"level": 20,
"icon": 25660,
"name": "Cavefish",
"xp": 23
},
{ {
"level": 21, "level": 21,
"icon": 9988, "icon": 9988,
@@ -378,6 +390,12 @@
"name": "Choc Saturday", "name": "Choc Saturday",
"xp": 170 "xp": 170
}, },
{
"level": 33,
"icon": 25666,
"name": "Tetra",
"xp": 31
},
{ {
"level": 34, "level": 34,
"icon": 7178, "icon": 7178,
@@ -516,6 +534,12 @@
"name": "Fried Mushrooms", "name": "Fried Mushrooms",
"xp": 60 "xp": 60
}, },
{
"level": 46,
"icon": 25672,
"name": "Catfish",
"xp": 43
},
{ {
"level": 47, "level": 47,
"icon": 7188, "icon": 7188,

View File

@@ -24,6 +24,12 @@
"name": "Raw Karambwanji", "name": "Raw Karambwanji",
"xp": 5 "xp": 5
}, },
{
"level": 7,
"icon": 25652,
"name": "Raw Guppy",
"xp": 8
},
{ {
"level": 10, "level": 10,
"icon": 345, "icon": 345,
@@ -48,6 +54,12 @@
"name": "Raw Trout", "name": "Raw Trout",
"xp": 50 "xp": 50
}, },
{
"level": 20,
"icon": 25658,
"name": "Raw Cavefish",
"xp": 16
},
{ {
"level": 23, "level": 23,
"icon": 341, "icon": 341,
@@ -72,6 +84,12 @@
"name": "Raw Salmon", "name": "Raw Salmon",
"xp": 70 "xp": 70
}, },
{
"level": 33,
"icon": 25664,
"name": "Raw Tetra",
"xp": 24
},
{ {
"level": 35, "level": 35,
"icon": 359, "icon": 359,
@@ -102,6 +120,12 @@
"name": "Raw Bass", "name": "Raw Bass",
"xp": 100 "xp": 100
}, },
{
"level": 46,
"icon": 25670,
"name": "Raw Catfish",
"xp": 33
},
{ {
"level": 48, "level": 48,
"icon": 11328, "icon": 11328,

View File

@@ -36,6 +36,18 @@
"name": "Limestone", "name": "Limestone",
"xp": 26.5 "xp": 26.5
}, },
{
"level": 14,
"icon": 25683,
"name": "Barronite shards",
"xp": 16
},
{
"level": 14,
"icon": 25684,
"name": "Barronite deposit",
"xp": 32
},
{ {
"level": 15, "level": 15,
"icon": 440, "icon": 440,

View File

@@ -368,6 +368,30 @@
"icon": 25419, "icon": 25419,
"name": "Urium Remains", "name": "Urium Remains",
"xp": 120 "xp": 120
},
{
"level": 1,
"icon": 25654,
"name": "Guppy",
"xp": 4
},
{
"level": 1,
"icon": 25660,
"name": "Cavefish",
"xp": 7
},
{
"level": 1,
"icon": 25666,
"name": "Tetra",
"xp": 10
},
{
"level": 1,
"icon": 25672,
"name": "Cavefish",
"xp": 16
} }
] ]
} }

View File

@@ -102,6 +102,12 @@
"name": "Mind Rune", "name": "Mind Rune",
"xp": 5.5 "xp": 5.5
}, },
{
"level": 2,
"icon": 25696,
"name": "Mind core",
"xp": 55
},
{ {
"level": 5, "level": 5,
"icon": 555, "icon": 555,
@@ -156,6 +162,12 @@
"name": "Body Rune", "name": "Body Rune",
"xp": 7.5 "xp": 7.5
}, },
{
"level": 20,
"icon": 25698,
"name": "Body core",
"xp": 75
},
{ {
"level": 23, "level": 23,
"icon": 4699, "icon": 4699,
@@ -174,6 +186,12 @@
"name": "Chaos Rune", "name": "Chaos Rune",
"xp": 8.5 "xp": 8.5
}, },
{
"level": 35,
"icon": 25700,
"name": "Chaos core",
"xp": 85
},
{ {
"level": 40, "level": 40,
"icon": 9075, "icon": 9075,

View File

@@ -156,6 +156,12 @@
"name": "Bronze 2h Sword", "name": "Bronze 2h Sword",
"xp": 37.5 "xp": 37.5
}, },
{
"level": 14,
"icon": 25684,
"name": "Barronite deposits",
"xp": 30
},
{ {
"level": 15, "level": 15,
"icon": 2351, "icon": 2351,