Merge branch 'master' into externalserror1

This commit is contained in:
Tyler Bochard
2020-03-12 22:33:30 -04:00
committed by GitHub
96 changed files with 2094 additions and 2758 deletions

View File

@@ -24,7 +24,7 @@
*/
package net.runelite.client;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;
import java.time.temporal.ChronoUnit;
import java.util.UUID;
import javax.inject.Inject;

View File

@@ -30,8 +30,8 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import io.reactivex.Completable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import io.sentry.Sentry;
import io.sentry.SentryClient;
import java.io.File;
@@ -39,14 +39,18 @@ import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.nio.file.Paths;
import java.util.Locale;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.inject.Provider;
import javax.inject.Singleton;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.ValueConversionException;
import joptsimple.ValueConverter;
import joptsimple.util.EnumConverter;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@@ -85,6 +89,7 @@ import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay;
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
import net.runelite.client.util.AppLock;
import net.runelite.client.util.WorldUtil;
import net.runelite.client.ws.PartyService;
import net.runelite.http.api.worlds.World;
@@ -105,6 +110,7 @@ public class RuneLite
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
public static final File LOGS_DIR = new File(RUNELITE_DIR, "logs");
public static final File PLUGINS_DIR = new File(RUNELITE_DIR, "plugins");
public static final File DEFAULT_CONFIG_FILE = new File(RUNELITE_DIR, "runeliteplus.properties");
public static final Locale SYSTEM_LOCALE = Locale.getDefault();
public static boolean allowPrivateServer = false;
@@ -201,6 +207,9 @@ public class RuneLite
@Inject
private Scheduler scheduler;
@Inject
private AppLock appLock;
public static void main(String[] args) throws Exception
{
Locale.setDefault(Locale.ENGLISH);
@@ -215,6 +224,11 @@ public class RuneLite
final ArgumentAcceptingOptionSpec<Integer> worldInfo = parser
.accepts("world")
.withRequiredArg().ofType(Integer.class);
final ArgumentAcceptingOptionSpec<File> configfile = parser.accepts("config", "Use a specified config file")
.withRequiredArg()
.withValuesConvertedBy(new ConfigFileConverter())
.defaultsTo(DEFAULT_CONFIG_FILE);
final ArgumentAcceptingOptionSpec<ClientUpdateCheckMode> updateMode = parser
.accepts("rs", "Select client type")
.withRequiredArg()
@@ -230,7 +244,18 @@ public class RuneLite
});
parser.accepts("help", "Show this text").forHelp();
OptionSet options = parser.parse(args);
OptionSet options = parser.parse("");
try
{
options = parser.parse(args);
}
catch (OptionException e)
{
log.warn("Error parsing launch args: {}", e.getMessage());
log.warn("Proceeding with no arguments.");
}
if (options.has("help"))
{
@@ -297,18 +322,6 @@ public class RuneLite
RuneLiteSplashScreen.init();
}
final boolean developerMode = options.has("developer-mode");
if (developerMode)
{
boolean assertions = false;
assert assertions = true;
if (!assertions)
{
log.warn("Developers should enable assertions; Add `-ea` to your JVM arguments`");
}
}
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) ->
{
log.error("Uncaught exception:", throwable);
@@ -327,7 +340,7 @@ public class RuneLite
injector = Guice.createInjector(new RuneLiteModule(
clientLoader,
true));
options.valueOf(configfile)));
injector.getInstance(RuneLite.class).start();
final long end = System.currentTimeMillis();
@@ -368,9 +381,11 @@ public class RuneLite
externalPluginManager.startExternalUpdateManager();
externalPluginManager.startExternalPluginManager();
RuneLiteSplashScreen.stage(.59, "Updating external plugins");
externalPluginManager.update();
if (appLock.lock(this.getClass().getName()))
{
RuneLiteSplashScreen.stage(.59, "Updating external plugins");
externalPluginManager.update();
}
// Load the plugins, but does not start them yet.
// This will initialize configuration
@@ -387,7 +402,7 @@ public class RuneLite
pluginManager.loadDefaultPluginConfiguration();
// Start client session
RuneLiteSplashScreen.stage(.80, "Starting core interface");
RuneLiteSplashScreen.stage(.77, "Starting core interface");
clientSessionManager.start();
//Set the world if specified via CLI args - will not work until clientUI.init is called
@@ -395,7 +410,7 @@ public class RuneLite
worldArg.ifPresent(this::setWorld);
// Initialize UI
RuneLiteSplashScreen.stage(.77, "Initialize UI");
RuneLiteSplashScreen.stage(.80, "Initialize UI");
clientUI.init(this);
// Initialize Discord service
@@ -487,8 +502,47 @@ public class RuneLite
public void shutdown()
{
configManager.sendConfig();
clientSessionManager.shutdown();
discordService.close();
appLock.release();
}
private static class ConfigFileConverter implements ValueConverter<File>
{
@Override
public File convert(String fileName)
{
final File file;
if (Paths.get(fileName).isAbsolute()
|| fileName.startsWith("./")
|| fileName.startsWith(".\\"))
{
file = new File(fileName);
}
else
{
file = new File(RuneLite.RUNELITE_DIR, fileName);
}
if (file.exists() && (!file.isFile() || !file.canWrite()))
{
throw new ValueConversionException(String.format("File %s is not accessible", file.getAbsolutePath()));
}
return file;
}
@Override
public Class<? extends File> valueType()
{
return File.class;
}
@Override
public String valuePattern()
{
return null;
}
}
}

View File

@@ -41,6 +41,7 @@ import net.runelite.client.callback.Hooks;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.LauncherConfig;
import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.EventBus;
@@ -61,18 +62,18 @@ public class RuneLiteModule extends AbstractModule
private static final int MAX_OKHTTP_CACHE_SIZE = 20 * 1024 * 1024; // 20mb
private final Supplier<Applet> clientLoader;
private final boolean developerMode;
private final File config;
public RuneLiteModule(final Supplier<Applet> clientLoader, boolean developerMode)
public RuneLiteModule(final Supplier<Applet> clientLoader, File config)
{
this.clientLoader = clientLoader;
this.developerMode = developerMode;
this.config = config;
}
@Override
protected void configure()
{
bindConstant().annotatedWith(Names.named("developerMode")).to(developerMode);
bind(File.class).annotatedWith(Names.named("config")).toInstance(config);
bind(ScheduledExecutorService.class).toInstance(new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()));
bind(OkHttpClient.class).toInstance(RuneLiteAPI.CLIENT.newBuilder()
.cache(new Cache(new File(RuneLite.CACHE_DIR, "okhttp"), MAX_OKHTTP_CACHE_SIZE))
@@ -132,4 +133,11 @@ public class RuneLiteModule extends AbstractModule
{
return configManager.getConfig(ChatColorConfig.class);
}
@Provides
@Singleton
LauncherConfig provideLauncherConfig(ConfigManager configManager)
{
return configManager.getConfig(LauncherConfig.class);
}
}

View File

@@ -136,8 +136,7 @@ public class RuneLiteProperties
@Nullable
public static String getLauncherVersion()
{
String launcherVersion = properties.getProperty(LAUNCHER_VERSION_PROPERTY);
return launcherVersion.equals("-1") ? null : launcherVersion;
return System.getProperty(LAUNCHER_VERSION_PROPERTY);
}
@Nullable

View File

@@ -24,8 +24,8 @@
*/
package net.runelite.client;
import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.core.Observable;
import java.io.IOException;
import java.util.UUID;
import net.runelite.http.api.RuneLiteAPI;

View File

@@ -25,7 +25,7 @@
package net.runelite.client.account;
import com.google.gson.Gson;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;

View File

@@ -25,8 +25,8 @@
package net.runelite.client.callback;
import com.google.inject.Inject;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
import io.reactivex.rxjava3.schedulers.Schedulers;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;

View File

