Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-07-07 13:20:23 +02:00
34 changed files with 311 additions and 94 deletions

View File

@@ -479,14 +479,11 @@ public class Notifier
{
if (NOTIFICATION_FILE.exists())
{
try
try (InputStream fileStream = new BufferedInputStream(new FileInputStream(NOTIFICATION_FILE));
AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
{
InputStream fileStream = new BufferedInputStream(new FileInputStream(NOTIFICATION_FILE));
try (AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
{
clip.open(sound);
return true;
}
clip.open(sound);
return true;
}
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e)
{
@@ -495,8 +492,8 @@ public class Notifier
}
// Otherwise load from the classpath
InputStream fileStream = new BufferedInputStream(Notifier.class.getResourceAsStream("notification.wav"));
try (AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
try (InputStream fileStream = new BufferedInputStream(Notifier.class.getResourceAsStream("notification.wav"));
AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
{
clip.open(sound);
return true;

View File

@@ -30,6 +30,7 @@ import com.google.gson.JsonSyntaxException;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
@@ -134,13 +135,12 @@ public class ExternalPluginClient
private static Certificate loadCertificate()
{
try
try (InputStream in = ExternalPluginClient.class.getResourceAsStream("externalplugins.crt"))
{
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
Certificate certificate = certFactory.generateCertificate(ExternalPluginClient.class.getResourceAsStream("externalplugins.crt"));
return certificate;
return certFactory.generateCertificate(in);
}
catch (CertificateException e)
catch (CertificateException | IOException e)
{
throw new RuntimeException(e);
}

View File

@@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
@@ -49,12 +50,19 @@ public class ItemVariationMapping
static
{
final Gson gson = new Gson();
final TypeToken<Map<String, Collection<Integer>>> typeToken = new TypeToken<Map<String, Collection<Integer>>>()
{
};
// CHECKSTYLE:OFF
final TypeToken<Map<String, Collection<Integer>>> typeToken = new TypeToken<Map<String, Collection<Integer>>>(){};
// CHECKSTYLE:ON
final InputStream geLimitData = ItemVariationMapping.class.getResourceAsStream("/item_variations.json");
final Map<String, Collection<Integer>> itemVariations = gson.fromJson(new InputStreamReader(geLimitData, StandardCharsets.UTF_8), typeToken.getType());
final Map<String, Collection<Integer>> itemVariations;
try (InputStream geLimitData = ItemVariationMapping.class.getResourceAsStream("/item_variations.json"))
{
itemVariations = gson.fromJson(new InputStreamReader(geLimitData, StandardCharsets.UTF_8), typeToken.getType());
}
catch (IOException e)
{
throw new RuntimeException(e);
}
ImmutableMap.Builder<Integer, Integer> builder = new ImmutableMap.Builder<>();
ImmutableMultimap.Builder<Integer, Integer> invertedBuilder = new ImmutableMultimap.Builder<>();

View File

@@ -237,7 +237,7 @@ public class LootManager
public void onNpcChanged(NpcChanged npcChanged)
{
final NPC npc = npcChanged.getNpc();
if (npc.getId() == NpcID.THE_NIGHTMARE_9433)
if (npc.getId() == NpcID.THE_NIGHTMARE_9433 || npc.getId() == NpcID.PHOSANIS_NIGHTMARE_9424)
{
delayedLootNpc = npc;
delayedLootTickLimit = 15;

View File

@@ -1738,12 +1738,22 @@ public class ChatCommandsPlugin extends Plugin
case "the corrupted gauntlet":
return "Corrupted Gauntlet";
// The Nightmare
case "nm":
case "tnm":
case "nmare":
case "the nightmare":
return "Nightmare";
// Phosani's Nightmare
case "pnm":
case "phosani":
case "phosanis":
case "phosani nm":
case "phosani nightmare":
case "phosanis nightmare":
return "Phosani's Nightmare";
// Hallowed Sepulchre
case "hs":
case "sepulchre":

View File

@@ -44,7 +44,7 @@ public interface ChatNotificationsConfig extends Config
position = 1,
keyName = "highlightWordsString",
name = "Highlight words",
description = "Highlights the following words in chat",
description = "Highlights the following words in chat, separated by commas",
section = highlightLists
)
default String highlightWordsString()

View File

@@ -149,7 +149,7 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc
new AnagramClue("TEN WIGS ON", "Wingstone", new WorldPoint(3389, 2877, 0), "Between Nardah & Agility Pyramid"),
new AnagramClue("THEM CAL CAME", "Cam the Camel", new WorldPoint(3300, 3231, 0), "Just outside of the Duel Arena"),
new AnagramClue("THICKNO", "Hickton", new WorldPoint(2822, 3442, 0), "Catherby fletching shop", "How many ranges are there in Catherby?", "2"),
new AnagramClue("TWENTY CURE IRON", "New recruit Tony", new WorldPoint(1503, 3553, 0), "Shayzien Graveyard"),
new AnagramClue("TWENTY CURE IRON", "New Recruit Tony", new WorldPoint(1503, 3553, 0), "Shayzien Graveyard"),
new AnagramClue("UNLEASH NIGHT MIST", "Sigli the Huntsman", new WorldPoint(2660, 3654, 0), "Rellekka", "What is the combined slayer requirement of every monster in the slayer cave?", "302"),
new AnagramClue("VESTE", "Steve", new WorldPoint(2432, 3423, 0), "Upstairs Wyvern Area or Stronghold Slayer Cave", "How many farming patches are there in Gnome stronghold?", "2"),
new AnagramClue("VEIL VEDA", "Evil Dave", new WorldPoint(3079, 9892, 0), "Doris' basement, Edgeville", "What is 333 multiplied by 2?", "666"),

View File

@@ -171,6 +171,7 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati
.put(new WorldPoint(3143, 3774, 0), new CoordinateClueInfo("In level 32 Wilderness, by the black chinchompa hunting area.", ZAMORAK_WIZARD))
.put(new WorldPoint(2992, 3941, 0), new CoordinateClueInfo("Wilderness Agility Course, past the log balance.", ZAMORAK_WIZARD))
.put(new WorldPoint(1410, 3611, 0), new CoordinateClueInfo("Lake Molch dock west of Shayzien Encampment.", SARADOMIN_WIZARD))
.put(new WorldPoint(1409, 3483, 0), new CoordinateClueInfo("South of Shayziens' Wall.", SARADOMIN_WIZARD))
// Elite
.put(new WorldPoint(2357, 3151, 0), new CoordinateClueInfo("Lletya.", ARMADYLEAN_OR_BANDOSIAN_GUARD))
.put(new WorldPoint(3587, 3180, 0), new CoordinateClueInfo("Meiyerditch.", ARMADYLEAN_OR_BANDOSIAN_GUARD))

View File

@@ -168,8 +168,8 @@ public enum HotColdLocation
WILDERNESS_54(MASTER, new WorldPoint(2981, 3944, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness.", BRASSICAN_MAGE),
ZEAH_BLASTMINE_BANK(MASTER, new WorldPoint(1504, 3859, 0), ZEAH, "Next to the bank in the Lovakengj blast mine.", BRASSICAN_MAGE),
ZEAH_BLASTMINE_NORTH(MASTER, new WorldPoint(1488, 3881, 0), ZEAH, "Northern part of the Lovakengj blast mine.", BRASSICAN_MAGE),
ZEAH_LOVAKITE_FURNACE(MASTER, new WorldPoint(1507, 3819, 0), ZEAH, "Next to the lovakite furnace in Lovakengj.", ANCIENT_WIZARDS),
ZEAH_LOVAKENGJ_MINE(MASTER, new WorldPoint(1477, 3778, 0), ZEAH, "Next to mithril rock in the Lovakengj mine.", ANCIENT_WIZARDS),
ZEAH_LOVAKITE_FURNACE(MASTER, new WorldPoint(1507, 3819, 0), ZEAH, "Next to the lovakite furnace in Lovakengj.", BRASSICAN_MAGE),
ZEAH_LOVAKENGJ_MINE(MASTER, new WorldPoint(1477, 3778, 0), ZEAH, "Next to mithril rock in the Lovakengj mine.", BRASSICAN_MAGE),
ZEAH_SULPHR_MINE(MASTER, new WorldPoint(1428, 3869, 0), ZEAH, "Western entrance in the Lovakengj sulphur mine. Facemask or Slayer Helmet recommended.", BRASSICAN_MAGE),
ZEAH_SHAYZIEN_BANK(MASTER, new WorldPoint(1498, 3627, 0), ZEAH, "South-east of the bank in Shayzien Encampment.", BRASSICAN_MAGE),
ZEAH_OVERPASS(MASTER, new WorldPoint(1467, 3714, 0), ZEAH, "Overpass between Lovakengj and Shayzien.", BRASSICAN_MAGE),
@@ -179,7 +179,7 @@ public enum HotColdLocation
ZEAH_LIBRARY(MASTER, new WorldPoint(1603, 3843, 0), ZEAH, "North-west of the Arceuus Library.", BRASSICAN_MAGE),
ZEAH_HOUSECHURCH(MASTER, new WorldPoint(1682, 3792, 0), ZEAH, "By the entrance to the Arceuus church.", ANCIENT_WIZARDS),
ZEAH_DARK_ALTAR(MASTER, new WorldPoint(1698, 3881, 0), ZEAH, "West of the Dark Altar.", BRASSICAN_MAGE),
ZEAH_ARCEUUS_HOUSE(MASTER, new WorldPoint(1710, 3700, 0), ZEAH, "By the southern entrance to Arceuus.", ANCIENT_WIZARDS),
ZEAH_ARCEUUS_HOUSE(MASTER, new WorldPoint(1710, 3700, 0), ZEAH, "By the south-eastern entrance to Arceuus.", BRASSICAN_MAGE),
ZEAH_ESSENCE_MINE(MASTER, new WorldPoint(1762, 3852, 0), ZEAH, "By the Arceuus essence mine.", BRASSICAN_MAGE),
ZEAH_ESSENCE_MINE_NE(MASTER, new WorldPoint(1773, 3867, 0), ZEAH, "North-east of the Arceuus essence mine.", BRASSICAN_MAGE),
ZEAH_PISCARILUS_MINE(MASTER, new WorldPoint(1768, 3705, 0), ZEAH, "South of the Piscarilius mine.", ANCIENT_WIZARDS),

View File

@@ -32,7 +32,9 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Template
{
private final List<Function<String, String>> resourceLoaders = new ArrayList<>();
@@ -80,10 +82,16 @@ public class Template
{
return add(f ->
{
InputStream is = clazz.getResourceAsStream(f);
if (is != null)
try (InputStream is = clazz.getResourceAsStream(f))
{
return inputStreamToString(is);
if (is != null)
{
return inputStreamToString(is);
}
}
catch (IOException ex)
{
log.warn(null, ex);
}
return null;
});

View File

@@ -46,7 +46,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.events.WidgetMenuOptionClicked;
import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_OPTION;
import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.eventbus.Subscribe;
@@ -57,9 +57,9 @@ import net.runelite.client.menus.WidgetMenuOption;
@Slf4j
class GroundMarkerSharingManager
{
private static final WidgetMenuOption EXPORT_MARKERS_OPTION = new WidgetMenuOption("Export", "Ground Markers", WORLD_MAP_OPTION);
private static final WidgetMenuOption IMPORT_MARKERS_OPTION = new WidgetMenuOption("Import", "Ground Markers", WORLD_MAP_OPTION);
private static final WidgetMenuOption CLEAR_MARKERS_OPTION = new WidgetMenuOption("Clear", "Ground Markers", WORLD_MAP_OPTION);
private static final WidgetMenuOption EXPORT_MARKERS_OPTION = new WidgetMenuOption("Export", "Ground Markers", MINIMAP_WORLDMAP_OPTIONS);
private static final WidgetMenuOption IMPORT_MARKERS_OPTION = new WidgetMenuOption("Import", "Ground Markers", MINIMAP_WORLDMAP_OPTIONS);
private static final WidgetMenuOption CLEAR_MARKERS_OPTION = new WidgetMenuOption("Clear", "Ground Markers", MINIMAP_WORLDMAP_OPTIONS);
private final GroundMarkerPlugin plugin;
private final Client client;
@@ -108,7 +108,7 @@ class GroundMarkerSharingManager
public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event)
{
// ensure that the option clicked is the export markers option
if (event.getWidget() != WORLD_MAP_OPTION)
if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS)
{
return;
}

View File

@@ -28,7 +28,7 @@ import com.google.inject.Binder;
import javax.inject.Inject;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.WidgetMenuOptionClicked;
import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_OPTION;
import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseManager;
@@ -44,7 +44,7 @@ import net.runelite.client.ui.overlay.OverlayManager;
)
public class InstanceMapPlugin extends Plugin
{
private final WidgetMenuOption openMapOption = new WidgetMenuOption("Show", "Instance Map", WORLD_MAP_OPTION);
private final WidgetMenuOption openMapOption = new WidgetMenuOption("Show", "Instance Map", MINIMAP_WORLDMAP_OPTIONS);
@Inject
private InstanceMapInputListener inputListener;
@@ -115,7 +115,7 @@ public class InstanceMapPlugin extends Plugin
@Subscribe
public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event)
{
if (event.getWidget() != WORLD_MAP_OPTION)
if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS)
{
return;
}

View File

@@ -55,4 +55,15 @@ public interface InventoryViewerConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "hideIfInventoryActive",
name = "Hidden on inventory tab",
description = "Whether or not the overlay is hidden when the inventory tab is open.",
position = 2
)
default boolean hideIfInventoryActive()
{
return false;
}
}

View File

@@ -35,6 +35,7 @@ import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemComposition;
import net.runelite.api.ItemContainer;
import net.runelite.api.VarClientInt;
import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.overlay.OverlayPanel;
import net.runelite.client.ui.overlay.OverlayPosition;
@@ -49,6 +50,7 @@ class InventoryViewerOverlay extends OverlayPanel
private final Client client;
private final ItemManager itemManager;
private final InventoryViewerConfig config;
private boolean hidden;
@Inject
@@ -61,6 +63,7 @@ class InventoryViewerOverlay extends OverlayPanel
panelComponent.setOrientation(ComponentOrientation.HORIZONTAL);
this.itemManager = itemManager;
this.client = client;
this.config = config;
this.hidden = config.hiddenDefault();
}
@@ -72,6 +75,11 @@ class InventoryViewerOverlay extends OverlayPanel
return null;
}
if (client.getVar(VarClientInt.INVENTORY_TAB) == 3 && config.hideIfInventoryActive())
{
return null;
}
final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY);
if (itemContainer == null)

View File

@@ -24,6 +24,7 @@
*/
package net.runelite.client.plugins.objectindicators;
import com.google.common.base.Strings;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
@@ -85,7 +86,10 @@ class ObjectIndicatorsOverlay extends Overlay
// This is a multiloc
composition = composition.getImpostor();
// Only mark the object if the name still matches
if (composition == null || !composition.getName().equals(colorTileObject.getName()))
if (composition == null
|| Strings.isNullOrEmpty(composition.getName())
|| "null".equals(composition.getName())
|| !composition.getName().equals(colorTileObject.getName()))
{
continue;
}

View File

@@ -288,6 +288,18 @@ public class ObjectIndicatorsPlugin extends Plugin
return;
}
ObjectComposition objectComposition = client.getObjectDefinition(object.getId());
if (objectComposition.getImpostorIds() == null)
{
// Multiloc names are instead checked in the overlay
String name = objectComposition.getName();
if (Strings.isNullOrEmpty(name) || name.equals("null"))
{
// was marked, but name has changed
return;
}
}
for (ObjectPoint objectPoint : objectPoints)
{
if (worldPoint.getRegionX() == objectPoint.getRegionX()
@@ -297,7 +309,7 @@ public class ObjectIndicatorsPlugin extends Plugin
{
log.debug("Marking object {} due to matching {}", object, objectPoint);
objects.add(new ColorTileObject(object,
client.getObjectDefinition(object.getId()),
objectComposition,
objectPoint.getName(),
objectPoint.getColor()));
break;

View File

@@ -872,7 +872,7 @@ public class RaidsPlugin extends Plugin
@Override
public void hotkeyPressed()
{
screenshotScoutOverlay();
clientThread.invoke(RaidsPlugin.this::screenshotScoutOverlay);
}
};

View File

@@ -28,6 +28,7 @@ import com.google.inject.Inject;
import com.google.inject.Provides;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.GameState;
@@ -59,7 +60,10 @@ public class SkyboxPlugin extends Plugin
@Override
public void startUp() throws IOException
{
skybox = new Skybox(SkyboxPlugin.class.getResourceAsStream("skybox.txt"), "skybox.txt");
try (InputStream in = SkyboxPlugin.class.getResourceAsStream("skybox.txt"))
{
skybox = new Skybox(in, "skybox.txt");
}
}
@Override

View File

@@ -260,6 +260,12 @@ public class WintertodtPlugin extends Plugin
MessageNode messageNode = chatMessage.getMessageNode();
final WintertodtInterruptType interruptType;
if (messageNode.getValue().startsWith("You carefully fletch the root"))
{
setActivity(WintertodtActivity.FLETCHING);
return;
}
if (messageNode.getValue().startsWith("The cold of"))
{
interruptType = WintertodtInterruptType.COLD;

View File

@@ -278,7 +278,7 @@ class XpInfoBox extends JPanel
{
final List<Integer> positions = new ArrayList<>();
for (int level = xpSnapshotSingle.getStartLevel() + 1; level < xpSnapshotSingle.getEndLevel(); level++)
for (int level = xpSnapshotSingle.getStartLevel() + 1; level <= xpSnapshotSingle.getEndLevel(); level++)
{
double relativeStartExperience = Experience.getXpForLevel(level) - xpSnapshotSingle.getStartGoalXp();
double relativeEndExperience = xpSnapshotSingle.getEndGoalXp() - xpSnapshotSingle.getStartGoalXp();

View File

@@ -614,13 +614,13 @@ public class ClientLoader implements Supplier<Applet>
private static Certificate[] getJagexCertificateChain()
{
try
try (InputStream in = ClientLoader.class.getResourceAsStream("jagex.crt"))
{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt"));
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
return certificates.toArray(new Certificate[0]);
}
catch (CertificateException e)
catch (CertificateException | IOException e)
{
throw new RuntimeException("Unable to parse pinned certificates", e);
}

View File

@@ -28,6 +28,7 @@ import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.text.StyleContext;
import lombok.Getter;
@@ -48,10 +49,12 @@ public class FontManager
{
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try
try (InputStream inRunescape = FontManager.class.getResourceAsStream("runescape.ttf");
InputStream inRunescapeSmall = FontManager.class.getResourceAsStream("runescape_small.ttf");
InputStream inRunescapeBold = FontManager.class.getResourceAsStream("runescape_bold.ttf"))
{
Font font = Font.createFont(Font.TRUETYPE_FONT,
FontManager.class.getResourceAsStream("runescape.ttf"))
// runescape
Font font = Font.createFont(Font.TRUETYPE_FONT, inRunescape)
.deriveFont(Font.PLAIN, 16);
ge.registerFont(font);
@@ -59,8 +62,8 @@ public class FontManager
.getFont(font.getName(), Font.PLAIN, 16);
ge.registerFont(runescapeFont);
Font smallFont = Font.createFont(Font.TRUETYPE_FONT,
FontManager.class.getResourceAsStream("runescape_small.ttf"))
// small
Font smallFont = Font.createFont(Font.TRUETYPE_FONT, inRunescapeSmall)
.deriveFont(Font.PLAIN, 16);
ge.registerFont(smallFont);
@@ -68,8 +71,8 @@ public class FontManager
.getFont(smallFont.getName(), Font.PLAIN, 16);
ge.registerFont(runescapeSmallFont);
Font boldFont = Font.createFont(Font.TRUETYPE_FONT,
FontManager.class.getResourceAsStream("runescape_bold.ttf"))
// bold
Font boldFont = Font.createFont(Font.TRUETYPE_FONT, inRunescapeBold)
.deriveFont(Font.BOLD, 16);
ge.registerFont(boldFont);

View File

@@ -36,6 +36,7 @@ import java.awt.image.PixelGrabber;
import java.awt.image.RescaleOp;
import java.awt.image.WritableRaster;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -384,11 +385,11 @@ public class ImageUtil
*/
public static BufferedImage loadImageResource(final Class<?> c, final String path)
{
try
try (InputStream in = c.getResourceAsStream(path))
{
synchronized (ImageIO.class)
{
return ImageIO.read(c.getResourceAsStream(path));
return ImageIO.read(in);
}
}
catch (IllegalArgumentException e)

View File

@@ -27,6 +27,7 @@ package net.runelite.client.util;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -104,10 +105,10 @@ public class ReflectUtil
*/
public static void installLookupHelper(PrivateLookupableClassLoader cl)
{
try
String name = PrivateLookupHelper.class.getName();
try (InputStream in = ReflectUtil.class.getResourceAsStream("/" + name.replace('.', '/') + ".class"))
{
String name = PrivateLookupHelper.class.getName();
byte[] classData = ByteStreams.toByteArray(ReflectUtil.class.getResourceAsStream("/" + name.replace('.', '/') + ".class"));
byte[] classData = ByteStreams.toByteArray(in);
Class<?> clazz = cl.defineClass0(name, classData, 0, classData.length);
// force <clinit> to run