Merge remote-tracking branch 'runelite/master'
This commit is contained in:
@@ -39,6 +39,7 @@ 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;
|
||||
@@ -48,6 +49,8 @@ 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;
|
||||
@@ -107,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;
|
||||
|
||||
@@ -220,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()
|
||||
@@ -313,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);
|
||||
@@ -343,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();
|
||||
@@ -505,9 +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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,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))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import lombok.Value;
|
||||
/**
|
||||
* Represents Discord Rich Presence RPC data
|
||||
*/
|
||||
@Builder
|
||||
@Builder(toBuilder = true)
|
||||
@Value
|
||||
public class DiscordPresence
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +53,6 @@ public @interface PluginDescriptor
|
||||
*/
|
||||
boolean hidden() default false;
|
||||
|
||||
boolean developerPlugin() default false;
|
||||
|
||||
boolean loadWhenOutdated() default false;
|
||||
|
||||
PluginType type() default PluginType.UNCATEGORIZED;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user