@@ -59,6 +59,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.coords.WorldPoint;
@@ -75,20 +76,20 @@ import org.apache.commons.lang3.StringUtils;
@Slf4j
public class ConfigManager
{
private static final String SETTINGS_FILE_NAME = "runeliteplus.properties";
private static final String STANDARD_SETTINGS_FILE_NAME = "settings.properties";
private static final File SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME);
private static final File STANDARD_SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, STANDARD_SETTINGS_FILE_NAME);
private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this);
private final Properties properties = new Properties();
private final Map<String, String> pendingChanges = new HashMap<>();
private final File settingsFileInput;
@Inject
EventBus eventBus;
@Inject
public ConfigManager(ScheduledExecutorService scheduledExecutorService)
public ConfigManager(@Named("config") File config, ScheduledExecutorService scheduledExecutorService)
{
this.settingsFileInput = config;
scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
}
@@ -414,7 +415,7 @@ public class ConfigManager
handler.invalidate();
properties.clear();
try (FileInputStream in = new FileInputStream(SETTINGS_FILE))
try (FileInputStream in = new FileInputStream(settingsFileInput))
{
properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
}
@@ -460,9 +461,9 @@ public class ConfigManager
private void saveToFile() throws IOException
{
ConfigManager.SETTINGS_FILE.getParentFile().mkdirs();
settingsFileInput.getParentFile().mkdirs();
File tempFile = new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME + ".tmp");
File tempFile = new File(RuneLite.RUNELITE_DIR, RuneLite.DEFAULT_CONFIG_FILE.getName() + ".tmp");
try (FileOutputStream out = new FileOutputStream(tempFile))
{
@@ -473,12 +474,12 @@ public class ConfigManager
try
{
Files.move(tempFile.toPath(), ConfigManager.SETTINGS_FILE.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
Files.move(tempFile.toPath(), settingsFileInput.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
}
catch (AtomicMoveNotSupportedException ex)
{
log.debug("atomic move not supported", ex);
Files.move(tempFile.toPath(), ConfigManager.SETTINGS_FILE.toPath(), StandardCopyOption.REPLACE_EXISTING);
Files.move(tempFile.toPath(), settingsFileInput.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
* 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.config;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@ConfigGroup("openosrs")
public interface LauncherConfig extends Config
{
@Getter(AccessLevel.PRIVATE)
@AllArgsConstructor
enum BootstrapMode
{
STABLE("Stable"),
NIGHTLY("Nightly");
private String name;
@Override
public String toString()
{
return getName();
}
}
@ConfigTitleSection(
keyName = "launcherTitle",
name = "Launcher",
description = "",
position = -1
)
default Title launcherTitle()
{
return new Title();
}
@ConfigTitleSection(
keyName = "updateChannelTitle",
name = "Update channel",
description = "",
position = 1,
titleSection = "launcherTitle"
)
default Title updateChannelTitle()
{
return new Title();
}
@ConfigItem(
position = 2,
keyName = "askMode",
name = "Prompt for update channel",
description = "Ask for nightly or stable every startup",
titleSection = "updateChannelTitle"
)
default boolean askMode()
{
return true;
}
@ConfigItem(
keyName = "bootstrapMode",
name = "Update channel",
description = "Select the update channel",
titleSection = "updateChannelTitle",
position = 3,
hide = "askMode"
)
default BootstrapMode bootstrapMode()
{
return BootstrapMode.STABLE;
}
@ConfigTitleSection(
keyName = "miscLauncherTitle",
name = "Miscellaneous",
description = "",
position = 4,
titleSection = "launcherTitle"
)
default Title miscLauncherTitle()
{
return new Title();
}
@ConfigItem(
position = 5,
keyName = "disableHw",
name = "Disable hardware acceleration",
description = "Enable this if you have graphical issues",
titleSection = "miscLauncherTitle",
warning = "Toggling this setting requires a restart of the client"
)
default boolean disableHw()
{
return false;
}
@ConfigTitleSection(
keyName = "advancedTitle",
name = "Advanced",
description = "",
position = 6,
titleSection = "launcherTitle"
)
default Title advancedTitle()
{
return new Title();
}
@ConfigItem(
position = 7,
keyName = "noJvm",
name = "Use system java (caution!)",
description = "Enable this if you want to make use of the system java version instead of the launcher bundled version",
titleSection = "advancedTitle",
warning = "Toggling this setting requires a restart of the client"
)
default boolean noJvm()
{
return false;
}
@ConfigItem(
position = 8,
keyName = "useProxy",
name = "Use SOCKS5 proxy",
description = "Enable the client to use a proxy",
titleSection = "advancedTitle",
warning = "Toggling this setting requires a restart of the client"
)
default boolean useProxy()
{
return false;
}
@ConfigItem(
keyName = "proxyDetails",
name = "Proxy details",
description = "The format for this field is ip:port or ip:port:user:pass",
titleSection = "advancedTitle",
position = 9,
hidden = true,
unhide = "useProxy"
)
default String proxyDetails()
{
return "";
}
}

View File

@@ -31,7 +31,7 @@ import lombok.Value;
/**
* Represents Discord Rich Presence RPC data
*/
@Builder
@Builder(toBuilder = true)
@Value
public class DiscordPresence
{

View File

@@ -1,7 +1,7 @@
package net.runelite.client.eventbus;
import com.google.common.collect.ImmutableSet;
import io.reactivex.functions.Consumer;
import io.reactivex.rxjava3.functions.Consumer;
import java.lang.invoke.CallSite;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;

View File

@@ -1,18 +1,18 @@
package net.runelite.client.eventbus;
import com.jakewharton.rxrelay2.PublishRelay;
import com.jakewharton.rxrelay2.Relay;
import io.reactivex.ObservableTransformer;
import io.reactivex.Scheduler;
import io.reactivex.annotations.NonNull;
import io.reactivex.annotations.Nullable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import com.jakewharton.rxrelay3.PublishRelay;
import com.jakewharton.rxrelay3.Relay;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.ObservableTransformer;
import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.sentry.Sentry;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;

View File

@@ -1,7 +1,7 @@
package net.runelite.client.eventbus;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.functions.Consumer;
import net.runelite.api.events.Event;
public interface EventBusInterface

View File

@@ -1,9 +1,9 @@
package net.runelite.client.eventbus;
import io.reactivex.Scheduler;
import io.reactivex.annotations.Nullable;
import io.reactivex.schedulers.Schedulers;
import java.util.function.Supplier;
import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.rxjava3.functions.Supplier;
import io.reactivex.rxjava3.schedulers.Schedulers;
import javax.annotation.Nullable;
import lombok.AllArgsConstructor;
@AllArgsConstructor
@@ -22,6 +22,14 @@ public enum EventScheduler
@Nullable
public Scheduler get()
{
return scheduler.get();
try
{
return scheduler.get();
}
catch (Throwable ignored)
{
}
return null;
}
}

View File

@@ -1,6 +1,6 @@
package net.runelite.client.eventbus;
import io.reactivex.functions.Consumer;
import io.reactivex.rxjava3.functions.Consumer;
import lombok.Value;
@Value

View File

@@ -28,8 +28,8 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import io.reactivex.Completable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

View File

@@ -27,8 +27,8 @@ package net.runelite.client.game;
import com.google.common.collect.ImmutableMap;
import com.google.gson.stream.JsonReader;
import io.reactivex.Completable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

View File

@@ -28,11 +28,14 @@ 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.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import javax.inject.Singleton;
import lombok.Getter;
import lombok.Value;
import net.runelite.api.Client;
import net.runelite.api.ItemDefinition;
import net.runelite.api.widgets.ItemQuantityMode;
@@ -66,6 +69,14 @@ public class ChatboxItemSearch extends ChatboxTextInput
@Getter
private Consumer<Integer> onItemSelected;
@Value
private static class ItemIcon
{
private final int modelId;
private final short[] colorsToReplace;
private final short[] texturesToReplace;
}
@Inject
private ChatboxItemSearch(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread,
ItemManager itemManager, Client client)
@@ -287,15 +298,26 @@ public class ChatboxItemSearch extends ChatboxTextInput
return;
}
Set<ItemIcon> itemIcons = new HashSet<>();
for (int i = 0; i < client.getItemCount() && results.size() < MAX_RESULTS; i++)
{
ItemDefinition itemComposition = itemManager.getItemDefinition(itemManager.canonicalize(i));
String name = itemComposition.getName().toLowerCase();
// The client assigns "null" to item names of items it doesn't know about
if (!name.equals("null") && name.contains(search))
// and the item might already be in the results from canonicalize
if (!name.equals("null") && name.contains(search) && !results.containsKey(itemComposition.getId()))
{
// This may already be in the map due to canonicalize mapping the item to something we've already seen
results.putIfAbsent(itemComposition.getId(), itemComposition);
// Check if the results already contain the same item image
ItemIcon itemIcon = new ItemIcon(itemComposition.getInventoryModel(),
itemComposition.getColorToReplaceWith(), itemComposition.getTextureToReplaceWith());
if (itemIcons.contains(itemIcon))
{
continue;
}
itemIcons.add(itemIcon);
results.put(itemComposition.getId(), itemComposition);
}
}
}

View File

@@ -17,6 +17,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -49,7 +50,9 @@ import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.ExternalPluginChanged;
import net.runelite.client.events.ExternalRepositoryChanged;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.RuneLiteSplashScreen;
import net.runelite.client.util.MiscUtils;
import net.runelite.client.util.SwingUtil;
import org.pf4j.DefaultPluginManager;
import org.pf4j.DependencyResolver;
@@ -77,7 +80,7 @@ class ExternalPluginManager
{
public static ArrayList<ClassLoader> pluginClassLoaders = new ArrayList<>();
private final PluginManager runelitePluginManager;
private final org.pf4j.PluginManager externalPluginManager;
private org.pf4j.PluginManager externalPluginManager;
@Getter(AccessLevel.PUBLIC)
private final List<UpdateRepository> repositories = new ArrayList<>();
private final OpenOSRSConfig openOSRSConfig;
@@ -85,7 +88,6 @@ class ExternalPluginManager
private final ConfigManager configManager;
private final List<Plugin> plugins = new CopyOnWriteArrayList<>();
private final Map<String, String> pluginsMap = new HashMap<>();
@Getter(AccessLevel.PUBLIC)
private UpdateManager updateManager;
@@ -104,9 +106,16 @@ class ExternalPluginManager
//noinspection ResultOfMethodCallIgnored
EXTERNALPLUGIN_DIR.mkdirs();
initPluginManager();
}
private void initPluginManager()
{
boolean debug = RuneLiteProperties.getLauncherVersion() == null && RuneLiteProperties.getPluginPath() != null;
this.externalPluginManager = new DefaultPluginManager(debug ? Paths.get(RuneLiteProperties.getPluginPath() + File.separator + "release") : EXTERNALPLUGIN_DIR.toPath())
this.externalPluginManager = new DefaultPluginManager(
debug ? Paths.get(RuneLiteProperties.getPluginPath() + File.separator + "release")
: EXTERNALPLUGIN_DIR.toPath())
{
@Override
protected PluginDescriptorFinder createPluginDescriptorFinder()
@@ -117,7 +126,27 @@ class ExternalPluginManager
@Override
protected PluginRepository createPluginRepository()
{
return new JarPluginRepository(getPluginsRoot());
return new JarPluginRepository(getPluginsRoot())
{
@Override
public List<Path> getPluginPaths()
{
File[] files = pluginsRoot.toFile().listFiles(filter);
if ((files == null) || files.length == 0)
{
return Collections.emptyList();
}
List<Path> paths = new ArrayList<>(files.length);
for (File file : files)
{
paths.add(file.toPath());
}
return paths;
}
};
}
@Override
@@ -184,22 +213,41 @@ class ExternalPluginManager
this.externalPluginManager.setSystemVersion(SYSTEM_VERSION);
}
public boolean doesGhRepoExist(String owner, String name)
{
return doesRepoExist("gh:" + owner + "/" + name);
}
/**
* Note that {@link org.pf4j.update.UpdateManager#addRepository} checks if the repo exists, however it throws an exception which is bad
*/
public boolean doesRepoExist(String id)
{
return repositories.stream().anyMatch((repo) -> repo.getId().equals(id));
}
private static URL toRepositoryUrl(String owner, String name) throws MalformedURLException
{
return new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/");
}
public static boolean testRepository(String owner, String name)
public static boolean testGHRepository(String owner, String name)
{
final List<UpdateRepository> repositories = new ArrayList<>();
try
{
repositories.add(new DefaultUpdateRepository("github", new URL("https://raw.githubusercontent.com/" + owner + "/" + name + "/master/")));
return testRepository(toRepositoryUrl(owner, name));
}
catch (MalformedURLException e)
{
return true;
e.printStackTrace();
}
return false;
}
public static boolean testRepository(URL url)
{
final List<UpdateRepository> repositories = new ArrayList<>();
repositories.add(new DefaultUpdateRepository("repository-testing", url));
DefaultPluginManager testPluginManager = new DefaultPluginManager(EXTERNALPLUGIN_DIR.toPath());
UpdateManager updateManager = new UpdateManager(testPluginManager, repositories);
@@ -238,9 +286,63 @@ class ExternalPluginManager
}
public void startExternalUpdateManager()
{
if (!tryLoadNewFormat())
{
loadOldFormat();
}
this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
saveConfig();
}
public boolean tryLoadNewFormat()
{
try
{
for (String keyval : openOSRSConfig.getExternalRepositories().split(";"))
{
String[] split = keyval.split("\\|");
if (split.length != 2)
{
repositories.clear();
return false;
}
String id = split[0];
String url = split[1];
if (!url.endsWith("/"))
{
url = url.concat("/");
}
if (id.contains("https://raw.githubusercontent.com/"))
{
id = "gh:" + id.substring(id.indexOf("https://raw.githubusercontent.com/")).replace("/master", "")
.replace("https://raw.githubusercontent.com/", "");
if (id.endsWith("/"))
{
id = id.substring(0, id.lastIndexOf("/"));
}
}
repositories.add(new DefaultUpdateRepository(id, new URL(url)));
}
}
catch (ArrayIndexOutOfBoundsException | MalformedURLException e)
{
repositories.clear();
return false;
}
return true;
}
public void loadOldFormat()
{
try
{
repositories.clear();
for (String keyval : openOSRSConfig.getExternalRepositories().split(";"))
{
String id = keyval.substring(0, keyval.lastIndexOf(":https"));
@@ -262,14 +364,11 @@ class ExternalPluginManager
this.updateManager = new UpdateManager(this.externalPluginManager, repositories);
}
public void addRepository(String owner, String name)
public void addGHRepository(String owner, String name)
{
try
{
DefaultUpdateRepository respository = new DefaultUpdateRepository(owner + toRepositoryUrl(owner, name), toRepositoryUrl(owner, name));
updateManager.addRepository(respository);
eventBus.post(ExternalRepositoryChanged.class, new ExternalRepositoryChanged(owner + toRepositoryUrl(owner, name), true));
saveConfig();
addRepository("gh:" + owner + "/" + name, toRepositoryUrl(owner, name));
}
catch (MalformedURLException e)
{
@@ -277,6 +376,14 @@ class ExternalPluginManager
}
}
public void addRepository(String key, URL url)
{
DefaultUpdateRepository respository = new DefaultUpdateRepository(key, url);
updateManager.addRepository(respository);
eventBus.post(ExternalRepositoryChanged.class, new ExternalRepositoryChanged(key, true));
saveConfig();
}
public void removeRepository(String owner)
{
updateManager.removeRepository(owner);
@@ -291,8 +398,8 @@ class ExternalPluginManager
for (UpdateRepository repository : updateManager.getRepositories())
{
config.append(repository.getId());
config.append(":");
config.append(repository.getUrl().toString());
config.append("|");
config.append(MiscUtils.urlToStringEncoded(repository.getUrl()));
config.append(";");
}
config.deleteCharAt(config.lastIndexOf(";"));
@@ -333,7 +440,8 @@ class ExternalPluginManager
}
else if (pluginDescriptor.type() == PluginType.EXTERNAL)
{
log.error("Class {} is using the the new external plugin loader, it should not use PluginType.EXTERNAL", clazz);
log.error("Class {} is using the the new external plugin loader, it should not use PluginType.EXTERNAL",
clazz);
continue;
}
@@ -373,16 +481,21 @@ class ExternalPluginManager
}
@SuppressWarnings("unchecked")
private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz, boolean init, boolean initConfig) throws PluginInstantiationException
private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz, boolean init, boolean initConfig)
throws PluginInstantiationException
{
net.runelite.client.plugins.PluginDependency[] pluginDependencies = clazz.getAnnotationsByType(net.runelite.client.plugins.PluginDependency.class);
net.runelite.client.plugins.PluginDependency[] pluginDependencies =
clazz.getAnnotationsByType(net.runelite.client.plugins.PluginDependency.class);
List<Plugin> deps = new ArrayList<>();
for (net.runelite.client.plugins.PluginDependency pluginDependency : pluginDependencies)
{
Optional<Plugin> dependency = Stream.concat(runelitePluginManager.getPlugins().stream(), scannedPlugins.stream()).filter(p -> p.getClass() == pluginDependency.value()).findFirst();
Optional<Plugin> dependency =
Stream.concat(runelitePluginManager.getPlugins().stream(), scannedPlugins.stream())
.filter(p -> p.getClass() == pluginDependency.value()).findFirst();
if (!dependency.isPresent())
{
throw new PluginInstantiationException("Unmet dependency for " + clazz.getSimpleName() + ": " + pluginDependency.value().getSimpleName());
throw new PluginInstantiationException(
"Unmet dependency for " + clazz.getSimpleName() + ": " + pluginDependency.value().getSimpleName());
}
deps.add(dependency.get());
}
@@ -444,7 +557,9 @@ class ExternalPluginManager
{
runelitePluginManager.startPlugin(plugin);
runelitePluginManager.add(plugin);
eventBus.post(ExternalPluginChanged.class, new ExternalPluginChanged(pluginsMap.get(plugin.getClass().getSimpleName()), plugin, true));
eventBus.post(ExternalPluginChanged.class,
new ExternalPluginChanged(pluginsMap.get(plugin.getClass().getSimpleName()), plugin,
true));
}
catch (PluginInstantiationException e)
{
@@ -479,6 +594,21 @@ class ExternalPluginManager
for (PluginWrapper plugin : startedPlugins)
{
boolean depsLoaded = true;
for (PluginDependency dependency : plugin.getDescriptor().getDependencies())
{
if (startedPlugins.stream().noneMatch(pl -> pl.getPluginId().equals(dependency.getPluginId())))
{
depsLoaded = false;
}
}
if (!depsLoaded)
{
// This should never happen but can crash the client
continue;
}
scannedPlugins.addAll(loadPlugin(plugin.getPluginId()));
}
@@ -630,7 +760,7 @@ class ExternalPluginManager
try
{
SwingUtil.syncExec(() ->
JOptionPane.showMessageDialog(null,
JOptionPane.showMessageDialog(ClientUI.getFrame(),
pluginId + " is outdated and cannot be installed",
"Installation error",
JOptionPane.ERROR_MESSAGE));
@@ -678,6 +808,7 @@ class ExternalPluginManager
public void update()
{
boolean error = false;
if (updateManager.hasUpdates())
{
List<PluginInfo> updates = updateManager.getUpdates();
@@ -692,14 +823,24 @@ class ExternalPluginManager
if (!updated)
{
log.warn("Cannot update plugin '{}'", plugin.id);
error = true;
}
}
catch (PluginRuntimeException ex)
{
log.warn("Cannot update plugin '{}', the user probably has another client open", plugin.id);
error = true;
break;
}
}
}
if (error)
{
initPluginManager();
startExternalUpdateManager();
startExternalPluginManager();
}
}
public Set<String> getDependencies()

View File

@@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.inject.Binder;
import com.google.inject.Injector;
import com.google.inject.Module;
import io.reactivex.functions.Consumer;
import io.reactivex.rxjava3.functions.Consumer;
import java.lang.reflect.Method;
import java.util.Set;
import lombok.AccessLevel;

View File

@@ -53,8 +53,6 @@ public @interface PluginDescriptor
*/
boolean hidden() default false;
boolean developerPlugin() default false;
boolean loadWhenOutdated() default false;
PluginType type() default PluginType.UNCATEGORIZED;

View File

@@ -56,7 +56,6 @@ import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.swing.SwingUtilities;
@@ -87,7 +86,6 @@ public class PluginManager
*/
private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins";
private final boolean developerMode;
private final EventBus eventBus;
private final Scheduler scheduler;
private final ConfigManager configManager;
@@ -108,13 +106,11 @@ public class PluginManager
@Inject
@VisibleForTesting
PluginManager(
@Named("developerMode") final boolean developerMode,
final EventBus eventBus,
final Scheduler scheduler,
final ConfigManager configManager,
final Provider<GameEventManager> sceneTileManager)
{
this.developerMode = developerMode;
this.eventBus = eventBus;
this.scheduler = scheduler;
this.configManager = configManager;
@@ -355,11 +351,6 @@ public class PluginManager
continue;
}
if (pluginDescriptor.developerPlugin() && !developerMode)
{
continue;
}
@SuppressWarnings("unchecked") Class<Plugin> pluginClass = (Class<Plugin>) clazz;
graph.addNode(pluginClass);
}
@@ -462,10 +453,12 @@ public class PluginManager
}
catch (ThreadDeath e)
{
activePlugins.remove(plugin);
throw e;
}
catch (Throwable ex)
{
activePlugins.remove(plugin);
throw new PluginInstantiationException(ex);
}

View File

@@ -41,7 +41,6 @@ import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
@@ -672,11 +671,7 @@ class ConfigPanel extends PluginPanel
if (units != null)
{
DecimalFormat df = ((JSpinner.NumberEditor) spinner.getEditor()).getFormat();
df.setPositiveSuffix(units.value());
df.setNegativeSuffix(units.value());
// Force update the spinner to have it add the units initially
spinnerTextField.setValue(value);
spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
}
item.add(spinner, BorderLayout.EAST);
@@ -812,11 +807,7 @@ class ConfigPanel extends PluginPanel
if (units != null)
{
DecimalFormat df = ((JSpinner.NumberEditor) widthSpinner.getEditor()).getFormat();
df.setPositiveSuffix(units.value());
df.setNegativeSuffix(units.value());
// Force update the spinner to have it add the units initially
widthSpinnerTextField.setValue(width);
widthSpinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
}
SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1);
@@ -827,11 +818,7 @@ class ConfigPanel extends PluginPanel
if (units != null)
{
DecimalFormat df = ((JSpinner.NumberEditor) heightSpinner.getEditor()).getFormat();
df.setPositiveSuffix(units.value());
df.setNegativeSuffix(units.value());
// Force update the spinner to have it add the units initially
heightSpinnerTextField.setValue(height);
heightSpinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
}
ChangeListener listener = e ->

View File

@@ -24,13 +24,16 @@
*/
package net.runelite.client.plugins.config;
import com.github.zafarkhaja.semver.Version;
import java.awt.image.BufferedImage;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.swing.SwingUtilities;
import net.runelite.api.MenuOpcode;
import net.runelite.client.RuneLiteProperties;
import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.LauncherConfig;
import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.Subscribe;
@@ -69,6 +72,9 @@ public class ConfigPlugin extends Plugin
@Inject
private ChatColorConfig chatColorConfig;
@Inject
private LauncherConfig launcherConfig;
private PluginListPanel pluginListPanel;
private NavigationButton navButton;
@@ -92,6 +98,18 @@ public class ConfigPlugin extends Plugin
"Chat Color", "Recolor chat text", PluginType.MISCELLANEOUS, new String[]{"colour", "messages"},
null, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig)
));
// Support for this has been added in launcher version 2.2.0
if (launcherVersion("2.2.0"))
{
pluginListPanel.addFakePlugin(
new PluginConfigurationDescriptor(
"Launcher", "Launcher settings", PluginType.IMPORTANT,
new String[]{"hw", "nightly", "stable", "proxy", "bootstrap"},
null, launcherConfig, configManager.getConfigDescriptor(launcherConfig)
));
}
pluginListPanel.rebuildPluginList();
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "config_icon.png");
@@ -137,4 +155,16 @@ public class ConfigPlugin extends Plugin
});
}
}
private boolean launcherVersion(String version)
{
String launcherVersion = RuneLiteProperties.getLauncherVersion();
if (launcherVersion == null)
{
return false;
}
return Version.valueOf(launcherVersion).greaterThanOrEqualTo(Version.valueOf(version));
}
}

