Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2020-03-09 22:40:04 +01:00
26 changed files with 181 additions and 2116 deletions

View File

@@ -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;
}
}
}

View File

@@ -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))

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

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

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

@@ -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);
}

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

@@ -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)