View File

@@ -45,12 +45,9 @@ import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil;
import org.apache.commons.text.similarity.JaroWinklerDistance;
public class PluginListItem extends JPanel
{
private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance();
private static final ImageIcon CONFIG_ICON;
private static final ImageIcon CONFIG_ICON_HOVER;
private static final ImageIcon ON_STAR;
@@ -61,6 +58,7 @@ public class PluginListItem extends JPanel
@Getter
private final PluginConfigurationDescriptor pluginConfig;
@Getter
private final List<String> keywords = new ArrayList<>();
public JLabel nameLabel;
@@ -201,24 +199,6 @@ public class PluginListItem extends JPanel
onOffToggle.setSelected(enabled);
}
/**
* Checks if all the search terms in the given list matches at least one keyword.
*
* @return true if all search terms matches at least one keyword, or false if otherwise.
*/
boolean matchesSearchTerms(String[] searchTerms)
{
for (String term : searchTerms)
{
if (keywords.stream().noneMatch((t) -> t.contains(term) ||
DISTANCE.apply(t, term) > 0.9))
{
return false;
}
}
return true;
}
private void openGroupConfigPanel()
{
pluginListPanel.openConfigurationPanel(pluginConfig);

View File

@@ -381,7 +381,7 @@ public class PluginListPanel extends PluginPanel
final String[] searchTerms = text.toLowerCase().split(" ");
pluginList.forEach(listItem ->
{
if (pinned == listItem.isPinned() && listItem.matchesSearchTerms(searchTerms))
if (pinned == listItem.isPinned() && Text.matchesSearchTerms(searchTerms, listItem.getKeywords()))
{
if (openOSRSConfig.pluginSortMode() == OpenOSRSConfig.SortStyle.ALPHABETICALLY || !openOSRSConfig.enableCategories())
{

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2020, Hydrox6 <ikada@protonmail.ch>
* 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.config;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFormattedTextField;
import lombok.RequiredArgsConstructor;
import net.runelite.client.config.Units;
final class UnitFormatter extends JFormattedTextField.AbstractFormatter
{
private final String units;
UnitFormatter(Units units)
{
this.units = units.value();
}
@Override
public Object stringToValue(final String text) throws ParseException
{
final String trimmedText;
// Using the spinner controls causes the value to have the unit on the end, so remove it
if (text.endsWith(units))
{
trimmedText = text.substring(0, text.length() - units.length());
}
else
{
trimmedText = text;
}
try
{
return Integer.valueOf(trimmedText);
}
catch (NumberFormatException e)
{
throw new ParseException(trimmedText + " is not an integer.", 0);
}
}
@Override
public String valueToString(final Object value)
{
return value + units;
}
}
@RequiredArgsConstructor
final class UnitFormatterFactory extends JFormattedTextField.AbstractFormatterFactory
{
private final Units units;
private final Map<JFormattedTextField, JFormattedTextField.AbstractFormatter> formatters = new HashMap<>();
@Override
public JFormattedTextField.AbstractFormatter getFormatter(final JFormattedTextField tf)
{
return formatters.computeIfAbsent(tf, (key) -> new UnitFormatter(units));
}
}

View File

@@ -79,11 +79,14 @@ class InfoPanel extends PluginPanel
}
private JPanel syncPanel;
@Inject
@Nullable
private Client client;
@Inject
private ConfigManager configManager;
@Inject
private InfoPlugin plugin;
@@ -104,8 +107,12 @@ class InfoPanel extends PluginPanel
JLabel version = new JLabel(htmlLabel("RuneLite version: ", RuneLiteProperties.getVersion()));
version.setFont(smallFont);
JLabel plusVersion = new JLabel(htmlLabel("OpenOSRS version: ", RuneLiteProperties.getPlusVersion()));
plusVersion.setFont(smallFont);
JLabel openOsrsVersion = new JLabel(htmlLabel("OpenOSRS version: ", RuneLiteProperties.getPlusVersion()));
openOsrsVersion.setFont(smallFont);
String launcher = RuneLiteProperties.getLauncherVersion();
JLabel launcherVersion = new JLabel(htmlLabel("Launcher version: ", launcher));
launcherVersion.setFont(smallFont);
JLabel revision = new JLabel();
revision.setFont(smallFont);
@@ -119,7 +126,11 @@ class InfoPanel extends PluginPanel
revision.setText(htmlLabel("Oldschool revision: ", engineVer));
versionPanel.add(version);
versionPanel.add(plusVersion);
versionPanel.add(openOsrsVersion);
if (launcher != null)
{
versionPanel.add(launcherVersion);
}
versionPanel.add(revision);
JPanel actionsContainer = new JPanel();

View File

@@ -6,6 +6,8 @@ import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import javax.swing.ImageIcon;
@@ -18,23 +20,28 @@ import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.ExternalPluginManager;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.util.ImageUtil;
public class ExternalPluginManagerPanel extends PluginPanel
{
private static final ImageIcon ADD_ICON;
private static final ImageIcon ADD_HOVER_ICON;
private static final ImageIcon ADD_ICON_RAW;
private static final ImageIcon ADD_HOVER_ICON_RAW;
private static final ImageIcon ADD_ICON_GH;
private static final ImageIcon ADD_HOVER_ICON_GH;
static
{
final BufferedImage addIcon =
ImageUtil.recolorImage(
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_icon.png"), ColorScheme.BRAND_BLUE
);
ADD_ICON = new ImageIcon(addIcon);
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
final BufferedImage addIconRaw =
ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "add_raw_icon.png");
final BufferedImage addIconGh = ImageUtil
.resizeImage(ImageUtil.getResourceStreamFromClass(ExternalPluginManagerPanel.class, "gh_icon.png"), 14, 14);
ADD_ICON_RAW = new ImageIcon(addIconRaw);
ADD_HOVER_ICON_RAW = new ImageIcon(ImageUtil.alphaOffset(addIconRaw, 0.53f));
ADD_ICON_GH = new ImageIcon(addIconGh);
ADD_HOVER_ICON_GH = new ImageIcon(ImageUtil.alphaOffset(addIconGh, 0.53f));
}
private final ExternalPluginManager externalPluginManager;
@@ -73,13 +80,17 @@ public class ExternalPluginManagerPanel extends PluginPanel
titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
JLabel title = new JLabel();
JLabel addRepo = new JLabel(ADD_ICON);
JLabel addGHRepo = new JLabel(ADD_ICON_GH);
JLabel addRawRepo = new JLabel(ADD_ICON_RAW);
JPanel buttonHolder = new JPanel(new BorderLayout());
buttonHolder.setBorder(new EmptyBorder(0, 0, 0, 0));
title.setText("External Plugin Manager");
title.setForeground(Color.WHITE);
addRepo.setToolTipText("Add new repository");
addRepo.addMouseListener(new MouseAdapter()
addGHRepo.setToolTipText("Add new GitHub repository");
addGHRepo.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
@@ -91,36 +102,120 @@ public class ExternalPluginManagerPanel extends PluginPanel
"Github Repository name:", name
};
int option = JOptionPane.showConfirmDialog(null, message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
int option =
JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
if (option != JOptionPane.OK_OPTION || owner.getText().equals("") || name.getText().equals(""))
{
return;
}
if (ExternalPluginManager.testRepository(owner.getText(), name.getText()))
if (externalPluginManager.doesGhRepoExist(owner.getText(), name.getText()))
{
JOptionPane.showMessageDialog(null, "This doesn't appear to be a valid repository.", "Error!", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This repository already exists.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
externalPluginManager.addRepository(owner.getText(), name.getText());
if (ExternalPluginManager.testGHRepository(owner.getText(), name.getText()))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
externalPluginManager.addGHRepository(owner.getText(), name.getText());
}
@Override
public void mouseEntered(MouseEvent mouseEvent)
{
addRepo.setIcon(ADD_HOVER_ICON);
addGHRepo.setIcon(ADD_HOVER_ICON_GH);
}
@Override
public void mouseExited(MouseEvent mouseEvent)
{
addRepo.setIcon(ADD_ICON);
addGHRepo.setIcon(ADD_ICON_GH);
}
});
addGHRepo.setBorder(new EmptyBorder(0, 3, 0, 0));
addRawRepo.setToolTipText("Add new raw repository");
addRawRepo.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
JTextField id = new JTextField();
JTextField url = new JTextField();
Object[] message = {
"Repository ID:", id,
"Repository URL:", url
};
int option =
JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Add repository", JOptionPane.OK_CANCEL_OPTION);
if (option != JOptionPane.OK_OPTION || id.getText().equals("") || url.getText().equals(""))
{
return;
}
if (id.getText().startsWith("gh:") || id.getText().contains("|"))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(),
"Repository id cannot begin with \"gh:\"\nor contain the pipe character '|'.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (externalPluginManager.doesRepoExist(id.getText()))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(),
String.format("The repository with id %s already exists.", id.getText()), "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
URL urlActual;
try
{
urlActual = new URL(url.getText());
}
catch (MalformedURLException e)
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (ExternalPluginManager.testRepository(urlActual))
{
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This doesn't appear to be a valid repository.", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
externalPluginManager.addRepository(id.getText(), urlActual);
}
@Override
public void mouseEntered(MouseEvent mouseEvent)
{
addRawRepo.setIcon(ADD_HOVER_ICON_RAW);
}
@Override
public void mouseExited(MouseEvent mouseEvent)
{
addRawRepo.setIcon(ADD_ICON_RAW);
}
});
addRawRepo.setBorder(new EmptyBorder(0, 0, 0, 3));
titlePanel.add(title, BorderLayout.WEST);
titlePanel.add(addRepo, BorderLayout.EAST);
buttonHolder.add(addRawRepo, BorderLayout.WEST);
buttonHolder.add(addGHRepo, BorderLayout.EAST);
titlePanel.add(buttonHolder, BorderLayout.EAST);
return titlePanel;
}

View File

@@ -30,11 +30,13 @@ import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import lombok.extern.slf4j.Slf4j;
import static net.runelite.api.util.Text.DISTANCE;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.ExternalPluginChanged;
import net.runelite.client.events.ExternalRepositoryChanged;
import net.runelite.client.plugins.ExternalPluginManager;
import static net.runelite.client.plugins.openosrs.externals.ExternalPluginManagerPanel.wrapContainer;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.PluginPanel;
@@ -43,7 +45,6 @@ import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
import net.runelite.client.util.DeferredDocumentChangedListener;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil;
import org.apache.commons.text.similarity.JaroWinklerDistance;
import org.pf4j.update.PluginInfo;
import org.pf4j.update.UpdateManager;
import org.pf4j.update.UpdateRepository;
@@ -52,7 +53,6 @@ import org.pf4j.update.VerifyException;
@Slf4j
public class PluginsPanel extends JPanel
{
private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance();
private static final ImageIcon ADD_ICON;
private static final ImageIcon ADD_HOVER_ICON;
private static final ImageIcon DELETE_ICON;
@@ -257,7 +257,7 @@ public class PluginsPanel extends JPanel
if (availablePlugins == null || plugins == null)
{
JOptionPane.showMessageDialog(null, "The external plugin list could not be loaded.", "Error", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(ClientUI.getFrame(), "The external plugin list could not be loaded.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
@@ -465,7 +465,7 @@ public class PluginsPanel extends JPanel
{
if (hideAction)
{
JOptionPane.showMessageDialog(null, "This plugin can't be uninstalled because one or more other plugins have a dependency on it.", "Error!", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(ClientUI.getFrame(), "This plugin can't be uninstalled because one or more other plugins have a dependency on it.", "Error!", JOptionPane.ERROR_MESSAGE);
}
else
{
@@ -573,7 +573,7 @@ public class PluginsPanel extends JPanel
try
{
SwingUtil.syncExec(() ->
JOptionPane.showMessageDialog(null, pluginInfo.name + " could not be installed, the hash could not be verified.", "Error!", JOptionPane.ERROR_MESSAGE));
JOptionPane.showMessageDialog(ClientUI.getFrame(), pluginInfo.name + " could not be installed, the hash could not be verified.", "Error!", JOptionPane.ERROR_MESSAGE));
}
catch (InvocationTargetException | InterruptedException ignored)
{

View File

@@ -58,8 +58,12 @@ public class RepositoryBox extends JPanel
setLayout(new BorderLayout());
setBackground(ColorScheme.DARKER_GRAY_COLOR);
String name = updateRepository.getId().replace(updateRepository.getUrl().toString(), "");
String urlString = updateRepository.getUrl().toString().replace("https://raw.githubusercontent.com/", "").replace("/master/", "");
String name = updateRepository.getId();
String urlString = updateRepository.getUrl().toString();
if (urlString.startsWith("/"))
{
urlString = urlString.substring(1);
}
JPanel titleWrapper = new JPanel(new BorderLayout());
titleWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR);
@@ -145,11 +149,31 @@ public class RepositoryBox extends JPanel
titleWrapper.add(titleActions, BorderLayout.EAST);
JMultilineLabel repository = new JMultilineLabel();
repository.setText(urlString.split("/", 2)[1]);
repository.setText(formatURL(urlString));
repository.setFont(smallFont);
repository.setDisabledTextColor(Color.WHITE);
String finalUrlString = urlString;
repository.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
LinkBrowser.browse(formatURL(finalUrlString));
}
});
add(titleWrapper, BorderLayout.NORTH);
add(repository, BorderLayout.CENTER);
}
private String formatURL(String url)
{
if (url.contains("githubusercontent"))
{
url = url.replace("raw.githubusercontent", "github").replace("/master/", "");
}
return url;
}
}

View File

@@ -29,7 +29,6 @@ import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.annotation.Nullable;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import net.runelite.api.Client;
@@ -65,13 +64,13 @@ final class ClientPanel extends JPanel
{
String message = "Detected a bad codebase. Resetting...\n"
+ "Please restart client.\n";
JOptionPane.showMessageDialog(new JFrame(), message, "Bad Codebase",
JOptionPane.showMessageDialog(ClientUI.getFrame(), message, "Bad Codebase",
JOptionPane.ERROR_MESSAGE);
StringFileUtils.writeStringToFile(RuneLite.RUNELITE_DIR + "/codebase", "http://127.0.0.1/");
}
else
{
JOptionPane.showMessageDialog(new JFrame(), "Error loading Oldschool RuneScape!", "Error",
JOptionPane.showMessageDialog(ClientUI.getFrame(), "Error loading Oldschool RuneScape!", "Error",
JOptionPane.ERROR_MESSAGE);
Sentry.capture(e);
}

View File

@@ -667,7 +667,7 @@ public class ClientUI
return;
}
final java.awt.Point hotspot = new java.awt.Point(container.getX(), container.getY());
final java.awt.Point hotspot = new java.awt.Point(0, 0);
final Cursor cursorAwt = Toolkit.getDefaultToolkit().createCustomCursor(image, hotspot, name);
container.setCursor(cursorAwt);
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright (c) 2018, Shingyx <https://github.com/Shingyx>
* 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.ui.components;
import java.awt.Component;
import java.awt.Container;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.dnd.DragSource;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BoxLayout;
import javax.swing.JLayeredPane;
/**
* Pane which allows reordering its components via drag and drop.
* <p>
* For child components' popup menus, implement the PopupMenuOwner interface in the child components.
*/
public class DragAndDropReorderPane extends JLayeredPane
{
private Point dragStartPoint;
private Component draggingComponent;
private int dragIndex = -1;
private final Map<Integer, PopupMenuOwner> popupMenuCandidates = new HashMap<>(); // keyed by mouse button
public DragAndDropReorderPane()
{
super();
setLayout(new DragAndDropReorderLayoutManager());
MouseAdapter mouseAdapter = new DragAndDropReorderMouseAdapter();
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
}
@Override
public void setLayout(LayoutManager layoutManager)
{
if (layoutManager != null && !(layoutManager instanceof DragAndDropReorderLayoutManager))
{
throw new IllegalArgumentException("DragAndDropReorderPane only supports DragAndDropReorderLayoutManager");
}
super.setLayout(layoutManager);
}
private void startDragging(Point point)
{
draggingComponent = getDefaultLayerComponentAt(dragStartPoint);
if (draggingComponent == null)
{
dragStartPoint = null;
return;
}
dragIndex = getPosition(draggingComponent);
setLayer(draggingComponent, DRAG_LAYER);
moveDraggingComponent(point);
}
private void drag(Point point)
{
moveDraggingComponent(point);
Component component = getDefaultLayerComponentAt(point);
if (component != null)
{
int index = getPosition(component);
dragIndex = index < dragIndex ? index : index + 1;
revalidate();
}
}
private void finishDragging()
{
if (draggingComponent != null)
{
setLayer(draggingComponent, DEFAULT_LAYER, dragIndex);
revalidate();
}
dragStartPoint = null;
draggingComponent = null;
dragIndex = -1;
}
private void moveDraggingComponent(Point point)
{
// place the center of the dragging component onto the mouse cursor
int y = point.y - draggingComponent.getHeight() / 2;
// clamp the height to stay within the pane
y = Math.max(y, 0);
y = Math.min(y, getHeight() - draggingComponent.getHeight());
draggingComponent.setLocation(new Point(0, y));
}
private Component getDefaultLayerComponentAt(Point point)
{
for (Component component : getComponentsInLayer(DEFAULT_LAYER))
{
if (component.contains(point.x - component.getX(), point.y - component.getY()))
{
return component;
}
}
return null;
}
private class DragAndDropReorderLayoutManager extends BoxLayout
{
private DragAndDropReorderLayoutManager()
{
super(DragAndDropReorderPane.this, BoxLayout.Y_AXIS);
}
@Override
public void layoutContainer(Container target)
{
if (draggingComponent != null)
{
// temporarily move the dragging component to the default layer for correct layout calculation
Point location = draggingComponent.getLocation();
setLayer(draggingComponent, DEFAULT_LAYER, dragIndex);
super.layoutContainer(target);
setLayer(draggingComponent, DRAG_LAYER);
draggingComponent.setLocation(location);
}
else
{
super.layoutContainer(target);
}
}
}
private class DragAndDropReorderMouseAdapter extends MouseAdapter
{
@Override
public void mousePressed(MouseEvent e)
{
Point point = e.getPoint();
int mouseButton = e.getButton();
if (mouseButton == MouseEvent.BUTTON1)
{
// candidate for dragging
if (popupMenuCandidates.isEmpty() && getComponentCount() > 1)
{
dragStartPoint = point;
}
}
else
{
if (dragStartPoint != null)
{
finishDragging();
}
else
{
// candidate for child popup menu
Component component = getDefaultLayerComponentAt(point);
if (component instanceof PopupMenuOwner)
{
PopupMenuOwner popupMenuCandidate = (PopupMenuOwner) component;
if (e.isPopupTrigger())
{
popupMenuCandidate.getPopupMenu().show(DragAndDropReorderPane.this, point.x, point.y);
}
else
{
popupMenuCandidates.put(mouseButton, popupMenuCandidate);
}
}
}
}
}
@Override
public void mouseDragged(MouseEvent e)
{
if (dragStartPoint == null)
{
return;
}
Point point = e.getPoint();
if (contains(point))
{
if (draggingComponent == null)
{
if (point.distance(dragStartPoint) > DragSource.getDragThreshold())
{
startDragging(point);
}
}
else
{
drag(point);
}
}
else
{
finishDragging();
}
}
@Override
public void mouseReleased(MouseEvent e)
{
Point point = e.getPoint();
int mouseButton = e.getButton();
if (mouseButton == MouseEvent.BUTTON1)
{
finishDragging();
}
else
{
PopupMenuOwner popupMenuCandidate = popupMenuCandidates.remove(mouseButton);
if (popupMenuCandidate != null && e.isPopupTrigger())
{
popupMenuCandidate.getPopupMenu().show(DragAndDropReorderPane.this, point.x, point.y);
}
}
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018, Shingyx <https://github.com/Shingyx>
* 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.ui.components;
import javax.swing.JPopupMenu;
/**
* Represents a UI component which has a popup menu, to be used on child components inside DragAndDropReorderPane.
* This is because using setComponentPopupMenu consumes the MouseEvents required for drag and drop reordering.
*/
public interface PopupMenuOwner
{
JPopupMenu getPopupMenu();
}

View File

@@ -63,6 +63,7 @@ public class WidgetOverlay extends Overlay
.put(WidgetInfo.LMS_INFO, OverlayPosition.TOP_CENTER)
.put(WidgetInfo.LMS_KDA, OverlayPosition.TOP_CENTER)
.put(WidgetInfo.THEATRE_OF_BLOOD_HEALTH_ORBS, OverlayPosition.TOP_LEFT)
.put(WidgetInfo.GAUNTLET_TIMER_CONTAINER, OverlayPosition.TOP_LEFT)
.build();
public static Collection<WidgetOverlay> createOverlays(final Client client)

View File

@@ -44,7 +44,6 @@ import net.runelite.client.ui.overlay.components.TooltipComponent;
public class TooltipOverlay extends Overlay
{
private static final int UNDER_OFFSET = 24;
private static final int ABOVE_OFFSET = -20;
private static final int PADDING = 2;
private final TooltipManager tooltipManager;
private final Client client;
@@ -84,50 +83,28 @@ public class TooltipOverlay extends Overlay
private Dimension renderTooltips(Graphics2D graphics, List<Tooltip> tooltips)
{
final Rectangle clientCanvasBounds = new Rectangle(client.getRealDimensions());
final int canvasWidth = client.getCanvasWidth();
final int canvasHeight = client.getCanvasHeight();
final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
final int offset = runeLiteConfig.tooltipPosition() == TooltipPositionType.UNDER_CURSOR ? UNDER_OFFSET : ABOVE_OFFSET;
final Point mousePosition = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + offset);
final Rectangle bounds = new Rectangle(getBounds());
bounds.setLocation(mousePosition);
final Rectangle prevBounds = getBounds();
if (!clientCanvasBounds.contains(bounds))
{
final int clientX = (int) clientCanvasBounds.getMaxX();
final int clientY = (int) clientCanvasBounds.getMaxY();
final int boundsX = (int) bounds.getMaxX();
final int boundsY = (int) bounds.getMaxY();
final int tooltipX = Math.min(canvasWidth - prevBounds.width, mouseCanvasPosition.getX());
final int tooltipY = runeLiteConfig.tooltipPosition() == TooltipPositionType.ABOVE_CURSOR
? Math.max(0, mouseCanvasPosition.getY() - prevBounds.height)
: Math.min(canvasHeight - prevBounds.height, mouseCanvasPosition.getY() + UNDER_OFFSET);
if (boundsY > clientY)
{
graphics.translate(0, -bounds.height - offset);
}
if (boundsX > clientX)
{
graphics.translate(-bounds.width + clientCanvasBounds.width - bounds.x, 0);
}
}
final Rectangle newBounds = new Rectangle(-1, -1, 0, 0);
final Rectangle newBounds = new Rectangle(tooltipX, tooltipY, 0, 0);
for (Tooltip tooltip : tooltips)
{
final TooltipComponent tooltipComponent = new TooltipComponent();
tooltipComponent.setModIcons(client.getModIcons());
tooltipComponent.setText(tooltip.getText());
tooltipComponent.setPosition(new Point(tooltipX, tooltipY + newBounds.height));
if (newBounds.contains(mousePosition))
{
mousePosition.move(mouseCanvasPosition.getX(), mouseCanvasPosition.getY() + offset + newBounds.height);
}
tooltipComponent.setPosition(mousePosition);
final Dimension dimension = tooltipComponent.render(graphics);
// Create incremental tooltip newBounds
newBounds.x = newBounds.x != -1 ? Math.min(newBounds.x, mousePosition.x) : mousePosition.x;
newBounds.y = newBounds.y != -1 ? Math.min(newBounds.y, mousePosition.y) : mousePosition.y;
newBounds.height += dimension.height + PADDING;
newBounds.width = Math.max(newBounds.width, dimension.width);
}

View File

@@ -0,0 +1,64 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 by rumatoest at github.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.runelite.client.util;
/**
* The Class AppLock.
*
* @author Vladislav Zablotsky
*/
public class AppLock
{
private static CrossLock lockInstance;
/**
* Set lock for application instance.
* Method must be run only one time at application start.
*
* @param lockId Unique lock identifiers
* @return true if succeeded
*/
public synchronized boolean lock(String lockId)
{
if (lockInstance == null)
{
lockInstance = new CrossLock("application_" + lockId);
}
return lockInstance.lock();
}
/**
* Trying to release application lock.
* Thus another application instances will be able to use lock with current ID.
*/
public synchronized void release()
{
if (lockInstance != null)
{
lockInstance.clear();
}
lockInstance = null;
}
}

View File

@@ -0,0 +1,228 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 by rumatoest at github.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.runelite.client.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import static net.runelite.client.RuneLite.RUNELITE_DIR;
/**
* Universal cross application instances locker.
* Allow you to create simple lock like object which can be used for
* different application instances. Basic idea is simple - just a simple file lock.
* <br />
* All you need is to define unique key for each lock type.
*
* @author Vladislav Zablotsky
*/
public class CrossLock
{
private static final HashMap<String, CrossLock> locks = new HashMap<>();
private final String id;
private final File fileToLock;
private FileOutputStream fileStream;
private FileChannel fileStreamChannel;
private FileLock lockOnFile;
/**
* Will create or retrieve lock instance.
* Each lock id is unique among all you instances,
* thus only one instance can acquire lock for this id.
*
* @param lockId Unique lock identifier
* @return Not null
*/
public static CrossLock get(String lockId)
{
if (locks.containsKey(lockId))
{
return locks.get(lockId);
}
else
{
synchronized (CrossLock.class)
{
if (locks.containsKey(lockId))
{
return locks.get(lockId);
}
else
{
CrossLock cl = new CrossLock(lockId);
locks.put(lockId, cl);
return cl;
}
}
}
}
/**
* Will remove lock object for specific id and release lock if any.
*
* @param lockId Unique lock identifier
*/
public static void remove(String lockId)
{
if (locks.containsKey(lockId))
{
CrossLock lock = null;
synchronized (CrossLock.class)
{
if (locks.containsKey(lockId))
{
lock = locks.remove(lockId);
}
}
if (lock != null)
{
lock.release();
}
}
}
CrossLock(String lockId)
{
this.id = lockId;
fileToLock = new File(RUNELITE_DIR, lockId + ".app_lock");
}
/**
* Return lock instance identifier.
*/
public String id()
{
return this.id;
}
/**
* Activate lock.
* Note! This is only cross application (cross instances) lock. It will not work
* as lock inside single application instance.
*
* @return true if lock was acquire or false
*/
public synchronized boolean lock()
{
if (lockOnFile != null && lockOnFile.isValid())
{
return true;
}
else
{
release();
}
String lockContent = "#Java AppLock Object\n#Locked by key: " + id() + "\r\n";
try
{
if (fileToLock.exists())
{
fileToLock.createNewFile();
}
fileStream = new FileOutputStream(fileToLock);
fileStreamChannel = fileStream.getChannel();
lockOnFile = fileStreamChannel.tryLock();
if (lockOnFile != null)
{
fileStream.write(lockContent.getBytes());
}
}
catch (Exception ex)
{
if (!(ex instanceof OverlappingFileLockException))
{
Logger.getLogger(AppLock.class.getName()).log(Level.WARNING,
"Can not get application lock for id=" + id() + "\n" + ex.getMessage(), ex);
}
return false;
}
return lockOnFile != null;
}
/**
* Release lock associated with this object.
*/
public synchronized void release()
{
try
{
if (lockOnFile != null && lockOnFile.isValid())
{
lockOnFile.release();
}
lockOnFile = null;
if (fileStream != null)
{
fileStream.close();
fileStream = null;
}
if (fileStreamChannel != null && fileStreamChannel.isOpen())
{
fileStreamChannel.close();
}
fileStreamChannel = null;
}
catch (IOException ex)
{
Logger.getLogger(AppLock.class.getName()).log(Level.WARNING,
"Can not get application lock for id=" + id() + "\n" + ex.getMessage(), ex);
}
}
/**
* Release lock and remove lock file.
*/
public synchronized void clear()
{
release();
if (fileToLock.exists())
{
fileToLock.delete();
}
}
@Override
protected void finalize() throws Throwable
{
this.clear();
super.finalize();
}
}

View File

@@ -24,7 +24,7 @@
*/
package net.runelite.client.util;
import io.reactivex.annotations.NonNull;
import io.reactivex.rxjava3.annotations.NonNull;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.inject.Inject;

View File

@@ -25,6 +25,7 @@
*/
package net.runelite.client.util;
import com.google.common.base.Strings;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.datatransfer.Clipboard;
@@ -40,6 +41,7 @@ import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.EnumSet;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -80,10 +82,11 @@ public class ImageCapture
*
* @param screenshot BufferedImage to capture.
* @param fileName Filename to use, without file extension.
* @param subDir Directory within the player screenshots dir to store the captured screenshot to.
* @param notify Send a notification to the system tray when the image is captured.
* @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard).
*/
public void takeScreenshot(BufferedImage screenshot, String fileName, boolean notify, ImageUploadStyle imageUploadStyle)
public void takeScreenshot(BufferedImage screenshot, String fileName, @Nullable String subDir, boolean notify, ImageUploadStyle imageUploadStyle)
{
if (client.getGameState() == GameState.LOGIN_SCREEN)
{
@@ -106,6 +109,12 @@ public class ImageCapture
{
playerDir += "-League";
}
if (!Strings.isNullOrEmpty(subDir))
{
playerDir += File.separator + subDir;
}
playerFolder = new File(SCREENSHOT_DIR, playerDir);
}
else
@@ -157,6 +166,20 @@ public class ImageCapture
}
}
/**
* Saves a screenshot of the client window to the screenshot folder as a PNG,
* and optionally uploads it to an image-hosting service.
*
* @param screenshot BufferedImage to capture.
* @param fileName Filename to use, without file extension.
* @param notify Send a notification to the system tray when the image is captured.
* @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard).
*/
public void takeScreenshot(BufferedImage screenshot, String fileName, boolean notify, ImageUploadStyle imageUploadStyle)
{
takeScreenshot(screenshot, fileName, null, notify, imageUploadStyle);
}
/**
* Uploads a screenshot to the Imgur image-hosting service,
* and copies the image link to the clipboard.

View File

@@ -36,6 +36,7 @@ import javax.inject.Singleton;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.ui.ClientUI;
/**
* Utility class used for web and file browser navigation
@@ -249,7 +250,7 @@ public class LinkBrowser
{
SwingUtilities.invokeLater(() ->
{
final int result = JOptionPane.showConfirmDialog(null, message, "Message",
final int result = JOptionPane.showConfirmDialog(ClientUI.getFrame(), message, "Message",
JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION)

View File

@@ -1,12 +1,17 @@
package net.runelite.client.util;
import java.awt.Polygon;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import net.runelite.api.Client;
import net.runelite.api.Player;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint;
import java.awt.Polygon;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MiscUtils
{
@@ -170,4 +175,28 @@ public class MiscUtils
}
return str;
}
/**
* Mostly stolen from {@link java.net.URLStreamHandler#toExternalForm(URL)}
*
* @param url URL to encode
* @return URL, with path, query and ref encoded
*/
public static String urlToStringEncoded(URL url)
{
String s;
String path = url.getPath() != null ? Stream.of(url.getPath().split("/"))
.map(s2 -> URLEncoder.encode(s2, StandardCharsets.UTF_8)).collect(Collectors.joining("/")) : "";
return url.getProtocol()
+ ':'
+ (((s = url.getAuthority()) != null && s.length() > 0) ? "//" + s : "")
+ (path)
+ (((s = url.getQuery()) != null) ? '?' + urlEncode(s) : "")
+ (((s = url.getRef()) != null) ? '#' + urlEncode(s) : "");
}
private static String urlEncode(String s)
{
return URLEncoder.encode(s, StandardCharsets.UTF_8);
}
}

View File

@@ -1401,11 +1401,13 @@
],
"coal bag": [
764,
12019
12019,
24480
],
"gem bag": [
766,
12020
12020,
24481
],
"phoenix crossbow": [
767,
@@ -7609,6 +7611,10 @@
11736,
11737
],
"herb box": [
11738,
11739
],
"armadyl crossbow": [
11785,
23611
@@ -7815,6 +7821,10 @@
11912,
11914
],
"slice of birthday cake": [
11916,
11917
],
"dragon pickaxe": [
11920,
12797,
@@ -8271,6 +8281,10 @@
13222,
13224
],
"herb sack": [
13226,
24478
],
"eternal boots": [
13235,
23644
@@ -8539,6 +8553,10 @@
13576,
20785
],
"seed box": [
13639,
24482
],
"farmers boro trousers": [
13640,
13641
@@ -9692,9 +9710,5 @@
24469,
24472,
24475
],
"cat ears": [
24522,
24525
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

File diff suppressed because one or more lines are too long

View File

@@ -11,6 +11,5 @@ open.osrs.builddate=@open.osrs.builddate@
runelite.wiki.troubleshooting.link=https://github.com/open-osrs/runelite/wiki/Troubleshooting-problems-with-the-client
runelite.wiki.building.link=https://github.com/open-osrs/runelite/wiki/Building-with-IntelliJ-IDEA
runelite.dnschange.link=https://1.1.1.1/dns/
launcher.version=@launcher.version@
plugin.path=@plugin.path@
runelite.imgur.client.id=30d71e5f6860809

View File

@@ -3,7 +3,17 @@
.string_stack_count 0
.int_var_count 35
.string_var_count 1
sconst "bankLayoutInit"
; callback "beforeBankLayout"
; Fired before the bank starts its layout
; Used by the TabInterface to hide fake bank items for tag tabs
;
; callback "setBankScroll"
; Fired before bank is calculated
; Used by the TabInterface to show fake bank items for tag tabs
;
; callback "isTabMenuActive"
; Used by the TabInterface to skip setting the bank title
sconst "beforeBankLayout"
runelite_callback
get_varbit 5102
iconst 1
@@ -12,12 +22,12 @@
LABEL4:
iconst 0
iload 9
if_sethide
if_sethide
jump LABEL13
LABEL8:
iconst 1
iload 9
if_sethide
if_sethide
iload 11
invoke 41
LABEL13:
@@ -33,10 +43,10 @@ LABEL19:
LABEL21:
iload 16
iload 14
if_sethide
if_sethide
iload 16
iload 15
if_sethide
if_sethide
get_varbit 8352
iconst 1
if_icmpeq LABEL31
@@ -51,22 +61,22 @@ LABEL34:
LABEL36:
iload 16
iload 12
if_sethide
if_sethide
iload 16
iload 13
if_sethide
if_sethide
iconst 441
iconst 0
iconst 0
iconst 0
iload 14
if_setposition
if_setposition
iconst 444
iconst 7
iconst 0
iconst 0
iload 15
if_setposition
if_setposition
get_varbit 8352
iconst 1
if_icmpeq LABEL58
@@ -78,27 +88,27 @@ LABEL58:
jump LABEL85
LABEL62:
iload 12
if_getx
if_getx
iload 12
if_gety
if_gety
iconst 0
iconst 0
iload 14
if_setposition
if_setposition
iload 13
if_getx
if_getx
iload 13
if_gety
if_gety
iconst 0
iconst 0
iload 15
if_setposition
if_setposition
iconst 37
iconst 37
iconst 1
iconst 0
iload 4
if_setsize
if_setsize
jump LABEL121
LABEL85:
get_varbit 8352
@@ -116,7 +126,7 @@ LABEL93:
iconst 1
iconst 0
iload 4
if_setsize
if_setsize
jump LABEL121
LABEL100:
get_varbit 8352
@@ -134,7 +144,7 @@ LABEL108:
iconst 1
iconst 0
iload 4
if_setsize
if_setsize
jump LABEL121
LABEL115:
iconst 0
@@ -142,13 +152,13 @@ LABEL115:
iconst 1
iconst 0
iload 4
if_setsize
if_setsize
LABEL121:
iconst 1
iload 10
if_sethide
if_sethide
iload 10
cc_deleteall
cc_deleteall
iconst 0
istore 17
get_varbit 4170
@@ -201,7 +211,7 @@ LABEL165:
LABEL171:
iconst 1
iload 8
if_sethide
if_sethide
iconst 2
istore 18
iconst 460
@@ -209,42 +219,42 @@ LABEL171:
iconst 0
iconst 1
iload 2
if_setsize
if_setsize
iconst 16
iconst 39
iconst 0
iconst 1
iload 3
if_setsize
if_setsize
iconst 28
iconst 42
iconst 2
iconst 0
iload 1
if_setposition
if_setposition
jump LABEL216
LABEL195:
iconst 0
iload 8
if_sethide
if_sethide
iconst 460
iconst 81
iconst 0
iconst 1
iload 2
if_setsize
if_setsize
iconst 16
iconst 81
iconst 0
iconst 1
iload 3
if_setsize
if_setsize
iconst 12
iconst 42
iconst 2
iconst 0
iload 1
if_setposition
if_setposition
LABEL216:
iload 3
iload 2
@@ -254,8 +264,8 @@ LABEL216:
iconst 816
iconst 9
iconst 3
multiply
add
multiply
add
istore 20
LABEL227:
iload 19
@@ -265,17 +275,17 @@ LABEL227:
LABEL231:
iload 2
iload 19
cc_find
cc_find
iconst 1
if_icmpeq LABEL237
jump LABEL239
LABEL237:
iconst 1
cc_sethide
cc_sethide
LABEL239:
iload 19
iconst 1
add
add
istore 19
jump LABEL227
LABEL244:
@@ -283,22 +293,22 @@ LABEL244:
istore 19
iconst 8
iconst 1
sub
sub
istore 21
iload 2
if_getwidth
if_getwidth
iconst 51
sub
sub
iconst 35
sub
sub
istore 22
iload 22
iconst 8
iconst 36
multiply
sub
multiply
sub
iload 21
div
div
istore 23
iconst -1
istore 24
@@ -331,51 +341,51 @@ LABEL288:
LABEL292:
iload 2
iload 19
cc_find
cc_find
iconst 1
if_icmpeq LABEL298
jump LABEL300
LABEL298:
iconst 1
cc_sethide
cc_sethide
LABEL300:
iconst 95
iload 19
inv_getobj
inv_getobj
iconst -1
if_icmpne LABEL306
jump LABEL312
LABEL306:
iload 28
iconst 1
add
add
iload 19
istore 29
istore 28
LABEL312:
iload 19
iconst 1
add
add
istore 19
jump LABEL288
LABEL317:
get_varbit 4171
get_varbit 4172
add
add
get_varbit 4173
add
add
get_varbit 4174
add
add
get_varbit 4175
add
add
get_varbit 4176
add
add
get_varbit 4177
add
add
get_varbit 4178
add
add
get_varbit 4179
add
add
istore 30
iload 30
iconst 0
@@ -384,13 +394,22 @@ LABEL317:
LABEL339:
iconst 816
iconst 1
sub
sub
istore 29
LABEL343:
iconst 0 ; Scroll height variable
iconst 0 ; Compare variable
iconst 0 ;
sconst "setBankScroll" ; Show fake bank items for tag tabs
runelite_callback ; If tag tab menu search isn't active
if_icmpeq CONTINUE_SEARCH ; continue to normal bank search
istore 27 ; Load scroll height into variable
jump GetTabRange ; Skip normal bank layout
CONTINUE_SEARCH:
iload 30
iload 29
iconst 1
add
add
iconst 0
iload 2
iload 3
@@ -406,7 +425,7 @@ LABEL343:
istore 27
iload 26
iload 25
add
add
istore 26
iconst 0
istore 19
@@ -423,7 +442,7 @@ LABEL370:
iload 19
iload 19
get_varbit 4171
add
add
iconst 1
iload 2
iload 3
@@ -439,11 +458,11 @@ LABEL370:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4171
add
add
istore 19
LABEL400:
get_varbit 4172
@@ -459,7 +478,7 @@ LABEL404:
iload 19
iload 19
get_varbit 4172
add
add
iconst 2
iload 2
iload 3
@@ -475,11 +494,11 @@ LABEL404:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4172
add
add
istore 19
LABEL434:
get_varbit 4173
@@ -495,7 +514,7 @@ LABEL438:
iload 19
iload 19
get_varbit 4173
add
add
iconst 3
iload 2
iload 3
@@ -511,11 +530,11 @@ LABEL438:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4173
add
add
istore 19
LABEL468:
get_varbit 4174
@@ -531,7 +550,7 @@ LABEL472:
iload 19
iload 19
get_varbit 4174
add
add
iconst 4
iload 2
iload 3
@@ -547,11 +566,11 @@ LABEL472:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4174
add
add
istore 19
LABEL502:
get_varbit 4175
@@ -567,7 +586,7 @@ LABEL506:
iload 19
iload 19
get_varbit 4175
add
add
iconst 5
iload 2
iload 3
@@ -583,11 +602,11 @@ LABEL506:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4175
add
add
istore 19
LABEL536:
get_varbit 4176
@@ -603,7 +622,7 @@ LABEL540:
iload 19
iload 19
get_varbit 4176
add
add
iconst 6
iload 2
iload 3
@@ -619,11 +638,11 @@ LABEL540:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4176
add
add
istore 19
LABEL570:
get_varbit 4177
@@ -639,7 +658,7 @@ LABEL574:
iload 19
iload 19
get_varbit 4177
add
add
iconst 7
iload 2
iload 3
@@ -655,11 +674,11 @@ LABEL574:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4177
add
add
istore 19
LABEL604:
get_varbit 4178
@@ -675,7 +694,7 @@ LABEL608:
iload 19
iload 19
get_varbit 4178
add
add
iconst 8
iload 2
iload 3
@@ -691,11 +710,11 @@ LABEL608:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4178
add
add
istore 19
LABEL638:
get_varbit 4179
@@ -711,7 +730,7 @@ LABEL642:
iload 19
iload 19
get_varbit 4179
add
add
iconst 9
iload 2
iload 3
@@ -727,11 +746,11 @@ LABEL642:
istore 27
iload 26
iload 25
add
add
istore 26
iload 19
get_varbit 4179
add
add
istore 19
LABEL672:
invoke 514
@@ -743,7 +762,7 @@ LABEL676:
lowercase ; instead get the var directly and lowercase it
sstore 0
sload 0
string_length
string_length
iconst 0
if_icmpgt LABEL683
jump LABEL702
@@ -754,7 +773,7 @@ LABEL683:
sconst "</col>"
join_string 4
iload 5
if_settext
if_settext
get_varc_int 5
iconst 11
if_icmpeq LABEL694
@@ -762,7 +781,7 @@ LABEL683:
LABEL694:
sconst "Show items whose names contain the following text: ("
iload 26
tostring
tostring
sconst " found)"
join_string 3
iload 26 ; load number of matches
@@ -770,7 +789,7 @@ LABEL694:
runelite_callback ; invoke callback
pop_int ; pop number of matches
iconst 10616876
if_settext
if_settext
LABEL701:
jump LABEL716
LABEL702:
@@ -780,7 +799,7 @@ LABEL702:
sconst "</col>"
join_string 4
iload 5
if_settext
if_settext
get_varc_int 5
iconst 11
if_icmpeq LABEL713
@@ -790,7 +809,7 @@ LABEL713:
sconst "setSearchBankInputText" ; load event name
runelite_callback ; invoke callback
iconst 10616876
if_settext
if_settext
LABEL716:
jump LABEL720
LABEL717:
@@ -798,7 +817,7 @@ LABEL717:
sconst "setBankTitle" ;
runelite_callback ;
iload 5
if_settext
if_settext
LABEL720:
iload 0
iload 1
@@ -821,17 +840,17 @@ LABEL720:
iload 14
iload 15
invoke 505
return
return
LABEL740:
invoke 514
iconst 1
if_icmpeq LABEL744
jump LABEL747
jump GetTabRange
LABEL744:
iconst 1
iconst 1
invoke 299
LABEL747:
GetTabRange:
iconst -1
istore 31
iconst -1
@@ -848,18 +867,18 @@ LABEL759:
iload 19
iconst 816
if_icmplt LABEL763
jump LABEL843
jump SetTitle
LABEL763:
iload 2
iload 19
cc_find
cc_find
iconst 1
if_icmpeq LABEL769
jump LABEL838
LABEL769:
iconst 95
iload 19
inv_getobj
inv_getobj
istore 24
iload 24
iconst -1
@@ -868,7 +887,7 @@ LABEL769:
LABEL777:
iload 28
iconst 1
add
add
istore 28
LABEL781:
iload 19
@@ -882,11 +901,11 @@ LABEL785:
jump LABEL836
LABEL789:
iconst 0
cc_sethide
cc_sethide
iload 24
iconst 95
iload 19
inv_getnum
inv_getnum
iload 2
iload 3
iload 9
@@ -895,22 +914,22 @@ LABEL789:
invoke 278
iload 34
iconst 36
multiply
multiply
istore 27
iconst 51
iload 33
iconst 36
iload 23
add
multiply
add
add
multiply
add
iload 27
iconst 0
iconst 0
cc_setposition
cc_setposition
iload 27
iconst 32
add
add
istore 27
iload 33
iload 21
@@ -919,55 +938,60 @@ LABEL789:
LABEL824:
iload 33
iconst 1
add
add
istore 33
jump LABEL835
LABEL829:
iconst 0
iload 34
iconst 1
add
add
istore 34
istore 33
LABEL835:
jump LABEL838
LABEL836:
iconst 1
cc_sethide
cc_sethide
LABEL838:
iload 19
iconst 1
add
add
istore 19
jump LABEL759
LABEL843:
SetTitle:
iconst 0 ; Compare variable
iconst 0 ;
sconst "isTabMenuActive" ; Check if tag tab menu
runelite_callback ; is active and skip setting
if_icmpne FinishBuilding ; the bank title if it is
get_varbit 4170
iconst 2
if_icmpeq LABEL847
jump LABEL857
LABEL847:
if_icmpeq SetTitleRomanNumeral
jump SetTitleNumber
SetTitleRomanNumeral:
sconst "Tab "
iconst 105
iconst 115
iconst 207
get_varbit 4150
enum
enum
join_string 2
sconst "setBankTitle" ;
runelite_callback ;
iload 5
if_settext
jump LABEL863
LABEL857:
if_settext
jump FinishBuilding
SetTitleNumber:
sconst "Tab "
get_varbit 4150
tostring
tostring
join_string 2
sconst "setBankTitle" ;
runelite_callback ;
iload 5
if_settext
LABEL863:
if_settext
FinishBuilding:
iload 0
iload 1
iload 2
@@ -987,4 +1011,4 @@ LABEL863:
iload 14
iload 15
invoke 505
return
return

View File

@@ -1 +1 @@
15660E39A740C416BFD71621A448A96FA6B5C5E8AD212179F3D6785AE35CAA38
A9BA4723E7D91AD151C1AB3ABEAF84971BFFD71AA8C23E763ECCC8981A8A1429

View File

@@ -47,7 +47,7 @@ LABEL23:
get_varbit 8119
iconst 1
if_icmpeq LABEL42
jump LABEL144
jump LABEL146
LABEL42:
iconst 105
iconst 115
@@ -96,11 +96,13 @@ LABEL77:
iload 4
iconst 1
if_icmpeq LABEL86
jump LABEL101
jump LABEL103
LABEL86:
iconst 60
iconst 5
iload 3
add
invoke 1045
iconst 30
iconst 0
iconst 0
@@ -112,8 +114,8 @@ LABEL86:
iconst 2
iconst 10616871
if_setposition
jump LABEL113
LABEL101:
jump LABEL115
LABEL103:
iconst 0
iconst 30
iconst 0
@@ -126,26 +128,26 @@ LABEL101:
iconst 2
iconst 10616871
if_setposition
LABEL113:
LABEL115:
iload 3
iconst 10616889
if_getwidth
if_icmpgt LABEL118
jump LABEL124
LABEL118:
if_icmpgt LABEL120
jump LABEL126
LABEL120:
iconst 2
iconst 2
iconst 0
iconst 10616889
if_settextalign
jump LABEL129
LABEL124:
jump LABEL131
LABEL126:
iconst 0
iconst 2
iconst 0
iconst 10616889
if_settextalign
LABEL129:
LABEL131:
iconst 10616889
if_clearops
iconst -1
@@ -160,8 +162,8 @@ LABEL129:
sconst ""
iconst 10616889
if_setonop
jump LABEL185
LABEL144:
jump LABEL187
LABEL146:
iconst 105
iconst 115
iconst 1894
@@ -203,7 +205,7 @@ LABEL144:
sconst "ii"
iconst 10616889
if_setonop
LABEL185:
LABEL187:
sload 2
iconst 10616889
if_settext

View File

@@ -1 +0,0 @@
C70BDF62710D9FC0EB6707BD94FC0C4335B428DEDD1B52DD51776F811F32C9CF

View File

@@ -1,802 +0,0 @@
.id 1658
.int_stack_count 15
.string_stack_count 0
.int_var_count 25
.string_var_count 1
; Callback "clanChatChannelRebuild" for whenever clan chat is done being built, used inside ClanChatPlugin for ignores
iload 3
iconst 6
iconst 7
iconst 6
sconst "Sort by rank"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 4
iconst 2
iconst 3
iconst 2
sconst "Sort by name"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 5
iconst 8
iconst 9
iconst 9
sconst "Sort by last world change"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 6
iconst 4
iconst 5
iconst 4
sconst "Sort by world"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
iload 7
iconst 0
iconst 1
iconst 0
sconst "Legacy sort"
iload 0
iload 1
iload 2
iload 3
iload 4
iload 5
iload 6
iload 7
iload 8
iload 9
iload 10
iload 11
iload 12
iload 13
iload 14
invoke 1659
3644
get_varc_int 185
switch
1: LABEL109
2: LABEL112
3: LABEL115
4: LABEL184
5: LABEL212
6: LABEL118
7: LABEL148
8: LABEL178
9: LABEL181
jump LABEL239
LABEL109:
iconst 0
3645
jump LABEL239
LABEL112:
iconst 1
3646
jump LABEL239
LABEL115:
iconst 0
3646
jump LABEL239
LABEL118:
iconst 1
3657
get_varc_int 206
switch
3: LABEL125
4: LABEL128
5: LABEL135
8: LABEL142
9: LABEL145
iconst 1
3646
jump LABEL147
LABEL125:
iconst 0
3646
jump LABEL147
LABEL128:
iconst 1
3652
iconst 1
3647
iconst 1
3646
jump LABEL147
LABEL135:
iconst 1
3652
iconst 0
3647
iconst 1
3646
jump LABEL147
LABEL142:
iconst 1
3648
jump LABEL147
LABEL145:
iconst 0
3648
LABEL147:
jump LABEL239
LABEL148:
iconst 0
3657
get_varc_int 206
switch
3: LABEL155
4: LABEL158
5: LABEL165
8: LABEL172
9: LABEL175
iconst 1
3646
jump LABEL177
LABEL155:
iconst 0
3646
jump LABEL177
LABEL158:
iconst 1
3652
iconst 1
3647
iconst 1
3646
jump LABEL177
LABEL165:
iconst 1
3652
iconst 0
3647
iconst 1
3646
jump LABEL177
LABEL172:
iconst 1
3648
jump LABEL177
LABEL175:
iconst 0
3648
LABEL177:
jump LABEL239
LABEL178:
iconst 1
3648
jump LABEL239
LABEL181:
iconst 0
3648
jump LABEL239
LABEL184:
iconst 1
3652
iconst 1
3647
get_varc_int 206
switch
3: LABEL193
6: LABEL196
7: LABEL201
8: LABEL206
9: LABEL209
iconst 1
3646
jump LABEL211
LABEL193:
iconst 0
3646
jump LABEL211
LABEL196:
iconst 1
3657
iconst 1
3646
jump LABEL211
LABEL201:
iconst 0
3657
iconst 1
3646
jump LABEL211
LABEL206:
iconst 1
3648
jump LABEL211
LABEL209:
iconst 0
3648
LABEL211:
jump LABEL239
LABEL212:
iconst 1
3652
iconst 0
3647
get_varc_int 206
switch
3: LABEL221
6: LABEL224
7: LABEL229
8: LABEL234
9: LABEL237
iconst 1
3646
jump LABEL239
LABEL221:
iconst 0
3646
jump LABEL239
LABEL224:
iconst 1
3657
iconst 1
3646
jump LABEL239
LABEL229:
iconst 0
3657
iconst 1
3646
jump LABEL239
LABEL234:
iconst 1
3648
jump LABEL239
LABEL237:
iconst 0
3648
LABEL239:
3655
iload 8
cc_deleteall
clan_getchatcount
istore 15
get_varbit 6363
iconst 1
if_icmpeq LABEL248
jump LABEL296
LABEL248:
iload 15
iconst 0
if_icmpgt LABEL252
jump LABEL253
LABEL252:
clan_leavechat
LABEL253:
iconst 0
istore 15
iconst 0
iload 2
if_sethide
iconst 1
iload 9
if_sethide
iload 11
invoke 2067
pop_int
iconst -1
sconst ""
iload 11
if_setonmouserepeat
iconst -1
sconst ""
iload 11
if_setonmouseleave
iload 13
invoke 2067
pop_int
iconst -1
sconst ""
iload 13
if_setonmouserepeat
iconst -1
sconst ""
iload 13
if_setonmouseleave
sconst "<col=7f7f7f>"
sconst "---"
sconst "</col>"
join_string 3
iload 12
if_settext
iload 12
if_clearops
iconst -1
sconst ""
iload 12
if_setonop
jump LABEL341
LABEL296:
iconst 1
iload 2
if_sethide
iconst 0
iload 9
if_sethide
iload 11
invoke 486
pop_int
iconst 94
iconst -2147483645
sconst "I"
iload 11
if_setonmouserepeat
iconst 92
iconst -2147483645
sconst "I"
iload 11
if_setonmouseleave
iload 13
invoke 486
pop_int
iconst 94
iconst -2147483645
sconst "I"
iload 13
if_setonmouserepeat
iconst 92
iconst -2147483645
sconst "I"
iload 13
if_setonmouseleave
sconst "Clan Setup"
iload 12
if_settext
iconst 1
sconst "Clan Setup"
iload 12
if_setop
iconst 489
iconst -2147483644
iconst 1
sconst "ii"
iload 12
if_setonop
LABEL341:
sconst ""
sstore 0
iconst -1
istore 16
iconst -1
istore 17
clan_getchatrank
istore 18
clan_getchatminkick
istore 19
iload 3
if_getwidth
istore 20
iconst 0
istore 21
iconst 0
istore 22
iconst 15
istore 23
invoke 1972
iconst 1
if_icmpeq LABEL364
jump LABEL369
LABEL364:
iconst 8
iconst 5
iload 23
scale
istore 23
LABEL369:
iconst 0
istore 24
LABEL371:
iload 24
iload 15
if_icmplt LABEL375
jump LABEL572
LABEL375:
iload 24
clan_getchatusername
iload 24
clan_getchatuserworld
iload 24
clan_getchatuserrank
istore 17
istore 16
sstore 0
iload 8
iconst 4
iload 21
cc_create
iload 21
iconst 1
add
istore 21
iload 20
iload 23
iconst 1
iconst 0
cc_setsize
iconst 0
iload 22
iconst 2
iconst 0
cc_setposition
iconst 494
cc_settextfont
iconst 0
iconst 1
iconst 0
cc_settextalign
sload 0
cc_settext
iconst 16777215
cc_setcolour
iconst 0
cc_settextshadow
iload 8
iconst 4
iload 21
cc_create 1
iload 21
iconst 1
add
istore 21
iload 20
iload 23
iconst 1
iconst 0
cc_setsize 1
iconst 0
iload 22
iconst 2
iconst 0
cc_setposition 1
iconst 494
cc_settextfont 1
iconst 2
iconst 1
iconst 0
cc_settextalign 1
sconst "World "
iload 16
tostring
join_string 2
cc_settext 1
iload 16
map_world
if_icmpeq LABEL447
jump LABEL450
LABEL447:
iconst 901389
cc_setcolour 1
jump LABEL452
LABEL450:
iconst 16777060
cc_setcolour 1
LABEL452:
iconst 0
cc_settextshadow 1
iload 8
iconst 5
iload 21
cc_create 1
iload 21
iconst 1
add
istore 21
iconst 9
iconst 9
iconst 0
iconst 0
cc_setsize 1
iconst 1
iload 22
iload 23
iconst 9
sub
iconst 2
div
add
iconst 0
iconst 0
cc_setposition 1
iconst 105
iconst 100
iconst 706
iload 17
enum
cc_setgraphic 1
iload 24
clan_isself
iconst 0
if_icmpeq LABEL489
jump LABEL525
LABEL489:
iload 24
clan_isfriend
iconst 1
if_icmpeq LABEL494
jump LABEL501
LABEL494:
iconst 9
sconst "Remove friend"
cc_setop
iconst 9
sconst "Remove friend"
cc_setop 1
jump LABEL525
LABEL501:
iload 24
clan_isignore
iconst 1
if_icmpeq LABEL506
jump LABEL513
LABEL506:
iconst 10
sconst "Remove ignore"
cc_setop
iconst 10
sconst "Remove ignore"
cc_setop 1
jump LABEL525
LABEL513:
iconst 7
sconst "Add friend"
cc_setop
iconst 7
sconst "Add friend"
cc_setop 1
iconst 8
sconst "Add ignore"
cc_setop
iconst 8
sconst "Add ignore"
cc_setop 1
LABEL525:
invoke 1942
iconst 0
if_icmpeq LABEL529
jump LABEL543
LABEL529:
iload 18
iload 19
if_icmpge LABEL533
jump LABEL543
LABEL533:
iload 18
iload 17
if_icmpgt LABEL537
jump LABEL543
LABEL537:
iconst 6
sconst "Kick user"
cc_setop
iconst 6
sconst "Kick user"
cc_setop 1
LABEL543:
sconst "<col=ff9040>"
sload 0
sconst "</col>"
join_string 3
cc_setopbase
sconst "<col=ff9040>"
sload 0
sconst "</col>"
join_string 3
cc_setopbase 1
iconst 214
sconst "event_opbase"
iconst -2147483644
sconst "si"
cc_setonop
iconst 214
sconst "event_opbase"
iconst -2147483644
sconst "si"
cc_setonop 1
iload 24
iconst 1
add
iload 22
iload 23
add
istore 22
istore 24
jump LABEL371
LABEL572:
iload 15
iconst 1
if_icmpge LABEL576
jump LABEL580
LABEL576:
iload 22
iconst 5
add
istore 22
LABEL580:
iload 10
if_clearops
get_varbit 6363
iconst 1
if_icmpeq LABEL586
jump LABEL605
LABEL586:
sconst ""
iload 0
if_settext
sconst ""
iload 1
if_settext
sconst "<col=7f7f7f>"
sconst "---"
sconst "</col>"
join_string 3
iload 10
if_settext
iload 10
if_clearops
iconst -1
sconst ""
iload 10
if_setonop
jump LABEL672
LABEL605:
iload 15
iconst 0
if_icmpgt LABEL609
jump LABEL653
LABEL609:
sconst "<col=ffff64>"
clan_getchatdisplayname
sconst "</col>"
join_string 3
iload 0
if_settext
sconst "<col=ffffff>"
clan_getchatownername
sconst "</col>"
join_string 3
iload 1
if_settext
sconst "Leave Chat"
iload 10
if_settext
get_varbit 5432
iconst 1
if_icmpeq LABEL631
get_varbit 4289
iconst 0
if_icmpne LABEL631
jump LABEL642
LABEL631:
iconst 6
sconst "Leave Chat"
iload 10
if_setop
iconst 194
iconst -2147483644
iconst 6
sconst "ii"
iload 10
if_setonop
jump LABEL652
LABEL642:
iconst 1
sconst "Leave Chat"
iload 10
if_setop
iconst 194
iconst -2147483644
iconst 1
sconst "ii"
iload 10
if_setonop
LABEL652:
jump LABEL672
LABEL653:
sconst "Not in chat"
iload 0
if_settext
sconst "None"
iload 1
if_settext
sconst "Join Chat"
iload 10
if_settext
iconst 1
sconst "Join Chat"
iload 10
if_setop
iconst 194
iconst -2147483644
iconst 1
sconst "ii"
iload 10
if_setonop
LABEL672:
iload 22
iload 8
if_getheight
if_icmpgt LABEL677
jump LABEL687
LABEL677:
iconst 0
iload 22
iload 8
if_setscrollsize
iload 9
iload 8
iload 8
if_getscrolly
invoke 72
jump LABEL695
LABEL687:
iconst 0
iconst 0
iload 8
if_setscrollsize
iload 9
iload 8
iconst 0
invoke 72
LABEL695:
sconst "clanChatChannelRebuild"
runelite_callback
return

View File

@@ -1 +0,0 @@
15F58F5939D9311F3D76FA2F0F3441B7B0DA1E8EAE23C654948095A7D51E07F0

View File

@@ -1,634 +0,0 @@
.id 1601
.int_stack_count 4
.string_stack_count 2
.int_var_count 14
.string_var_count 3
; callback "itemsKeptOnDeath"
; Used by the ItemsKepthOnDeath plugin to edit the interface
; Put a rune pouch in your inventory and it shouldn't have a white outline
; in the Items kept on death screen
sload 1
iconst 262167
if_settext
iconst 0
istore 4
iconst 0
istore 5
iconst -1
istore 6
iconst 0
istore 7
sconst ""
sstore 2
iconst 0
istore 8
iconst 0
istore 9
iconst 0
istore 10
iconst 0
istore 11
iload 1
define_array 111
iconst 0
istore 12
iconst 0
istore 13
iload 0
iconst 0
if_icmpeq LABEL31
jump LABEL525
LABEL31:
iconst 93
iconst 13190
inv_total
iconst 0
if_icmpgt LABEL42
iconst 93
iconst 13192
inv_total
iconst 0
if_icmpgt LABEL42
jump LABEL44
LABEL42:
iconst 1
istore 9
LABEL44:
iload 10
iload 1
if_icmplt LABEL48
jump LABEL88
LABEL48:
iconst 584
iload 11
inv_getobj
istore 6
iload 6
iconst -1
if_icmpne LABEL56
jump LABEL85
LABEL56:
iconst 584
iload 11
inv_getnum
istore 7
LABEL60:
iload 10
iload 1
if_icmplt LABEL64
jump LABEL80
LABEL64:
iload 7
iconst 0
if_icmpgt LABEL68
jump LABEL80
LABEL68:
iload 10
iload 6
set_array_int
iload 7
iconst 1
sub
istore 7
iload 10
iconst 1
add
istore 10
jump LABEL60
LABEL80:
iload 11
iconst 1
add
istore 11
jump LABEL87
LABEL85:
iload 1
istore 10
LABEL87:
jump LABEL44
LABEL88:
iload 4
iload 1
if_icmplt LABEL92
jump LABEL147
LABEL92:
iconst 262162
iconst 5
iload 4
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 4
iconst 40
multiply
add
iconst 25
iconst 0
iconst 0
cc_setposition
iload 4
get_array_int
istore 6
iload 6
iconst -1
if_icmpne LABEL117
jump LABEL144
LABEL117:
iload 6
iconst 1
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 1
iconst 1
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 1
cc_setoutline
iload 4
iconst 1
add
istore 4
jump LABEL146
LABEL144:
iload 1
istore 4
LABEL146:
jump LABEL88
LABEL147:
iconst 0
istore 4
LABEL149:
iload 4
iconst 468
inv_size
if_icmplt LABEL154
jump LABEL350
LABEL154:
iconst 468
iload 4
inv_getobj
istore 6
iload 6
iconst -1
if_icmpne LABEL162
jump LABEL345
LABEL162:
iconst 262165
iconst 5
iload 5
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 5
iconst 8
mod
iconst 38
multiply
add
iconst 25
iconst 38
iload 5
iconst 8
div
multiply
add
iconst 0
iconst 0
cc_setposition
iload 6
iconst 468
iload 4
inv_getnum
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 0
iconst 468
iload 4
inv_getnum
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 111
iconst 49
iconst 879
iload 6
oc_uncert
enum
iconst 1
if_icmpeq LABEL221
jump LABEL226
LABEL221:
iconst 2
cc_setoutline
iconst 1
istore 8
jump LABEL228
LABEL226:
iconst 1
cc_setoutline
LABEL228:
iload 5
iconst 1
add
istore 5
iload 6
oc_stackable
iconst 1
if_icmpeq LABEL237
jump LABEL345
LABEL237:
iconst 0
istore 10
iconst 0
istore 13
LABEL241:
iload 10
iload 1
if_icmplt LABEL245
jump LABEL259
LABEL245:
iload 10
get_array_int
iload 6
if_icmpeq LABEL250
jump LABEL254
LABEL250:
iload 13
iconst 1
add
istore 13
LABEL254:
iload 10
iconst 1
add
istore 10
jump LABEL241
LABEL259:
iconst 2147483647
iconst 94
iload 6
inv_total
sub
iconst 93
iload 6
inv_total
sub
iload 13
add
istore 12
iconst 0
iload 12
sub
istore 12
iload 12
iconst 0
if_icmpgt LABEL279
jump LABEL345
LABEL279:
iconst 262165
iconst 5
iload 5
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 5
iconst 8
mod
iconst 38
multiply
add
iconst 25
iconst 38
iload 5
iconst 8
div
multiply
add
iconst 0
iconst 0
cc_setposition
iload 6
iload 12
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 0
iload 12
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 111
iconst 49
iconst 879
iload 6
oc_uncert
enum
iconst 1
if_icmpeq LABEL334
jump LABEL339
LABEL334:
iconst 2
cc_setoutline
iconst 1
istore 8
jump LABEL341
LABEL339:
iconst 1
cc_setoutline
LABEL341:
iload 5
iconst 1
add
istore 5
LABEL345:
iload 4
iconst 1
add
istore 4
jump LABEL149
LABEL350:
sconst "The normal amount of items kept is "
sconst "three"
sconst "."
sconst "<br>"
sconst "<br>"
join_string 5
sstore 2
iload 3
iconst 1
if_icmpeq LABEL361
jump LABEL371
LABEL361:
sload 2
sconst "You're an "
sconst "<col=ff3333>"
sconst "Ultimate Iron Man"
sconst "<col=ff981f>"
sconst ", so you will always keep zero items."
join_string 5
append
sstore 2
jump LABEL434
LABEL371:
iload 1
iconst 0
if_icmpeq LABEL375
jump LABEL387
LABEL375:
sload 2
sconst "You're marked with a "
sconst "<col=ff3333>"
sconst "PK skull"
sconst "<col=ff981f>"
sconst ". This reduces the items you keep from "
sconst "three"
sconst " to zero!"
join_string 7
append
sstore 2
jump LABEL434
LABEL387:
iload 1
iconst 1
if_icmpeq LABEL391
jump LABEL410
LABEL391:
sload 2
sconst "You're marked with a "
sconst "<col=ff3333>"
sconst "PK skull"
sconst "<col=ff981f>"
sconst ". This reduces the items you keep from "
sconst "three"
sconst " to zero!"
sconst "<br>"
sconst "<br>"
sconst "However, you also have the "
sconst "<col=ff3333>"
sconst "Protect Items"
sconst "<col=ff981f>"
sconst " prayer active, which saves you one extra item!"
join_string 14
append
sstore 2
jump LABEL434
LABEL410:
iload 1
iconst 3
if_icmpeq LABEL414
jump LABEL419
LABEL414:
sload 2
sconst "You have no factors affecting the items you keep."
append
sstore 2
jump LABEL434
LABEL419:
iload 1
iconst 3
iconst 1
add
if_icmpeq LABEL425
jump LABEL434
LABEL425:
sload 2
sconst "You have the "
sconst "<col=ff3333>"
sconst "Protect Items"
sconst "<col=ff981f>"
sconst " prayer active, which saves you one extra item!"
join_string 5
append
sstore 2
LABEL434:
iload 8
iconst 1
if_icmpeq LABEL441
iload 9
iconst 1
if_icmpeq LABEL441
jump LABEL492
LABEL441:
iload 8
iconst 1
if_icmpeq LABEL445
jump LABEL466
LABEL445:
iload 9
iconst 1
if_icmpeq LABEL449
jump LABEL466
LABEL449:
sload 2
sconst "<br>"
sconst "<br>"
sconst "Items with a "
sconst "<col=ffffff>"
sconst "white outline"
sconst "<col=ff981f>"
sconst " will always be lost."
sconst "<br>"
sconst "<col=00ff00>"
sconst "Bonds"
sconst "</col>"
sconst " are always protected."
join_string 12
append
sstore 2
jump LABEL492
LABEL466:
iload 8
iconst 1
if_icmpeq LABEL470
jump LABEL482
LABEL470:
sload 2
sconst "<br>"
sconst "<br>"
sconst "Items with a "
sconst "<col=ffffff>"
sconst "white outline"
sconst "<col=ff981f>"
sconst " will always be lost."
join_string 7
append
sstore 2
jump LABEL492
LABEL482:
sload 2
sconst "<br>"
sconst "<br>"
sconst "<col=00ff00>"
sconst "Bonds"
sconst "</col>"
sconst " are always protected, so are not shown here."
join_string 6
append
sstore 2
LABEL492:
sload 2
iconst 262173
if_settext
sconst "<col=ffcc33>"
sconst "Max items kept on death :"
sconst "<br>"
sconst "<br>"
sconst "<col=ffcc33>"
sconst "~ "
iload 1
tostring
sconst " ~"
join_string 8
iconst 262174
if_settext
iload 2
iconst 0
if_icmpgt LABEL511
jump LABEL518
LABEL511:
sconst "Items you will keep on death:"
iconst 262161
if_settext
sconst "Items you will lose on death:"
iconst 262164
if_settext
jump LABEL524
LABEL518:
sconst "Items you will keep on death if not skulled:"
iconst 262161
if_settext
sconst "Items you will lose on death if not skulled:"
iconst 262164
if_settext
LABEL524:
jump LABEL565
LABEL525:
iconst 1
iconst 262165
if_sethide
iconst 1
iconst 262162
if_sethide
iconst 0
iconst 262175
if_sethide
sload 0
iconst 262176
if_settext
sconst "The normal amount of items kept is "
sconst "three"
sconst "."
sconst "<br>"
sconst "<br>"
join_string 5
sstore 2
sload 2
sconst "You're in a "
sconst "<col=ff3333>"
sconst "safe area"
sconst "<col=ff981f>"
sconst ". See information to the left for a more detailed description."
join_string 5
append
sstore 2
sload 2
iconst 262173
if_settext
sconst "<col=ffcc33>"
sconst "Max items kept on death :"
sconst "<br>"
sconst "<br>"
sconst "<col=ffcc33>"
sconst "All items!"
join_string 6
iconst 262174
if_settext
LABEL565:
sconst "itemsKeptOnDeath" ; push event name
runelite_callback ; invoke callback
return

View File

@@ -1 +0,0 @@
B370DDEEF61E0F420C1990DDA4FBBEDCEE8324F3750ABAC79B072A27268D887B

View File

@@ -1,394 +0,0 @@
.id 779
.int_stack_count 15
.string_stack_count 0
.int_var_count 16
.string_var_count 1
get_varbit 4397
iconst 1
if_icmpeq LABEL4
jump LABEL65
LABEL4:
iload 0
iload 1
cc_find
iconst 1
if_icmpeq LABEL10
jump LABEL12
LABEL10:
iconst 1
cc_sethide
LABEL12:
iload 0
iload 6
cc_find
iconst 1
if_icmpeq LABEL18
jump LABEL23
LABEL18:
iconst 0
cc_settrans
iconst -1
sconst ""
cc_setontimer
LABEL23:
iload 0
iload 12
cc_find
iconst 1
if_icmpeq LABEL29
jump LABEL31
LABEL29:
iconst 1
cc_sethide
LABEL31:
iload 0
iload 4
cc_find
iconst 1
if_icmpeq LABEL37
jump LABEL39
LABEL37:
sconst "Sell offer"
cc_settext
LABEL39:
iload 0
iload 5
cc_find
iconst 1
if_icmpeq LABEL45
jump LABEL47
LABEL45:
iconst 1119
cc_setgraphic
LABEL47:
iload 0
iload 2
cc_find
iconst 1
if_icmpeq LABEL53
jump LABEL56
LABEL53:
iconst 1
sconst "All"
cc_setop
LABEL56:
iload 0
iload 3
cc_find
iconst 1
if_icmpeq LABEL62
jump LABEL64
LABEL62:
sconst "All"
cc_settext
LABEL64:
jump LABEL130
LABEL65:
iload 0
iload 1
cc_find
iconst 1
if_icmpeq LABEL71
jump LABEL73
LABEL71:
iconst 0
cc_sethide
LABEL73:
iload 0
iload 6
cc_find
iconst 1
if_icmpeq LABEL79
jump LABEL89
LABEL79:
iconst 100
cc_settrans
iconst 811
iconst -2147483645
iconst -2147483643
clientclock
iconst 100
iconst 250
sconst "Iiiii"
cc_setontimer
LABEL89:
iload 0
iload 12
cc_find
iconst 1
if_icmpeq LABEL95
jump LABEL97
LABEL95:
iconst 0
cc_sethide
LABEL97:
iload 0
iload 4
cc_find
iconst 1
if_icmpeq LABEL103
jump LABEL105
LABEL103:
sconst "Buy offer"
cc_settext
LABEL105:
iload 0
iload 5
cc_find
iconst 1
if_icmpeq LABEL111
jump LABEL113
LABEL111:
iconst 1118
cc_setgraphic
LABEL113:
iload 0
iload 2
cc_find
iconst 1
if_icmpeq LABEL119
jump LABEL122
LABEL119:
iconst 1
sconst "+1K"
cc_setop
LABEL122:
iload 0
iload 3
cc_find
iconst 1
if_icmpeq LABEL128
jump LABEL130
LABEL128:
sconst "+1K"
cc_settext
LABEL130:
sconst ","
sstore 0
iconst 0
istore 15
get_varp 1151
iconst -1
if_icmpne LABEL138
jump LABEL274
LABEL138:
iload 0
iload 7
cc_find
iconst 1
if_icmpeq LABEL144
jump LABEL147
LABEL144:
get_varp 1151
get_varbit 4396
cc_setobject_nonum
LABEL147:
iload 0
iload 8
cc_find
iconst 1
if_icmpeq LABEL153
jump LABEL156
LABEL153:
get_varp 1151
oc_name
cc_settext
LABEL156:
iload 0
iload 9
cc_find
iconst 1
if_icmpeq LABEL162
jump LABEL166
LABEL162:
get_varbit 4396
sload 0
invoke 46
cc_settext
LABEL166:
iload 0
iload 10
cc_find
iconst 1
if_icmpeq LABEL172
jump LABEL185
LABEL172:
get_varbit 4398
iconst 1
if_icmpeq LABEL176
jump LABEL179
LABEL176:
sconst "1 coin"
cc_settext
jump LABEL185
LABEL179:
get_varbit 4398
sload 0
invoke 46
sconst " coins"
join_string 2
cc_settext
LABEL185:
get_varbit 4396
iconst 0
if_icmpgt LABEL189
jump LABEL211
LABEL189:
iconst 2147483647
get_varbit 4396
div
get_varbit 4398
if_icmplt LABEL195
jump LABEL211
LABEL195:
iload 0
iload 11
cc_find
iconst 1
if_icmpeq LABEL201
jump LABEL206
LABEL201:
sconst "<col=ff0000>"
sconst "Too much money!"
sconst "</col>"
join_string 3
cc_settext
LABEL206:
iload 0
iload 14
iload 13
invoke 780
jump LABEL273
LABEL211:
get_varbit 4396
get_varbit 4398
multiply
istore 15
iload 0
iload 11
cc_find
iconst 1
if_icmpeq LABEL221
jump LABEL234
LABEL221:
iload 15
iconst 1
if_icmpeq LABEL225
jump LABEL228
LABEL225:
sconst "1 coin"
cc_settext
jump LABEL234
LABEL228:
iload 15
sload 0
invoke 46
sconst " coins"
join_string 2
cc_settext
LABEL234:
iload 15
iconst 0
if_icmpgt LABEL238
jump LABEL269
LABEL238:
iload 13
invoke 208
pop_int
iconst 772
iconst -2147483645
sconst "I"
iload 13
if_setonmouserepeat
iconst 97
iconst -2147483645
sconst "I"
iload 13
if_setonmouseleave
iconst 489
iconst -2147483644
iconst 2
sconst "ii"
iload 13
if_setonop
iload 0
iload 14
cc_find
iconst 1
if_icmpeq LABEL263
jump LABEL268
LABEL263:
sconst "<col=ffffff>"
sconst "Confirm"
sconst "</col>"
join_string 3
cc_settext
LABEL268:
jump LABEL273
LABEL269:
iload 0
iload 14
iload 13
invoke 780
LABEL273:
jump LABEL319
LABEL274:
iload 0
iload 7
cc_find
iconst 1
if_icmpeq LABEL280
jump LABEL283
LABEL280:
iconst 6512
iconst 1
cc_setobject_nonum
LABEL283:
iload 0
iload 8
cc_find
iconst 1
if_icmpeq LABEL289
jump LABEL291
LABEL289:
sconst "Choose an item..."
cc_settext
LABEL291:
iload 0
iload 9
cc_find
iconst 1
if_icmpeq LABEL297
jump LABEL299
LABEL297:
sconst ""
cc_settext
LABEL299:
iload 0
iload 10
cc_find
iconst 1
if_icmpeq LABEL305
jump LABEL307
LABEL305:
sconst ""
cc_settext
LABEL307:
iload 0
iload 11
cc_find
iconst 1
if_icmpeq LABEL313
jump LABEL315
LABEL313:
sconst ""
cc_settext
LABEL315:
iload 0
iload 14
iload 13
invoke 780
LABEL319:
sconst "geBuilt" ;
runelite_callback ;
return

View File

@@ -1 +0,0 @@
FC7F8B54745582D6DD530D5458E129B67D6B3CFF61BACD4BBE7BC8C40E26F3C6

View File

@@ -1,228 +0,0 @@
.id 1354
.int_stack_count 3
.string_stack_count 0
.int_var_count 7
.string_var_count 0
iconst 0
istore 3
iconst 0
istore 4
iconst 0
istore 5
invoke 1340
istore 6
LABEL8:
iload 5
iload 6
if_icmplt LABEL12
jump LABEL64
LABEL12:
iload 0
iload 5
cc_find
iconst 1
if_icmpeq LABEL18
jump LABEL59
LABEL18:
iload 5
invoke 1357
istore 3
iload 5
invoke 3236
iconst 1
if_icmpeq LABEL26
jump LABEL29
LABEL26:
iconst 10461087
istore 4
jump LABEL45
LABEL29:
iload 3
iconst 2
if_icmpeq LABEL33
jump LABEL36
LABEL33:
iconst 901389
istore 4
jump LABEL45
LABEL36:
iload 3
iconst 0
if_icmpeq LABEL40
jump LABEL43
LABEL40:
iconst 16776960
istore 4
jump LABEL45
LABEL43:
iconst 16711680
istore 4
LABEL45:
iload 4
cc_setcolour
iconst 85
iconst -2147483645
iconst -2147483643
iconst 16777215
sconst "Iii"
cc_setonmouseover
iconst 85
iconst -2147483645
iconst -2147483643
iload 4
sconst "Iii"
cc_setonmouseleave
LABEL59:
iload 5
iconst 1
add
istore 5
jump LABEL8
LABEL64:
iconst 0
invoke 2245
istore 6
istore 5
LABEL68:
iload 5
iload 6
if_icmplt LABEL72
jump LABEL124
LABEL72:
iload 1
iload 5
cc_find
iconst 1
if_icmpeq LABEL78
jump LABEL119
LABEL78:
iload 5
invoke 1358
istore 3
iload 5
invoke 3237
iconst 1
if_icmpeq LABEL86
jump LABEL89
LABEL86:
iconst 10461087
istore 4
jump LABEL105
LABEL89:
iload 3
iconst 2
if_icmpeq LABEL93
jump LABEL96
LABEL93:
iconst 901389
istore 4
jump LABEL105
LABEL96:
iload 3
iconst 0
if_icmpeq LABEL100
jump LABEL103
LABEL100:
iconst 16776960
istore 4
jump LABEL105
LABEL103:
iconst 16711680
istore 4
LABEL105:
iload 4
cc_setcolour
iconst 85
iconst -2147483645
iconst -2147483643
iconst 16777215
sconst "Iii"
cc_setonmouseover
iconst 85
iconst -2147483645
iconst -2147483643
iload 4
sconst "Iii"
cc_setonmouseleave
LABEL119:
iload 5
iconst 1
add
istore 5
jump LABEL68
LABEL124:
iconst 0
invoke 2265
istore 6
istore 5
LABEL128:
iload 5
iload 6
if_icmplt LABEL132
jump LABEL184
LABEL132:
iload 2
iload 5
cc_find
iconst 1
if_icmpeq LABEL138
jump LABEL179
LABEL138:
iload 5
invoke 1359
istore 3
iload 5
invoke 3238
iconst 1
if_icmpeq LABEL146
jump LABEL149
LABEL146:
iconst 10461087
istore 4
jump LABEL165
LABEL149:
iload 3
iconst 2
if_icmpeq LABEL153
jump LABEL156
LABEL153:
iconst 901389
istore 4
jump LABEL165
LABEL156:
iload 3
iconst 0
if_icmpeq LABEL160
jump LABEL163
LABEL160:
iconst 16776960
istore 4
jump LABEL165
LABEL163:
iconst 16711680
istore 4
LABEL165:
iload 4
cc_setcolour
iconst 85
iconst -2147483645
iconst -2147483643
iconst 16777215
sconst "Iii"
cc_setonmouseover
iconst 85
iconst -2147483645
iconst -2147483643
iload 4
sconst "Iii"
cc_setonmouseleave
LABEL179:
iload 5
iconst 1
add
istore 5
jump LABEL128
LABEL184:
sconst "questProgressUpdated"
runelite_callback
return

View File

@@ -27,11 +27,14 @@ package net.runelite.client.config;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.io.File;
import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import javax.inject.Named;
import net.runelite.api.Client;
import net.runelite.client.RuneLite;
import net.runelite.client.account.AccountSession;
import net.runelite.client.eventbus.EventBus;
import org.junit.Assert;
@@ -64,6 +67,10 @@ public class ConfigManagerTest
@Bind
private OpenOSRSConfig openOSRSConfig;
@Bind
@Named("config")
private File config = RuneLite.DEFAULT_CONFIG_FILE;
@Inject
ConfigManager manager;

View File

@@ -87,7 +87,7 @@ public class PluginManagerTest
public void before() throws IOException
{
Injector injector = Guice.createInjector(Modules
.override(new RuneLiteModule(() -> null, true))
.override(new RuneLiteModule(() -> null, RuneLite.DEFAULT_CONFIG_FILE))
.with(BoundFieldModule.of(this)));
RuneLite.setInjector(injector);
@@ -116,7 +116,7 @@ public class PluginManagerTest
@Test
public void testLoadPlugins() throws Exception
{
PluginManager pluginManager = new PluginManager(false, null, null, null, null);
PluginManager pluginManager = new PluginManager(null, null, null, null);
pluginManager.setOutdated(true);
pluginManager.loadCorePlugins();
Collection<Plugin> plugins = pluginManager.getPlugins();
@@ -127,14 +127,13 @@ public class PluginManagerTest
.count();
assertEquals(expected, plugins.size());
pluginManager = new PluginManager(false, null, null, null, null);
pluginManager = new PluginManager(null, null, null, null);
pluginManager.loadCorePlugins();
plugins = pluginManager.getPlugins();
expected = pluginClasses.stream()
.map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class))
.filter(Objects::nonNull)
.filter(pd -> !pd.developerPlugin())
.count();
assertEquals(expected, plugins.size());
}
@@ -144,9 +143,9 @@ public class PluginManagerTest
{
List<Module> modules = new ArrayList<>();
modules.add(new GraphvizModule());
modules.add(new RuneLiteModule(() -> null, true));
modules.add(new RuneLiteModule(() -> null, RuneLite.DEFAULT_CONFIG_FILE));
PluginManager pluginManager = new PluginManager(true, null, null, null, null);
PluginManager pluginManager = new PluginManager(null, null, null, null);
pluginManager.loadCorePlugins();
modules.addAll(pluginManager.getPlugins());
@@ -198,7 +197,7 @@ public class PluginManagerTest
public void testEventbusAnnotations() throws PluginInstantiationException
{
EventBus eventbus = new EventBus();
PluginManager pluginManager = new PluginManager(true, eventbus, null, null, null)
PluginManager pluginManager = new PluginManager(eventbus, null, null, null)
{
@Override
public boolean isPluginEnabled(Plugin plugin)