openrune: reset to upstream client bare
This commit is contained in:
@@ -24,88 +24,114 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ClientShutdown;
|
||||
import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.util.RunnableExceptionLogger;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ClientSessionManager
|
||||
{
|
||||
private final ScheduledExecutorService executorService;
|
||||
private final Client client;
|
||||
private final SessionClient sessionClient;
|
||||
|
||||
private ScheduledFuture<?> scheduledFuture;
|
||||
private UUID sessionId;
|
||||
|
||||
|
||||
@Inject
|
||||
ClientSessionManager(EventBus eventBus,
|
||||
ClientSessionManager(ScheduledExecutorService executorService,
|
||||
@Nullable Client client,
|
||||
OkHttpClient okHttpClient)
|
||||
{
|
||||
this.executorService = executorService;
|
||||
this.client = client;
|
||||
this.sessionClient = new SessionClient(okHttpClient);
|
||||
}
|
||||
|
||||
eventBus.subscribe(ClientShutdown.class, this, (e) ->
|
||||
public void start()
|
||||
{
|
||||
try
|
||||
{
|
||||
Future<Void> f = shutdown();
|
||||
if (f != null)
|
||||
sessionId = sessionClient.open();
|
||||
log.debug("Opened session {}", sessionId);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("error opening session", ex);
|
||||
}
|
||||
|
||||
scheduledFuture = executorService.scheduleWithFixedDelay(RunnableExceptionLogger.wrap(this::ping), 1, 10, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onClientShutdown(ClientShutdown e)
|
||||
{
|
||||
scheduledFuture.cancel(true);
|
||||
|
||||
e.waitFor(executorService.submit(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
e.waitFor(f);
|
||||
UUID localUuid = sessionId;
|
||||
if (localUuid != null)
|
||||
{
|
||||
sessionClient.delete(localUuid);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn(null, ex);
|
||||
}
|
||||
sessionId = null;
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
void start()
|
||||
private void ping()
|
||||
{
|
||||
sessionClient.openSession()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.single())
|
||||
.doOnError(this::error)
|
||||
.subscribe(this::setUuid);
|
||||
}
|
||||
|
||||
@Schedule(period = 10, unit = ChronoUnit.MINUTES, asynchronous = true)
|
||||
public void ping()
|
||||
{
|
||||
if (sessionId == null)
|
||||
try
|
||||
{
|
||||
start();
|
||||
if (sessionId == null)
|
||||
{
|
||||
sessionId = sessionClient.open();
|
||||
log.debug("Opened session {}", sessionId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("unable to open session", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
sessionClient.pingSession(sessionId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.single())
|
||||
.doOnError(this::error)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
private Future<Void> shutdown()
|
||||
{
|
||||
if (sessionId != null)
|
||||
boolean loggedIn = false;
|
||||
if (client != null)
|
||||
{
|
||||
return sessionClient.delete(sessionId)
|
||||
.toFuture();
|
||||
|
||||
GameState gameState = client.getGameState();
|
||||
loggedIn = gameState.getState() >= GameState.LOADING.getState();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setUuid(UUID uuid)
|
||||
{
|
||||
this.sessionId = uuid;
|
||||
log.debug("Opened session {}.", sessionId);
|
||||
}
|
||||
try
|
||||
{
|
||||
sessionClient.ping(sessionId, loggedIn);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("Resetting session", ex);
|
||||
sessionId = null;
|
||||
}
|
||||
|
||||
private void error(Throwable error)
|
||||
{
|
||||
log.debug("Error in client session.");
|
||||
log.trace(null, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.escape.Escaper;
|
||||
import com.google.common.escape.Escapers;
|
||||
import com.google.inject.Inject;
|
||||
@@ -113,7 +114,7 @@ public class Notifier
|
||||
private final ChatMessageManager chatMessageManager;
|
||||
private final EventBus eventBus;
|
||||
private final Path notifyIconPath;
|
||||
private final boolean terminalNotifierAvailable;
|
||||
private boolean terminalNotifierAvailable;
|
||||
private Instant flashStart;
|
||||
private long mouseLastPressedMillis;
|
||||
private long lastClipMTime = CLIP_MTIME_UNLOADED;
|
||||
@@ -137,7 +138,10 @@ public class Notifier
|
||||
this.notifyIconPath = RuneLite.RUNELITE_DIR.toPath().resolve("icon.png");
|
||||
|
||||
// First check if we are running in launcher
|
||||
this.terminalNotifierAvailable = true;
|
||||
if (!Strings.isNullOrEmpty(RuneLiteProperties.getLauncherVersion()) && OSType.getOSType() == OSType.MacOS)
|
||||
{
|
||||
executorService.execute(() -> terminalNotifierAvailable = isTerminalNotifierAvailable());
|
||||
}
|
||||
|
||||
storeIcon();
|
||||
}
|
||||
@@ -149,7 +153,7 @@ public class Notifier
|
||||
|
||||
public void notify(String message, TrayIcon.MessageType type)
|
||||
{
|
||||
eventBus.post(NotificationFired.class, new NotificationFired(message, type));
|
||||
eventBus.post(new NotificationFired(message, type));
|
||||
|
||||
if (!runeLiteConfig.sendNotificationsWhenFocused() && clientUI.isFocused())
|
||||
{
|
||||
@@ -364,7 +368,7 @@ public class Notifier
|
||||
|
||||
private static Process sendCommand(final List<String> commands) throws IOException
|
||||
{
|
||||
return new ProcessBuilder(commands.toArray(new String[0]))
|
||||
return new ProcessBuilder(commands.toArray(new String[commands.size()]))
|
||||
.redirectErrorStream(true)
|
||||
.start();
|
||||
}
|
||||
@@ -373,7 +377,7 @@ public class Notifier
|
||||
{
|
||||
if (OSType.getOSType() == OSType.Linux && !Files.exists(notifyIconPath))
|
||||
{
|
||||
try (InputStream stream = Notifier.class.getResourceAsStream("/openosrs.png"))
|
||||
try (InputStream stream = Notifier.class.getResourceAsStream("/runelite.png"))
|
||||
{
|
||||
Files.copy(stream, notifyIconPath);
|
||||
}
|
||||
@@ -386,21 +390,19 @@ public class Notifier
|
||||
|
||||
private boolean isTerminalNotifierAvailable()
|
||||
{
|
||||
if (OSType.getOSType() == OSType.MacOS)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
final Process exec = Runtime.getRuntime().exec(new String[]{"terminal-notifier", "-help"});
|
||||
exec.waitFor();
|
||||
return exec.exitValue() == 0;
|
||||
}
|
||||
catch (IOException | InterruptedException e)
|
||||
final Process exec = Runtime.getRuntime().exec(new String[]{"terminal-notifier", "-help"});
|
||||
if (!exec.waitFor(2, TimeUnit.SECONDS))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return exec.exitValue() == 0;
|
||||
}
|
||||
catch (IOException | InterruptedException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String toUrgency(TrayIcon.MessageType type)
|
||||
|
||||
@@ -26,41 +26,27 @@ package net.runelite.client;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import com.github.zafarkhaja.semver.Version;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import io.reactivex.rxjava3.core.Completable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.swing.SwingUtilities;
|
||||
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||
import joptsimple.OptionException;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.ValueConversionException;
|
||||
@@ -69,49 +55,34 @@ import joptsimple.util.EnumConverter;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.callback.Hooks;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.CommandManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.LauncherConfig;
|
||||
import net.runelite.client.config.OpenOSRSConfig;
|
||||
import net.runelite.client.discord.DiscordService;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.events.ExternalPluginsLoaded;
|
||||
import net.runelite.client.externalplugins.ExternalPluginManager;
|
||||
import net.runelite.client.game.FriendChatManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.LootManager;
|
||||
import net.runelite.client.game.PlayerManager;
|
||||
import net.runelite.client.game.WorldService;
|
||||
import net.runelite.client.game.XpDropManager;
|
||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.graphics.ModelOutlineRenderer;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.ExternalPluginManager;
|
||||
import net.runelite.client.plugins.PluginManager;
|
||||
import net.runelite.client.rs.ClientLoader;
|
||||
import net.runelite.client.rs.ClientUpdateCheckMode;
|
||||
import net.runelite.client.task.Scheduler;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import net.runelite.client.ui.RuneLiteSplashScreen;
|
||||
import net.runelite.client.ui.DrawManager;
|
||||
import net.runelite.client.ui.FatalErrorDialog;
|
||||
import net.runelite.client.ui.SplashScreen;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||
import net.runelite.client.ui.overlay.WidgetOverlay;
|
||||
import net.runelite.client.ui.overlay.arrow.ArrowMinimapOverlay;
|
||||
import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
|
||||
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
|
||||
import net.runelite.client.util.Groups;
|
||||
import net.runelite.client.util.WorldUtil;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.worlds.World;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -120,42 +91,41 @@ import org.slf4j.LoggerFactory;
|
||||
@Slf4j
|
||||
public class RuneLite
|
||||
{
|
||||
public static final String SYSTEM_VERSION = "0.0.1";
|
||||
|
||||
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite");
|
||||
public static final File CACHE_DIR = new File(RUNELITE_DIR, "cache");
|
||||
public static final File PLUGINS_DIR = new File(RUNELITE_DIR, "plugins");
|
||||
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
||||
public static final File EXTERNALPLUGIN_DIR = new File(RUNELITE_DIR, "externalmanager");
|
||||
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 DEFAULT_CONFIG_FILE = new File(RUNELITE_DIR, "runeliteplus.properties");
|
||||
public static final Locale SYSTEM_LOCALE = Locale.getDefault();
|
||||
public static boolean allowPrivateServer = false;
|
||||
public static String uuid = UUID.randomUUID().toString();
|
||||
public static final File DEFAULT_SESSION_FILE = new File(RUNELITE_DIR, "session");
|
||||
public static final File DEFAULT_CONFIG_FILE = new File(RUNELITE_DIR, "settings.properties");
|
||||
|
||||
private static final int MAX_OKHTTP_CACHE_SIZE = 20 * 1024 * 1024; // 20mb
|
||||
|
||||
@Getter
|
||||
private static Injector injector;
|
||||
|
||||
@Inject
|
||||
public DiscordService discordService;
|
||||
|
||||
@Inject
|
||||
private WorldService worldService;
|
||||
|
||||
@Inject
|
||||
private PluginManager pluginManager;
|
||||
|
||||
@Inject
|
||||
private ExternalPluginManager externalPluginManager;
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Inject
|
||||
private DrawManager drawManager;
|
||||
|
||||
@Inject
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Inject
|
||||
private DiscordService discordService;
|
||||
|
||||
@Inject
|
||||
private ClientSessionManager clientSessionManager;
|
||||
|
||||
@@ -163,10 +133,10 @@ public class RuneLite
|
||||
private ClientUI clientUI;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
private Provider<InfoBoxManager> infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private TooltipManager tooltipManager;
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private Provider<PartyService> partyService;
|
||||
@@ -178,7 +148,7 @@ public class RuneLite
|
||||
private Provider<OverlayRenderer> overlayRenderer;
|
||||
|
||||
@Inject
|
||||
private Provider<FriendChatManager> friendChatManager;
|
||||
private Provider<FriendChatManager> friendsChatManager;
|
||||
|
||||
@Inject
|
||||
private Provider<ChatMessageManager> chatMessageManager;
|
||||
@@ -189,58 +159,25 @@ public class RuneLite
|
||||
@Inject
|
||||
private Provider<CommandManager> commandManager;
|
||||
|
||||
@Inject
|
||||
private Provider<InfoBoxManager> infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private Provider<TooltipOverlay> tooltipOverlay;
|
||||
|
||||
@Inject
|
||||
private Provider<WorldMapOverlay> worldMapOverlay;
|
||||
|
||||
@Inject
|
||||
private Provider<ArrowWorldOverlay> arrowWorldOverlay;
|
||||
|
||||
@Inject
|
||||
private Provider<ArrowMinimapOverlay> arrowMinimapOverlay;
|
||||
|
||||
@Inject
|
||||
private Provider<LootManager> lootManager;
|
||||
|
||||
@Inject
|
||||
private Provider<XpDropManager> xpDropManager;
|
||||
|
||||
@Inject
|
||||
private Provider<PlayerManager> playerManager;
|
||||
|
||||
@Inject
|
||||
private Provider<ChatboxPanelManager> chatboxPanelManager;
|
||||
|
||||
@Inject
|
||||
private Groups groups;
|
||||
|
||||
@Inject
|
||||
private Hooks hooks;
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
private Provider<Hooks> hooks;
|
||||
|
||||
@Inject
|
||||
@Nullable
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OpenOSRSConfig openOSRSConfig;
|
||||
|
||||
@Inject
|
||||
private LauncherConfig launcherConfig;
|
||||
|
||||
@Inject
|
||||
private Provider<ModelOutlineRenderer> modelOutlineRenderer;
|
||||
|
||||
@Inject
|
||||
private Scheduler scheduler;
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
Locale.setDefault(Locale.ENGLISH);
|
||||
@@ -249,15 +186,13 @@ public class RuneLite
|
||||
parser.accepts("developer-mode", "Enable developer tools");
|
||||
parser.accepts("debug", "Show extra debugging output");
|
||||
parser.accepts("safe-mode", "Disables external plugins and the GPU plugin");
|
||||
parser.accepts("no-splash", "Do not show the splash screen");
|
||||
parser.accepts("insecure-skip-tls-verification", "Disables TLS verification");
|
||||
|
||||
final ArgumentAcceptingOptionSpec<String> proxyInfo = parser
|
||||
.accepts("proxy")
|
||||
.withRequiredArg().ofType(String.class);
|
||||
final ArgumentAcceptingOptionSpec<Integer> worldInfo = parser
|
||||
.accepts("world")
|
||||
.withRequiredArg().ofType(Integer.class);
|
||||
final ArgumentAcceptingOptionSpec<File> sessionfile = parser.accepts("sessionfile", "Use a specified session file")
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(new ConfigFileConverter())
|
||||
.defaultsTo(DEFAULT_SESSION_FILE);
|
||||
|
||||
final ArgumentAcceptingOptionSpec<File> configfile = parser.accepts("config", "Use a specified config file")
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(new ConfigFileConverter())
|
||||
@@ -268,7 +203,7 @@ public class RuneLite
|
||||
.withRequiredArg()
|
||||
.ofType(ClientUpdateCheckMode.class)
|
||||
.defaultsTo(ClientUpdateCheckMode.AUTO)
|
||||
.withValuesConvertedBy(new EnumConverter<>(ClientUpdateCheckMode.class)
|
||||
.withValuesConvertedBy(new EnumConverter<ClientUpdateCheckMode>(ClientUpdateCheckMode.class)
|
||||
{
|
||||
@Override
|
||||
public ClientUpdateCheckMode convert(String v)
|
||||
@@ -278,18 +213,7 @@ public class RuneLite
|
||||
});
|
||||
|
||||
parser.accepts("help", "Show this text").forHelp();
|
||||
|
||||
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.");
|
||||
}
|
||||
OptionSet options = parser.parse(args);
|
||||
|
||||
if (options.has("help"))
|
||||
{
|
||||
@@ -303,147 +227,92 @@ public class RuneLite
|
||||
logger.setLevel(Level.DEBUG);
|
||||
}
|
||||
|
||||
if (options.has("proxy"))
|
||||
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) ->
|
||||
{
|
||||
String[] proxy = options.valueOf(proxyInfo).split(":");
|
||||
|
||||
if (proxy.length >= 2)
|
||||
log.error("Uncaught exception:", throwable);
|
||||
if (throwable instanceof AbstractMethodError)
|
||||
{
|
||||
System.setProperty("socksProxyHost", proxy[0]);
|
||||
System.setProperty("socksProxyPort", proxy[1]);
|
||||
log.error("Classes are out of date; Build with maven again.");
|
||||
}
|
||||
});
|
||||
|
||||
if (proxy.length >= 4)
|
||||
{
|
||||
System.setProperty("java.net.socks.username", proxy[2]);
|
||||
System.setProperty("java.net.socks.password", proxy[3]);
|
||||
|
||||
final String user = proxy[2];
|
||||
final char[] pass = proxy[3].toCharArray();
|
||||
|
||||
Authenticator.setDefault(new Authenticator()
|
||||
{
|
||||
private final PasswordAuthentication auth = new PasswordAuthentication(user, pass);
|
||||
|
||||
protected PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return auth;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (options.has("world"))
|
||||
{
|
||||
int world = options.valueOf(worldInfo);
|
||||
System.setProperty("cli.world", String.valueOf(world));
|
||||
}
|
||||
|
||||
final File configFile = resolveLinks(options.valueOf(configfile));
|
||||
Properties properties = new Properties();
|
||||
try (FileInputStream in = new FileInputStream(configFile))
|
||||
{
|
||||
properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
|
||||
try
|
||||
{
|
||||
@SuppressWarnings("unchecked") Map<String, String> copy = (Map) Map.copyOf(properties);
|
||||
copy.forEach((groupAndKey, value) ->
|
||||
{
|
||||
final String[] split = groupAndKey.split("\\.", 2);
|
||||
final String groupName = split[0];
|
||||
final String key = split[1];
|
||||
|
||||
if (!groupName.equals("openosrs"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.equals("disableHw") && value.equals("true"))
|
||||
{
|
||||
log.info("Disabling HW Accel");
|
||||
System.setProperty("sun.java2d.noddraw", "true");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error("Unexpected error", ex);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
log.error("Unable to load settings - no such file");
|
||||
}
|
||||
catch (IllegalArgumentException | IOException ex)
|
||||
{
|
||||
log.error("Unable to load settings", ex);
|
||||
}
|
||||
|
||||
final OkHttpClient.Builder okHttpClientBuilder = RuneLiteAPI.CLIENT.newBuilder()
|
||||
OkHttpClient.Builder okHttpClientBuilder = RuneLiteAPI.CLIENT.newBuilder()
|
||||
.cache(new Cache(new File(CACHE_DIR, "okhttp"), MAX_OKHTTP_CACHE_SIZE));
|
||||
|
||||
final boolean insecureSkipTlsVerification = options.has("insecure-skip-tls-verification");
|
||||
if (insecureSkipTlsVerification)
|
||||
if (insecureSkipTlsVerification || RuneLiteProperties.isInsecureSkipTlsVerification())
|
||||
{
|
||||
setupInsecureTrustManager(okHttpClientBuilder);
|
||||
}
|
||||
|
||||
final OkHttpClient okHttpClient = okHttpClientBuilder.build();
|
||||
|
||||
final ClientLoader clientLoader = new ClientLoader(okHttpClient, options.valueOf(updateMode));
|
||||
Completable.fromAction(clientLoader::get)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.subscribe();
|
||||
SplashScreen.init();
|
||||
SplashScreen.stage(0, "Retrieving client", "");
|
||||
|
||||
Completable.fromAction(ClassPreloader::preload)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.subscribe();
|
||||
|
||||
if (!options.has("no-splash"))
|
||||
try
|
||||
{
|
||||
RuneLiteSplashScreen.init();
|
||||
}
|
||||
final ClientLoader clientLoader = new ClientLoader(okHttpClient, options.valueOf(updateMode));
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) ->
|
||||
{
|
||||
log.error("Uncaught exception:", throwable);
|
||||
if (throwable instanceof AbstractMethodError)
|
||||
new Thread(() ->
|
||||
{
|
||||
RuneLiteSplashScreen.setError("Out of date!", "Classes are out of date; Build with Gradle again.");
|
||||
return;
|
||||
clientLoader.get();
|
||||
ClassPreloader.preload();
|
||||
}, "Preloader").start();
|
||||
|
||||
final boolean developerMode = options.has("developer-mode") && RuneLiteProperties.getLauncherVersion() == null;
|
||||
|
||||
if (developerMode)
|
||||
{
|
||||
boolean assertions = false;
|
||||
assert assertions = true;
|
||||
if (!assertions)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
new FatalErrorDialog("Developers should enable assertions; Add `-ea` to your JVM arguments`")
|
||||
.addBuildingGuide()
|
||||
.open());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RuneLiteSplashScreen.setError("Error while loading!", "Please check your internet connection and your DNS settings.");
|
||||
});
|
||||
PROFILES_DIR.mkdirs();
|
||||
|
||||
PROFILES_DIR.mkdirs();
|
||||
log.info("RuneLite {} (launcher version {}) starting up, args: {}",
|
||||
RuneLiteProperties.getVersion(), RuneLiteProperties.getLauncherVersion() == null ? "unknown" : RuneLiteProperties.getLauncherVersion(),
|
||||
args.length == 0 ? "none" : String.join(" ", args));
|
||||
|
||||
log.info("OpenOSRS {} Runelite {} (launcher version {}) starting up, args: {}",
|
||||
RuneLiteProperties.getPlusVersion(), RuneLiteProperties.getVersion(), RuneLiteProperties.getLauncherVersion() == null ? "unknown" : RuneLiteProperties.getLauncherVersion(),
|
||||
args.length == 0 ? "none" : String.join(" ", args));
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
final long start = System.currentTimeMillis();
|
||||
injector = Guice.createInjector(new RuneLiteModule(
|
||||
okHttpClient,
|
||||
clientLoader,
|
||||
developerMode,
|
||||
options.has("safe-mode"),
|
||||
options.valueOf(sessionfile),
|
||||
options.valueOf(configfile)));
|
||||
|
||||
injector = Guice.createInjector(new RuneLiteModule(
|
||||
okHttpClient,
|
||||
clientLoader,
|
||||
options.has("safe-mode"),
|
||||
configFile));
|
||||
injector.getInstance(RuneLite.class).start();
|
||||
|
||||
injector.getInstance(RuneLite.class).start();
|
||||
final long end = System.currentTimeMillis();
|
||||
final RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
||||
final long uptime = rb.getUptime();
|
||||
log.info("Client initialization took {}ms. Uptime: {}ms", end - start, uptime);
|
||||
final long end = System.currentTimeMillis();
|
||||
final RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
||||
final long uptime = rb.getUptime();
|
||||
log.info("Client initialization took {}ms. Uptime: {}ms", end - start, uptime);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("Failure during startup", e);
|
||||
SwingUtilities.invokeLater(() ->
|
||||
new FatalErrorDialog("RuneLite has encountered an unexpected error during startup.")
|
||||
.open());
|
||||
}
|
||||
finally
|
||||
{
|
||||
SplashScreen.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static void setInjector(Injector injector)
|
||||
{
|
||||
RuneLite.injector = injector;
|
||||
}
|
||||
|
||||
private void start() throws Exception
|
||||
public void start() throws Exception
|
||||
{
|
||||
// Load RuneLite or Vanilla client
|
||||
final boolean isOutdated = client == null;
|
||||
@@ -454,181 +323,84 @@ public class RuneLite
|
||||
injector.injectMembers(client);
|
||||
}
|
||||
|
||||
if (RuneLiteProperties.getLauncherVersion() == null || !openOSRSConfig.shareLogs())
|
||||
{
|
||||
final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||
logger.detachAppender("Sentry");
|
||||
}
|
||||
SplashScreen.stage(.57, null, "Loading configuration");
|
||||
|
||||
// Load user configuration
|
||||
RuneLiteSplashScreen.stage(.57, "Loading user config");
|
||||
configManager.load();
|
||||
|
||||
parseLauncherConfig();
|
||||
|
||||
// Load the session, including saved configuration
|
||||
RuneLiteSplashScreen.stage(.58, "Loading session data");
|
||||
sessionManager.loadSession();
|
||||
|
||||
// Tell the plugin manager if client is outdated or not
|
||||
pluginManager.setOutdated(isOutdated);
|
||||
|
||||
// Load external plugin manager
|
||||
externalPluginManager.startExternalUpdateManager();
|
||||
externalPluginManager.startExternalPluginManager();
|
||||
|
||||
// Update external plugins
|
||||
externalPluginManager.update();
|
||||
|
||||
// Load the plugins, but does not start them yet.
|
||||
// This will initialize configuration
|
||||
pluginManager.loadCorePlugins();
|
||||
externalPluginManager.loadPlugins();
|
||||
externalPluginManager.loadExternalPlugins();
|
||||
|
||||
RuneLiteSplashScreen.stage(.76, "Finalizing configuration");
|
||||
SplashScreen.stage(.70, null, "Finalizing configuration");
|
||||
|
||||
// Plugins have provided their config, so set default config
|
||||
// to main settings
|
||||
pluginManager.loadDefaultPluginConfiguration();
|
||||
pluginManager.loadDefaultPluginConfiguration(null);
|
||||
|
||||
// Start client session
|
||||
RuneLiteSplashScreen.stage(.77, "Starting core interface");
|
||||
clientSessionManager.start();
|
||||
eventBus.register(clientSessionManager);
|
||||
|
||||
//Set the world if specified via CLI args - will not work until clientUI.init is called
|
||||
Optional<Integer> worldArg = Optional.ofNullable(System.getProperty("cli.world")).map(Integer::parseInt);
|
||||
worldArg.ifPresent(this::setWorld);
|
||||
SplashScreen.stage(.75, null, "Starting core interface");
|
||||
|
||||
// Initialize UI
|
||||
RuneLiteSplashScreen.stage(.80, "Initialize UI");
|
||||
clientUI.init();
|
||||
|
||||
// Initialize Discord service
|
||||
discordService.init();
|
||||
|
||||
// Register event listeners
|
||||
eventBus.register(clientUI);
|
||||
eventBus.register(pluginManager);
|
||||
eventBus.register(externalPluginManager);
|
||||
eventBus.register(overlayManager);
|
||||
eventBus.register(drawManager);
|
||||
eventBus.register(configManager);
|
||||
eventBus.register(discordService);
|
||||
|
||||
if (!isOutdated)
|
||||
{
|
||||
// Initialize chat colors
|
||||
chatMessageManager.get().loadColors();
|
||||
|
||||
infoBoxManager.get();
|
||||
overlayRenderer.get();
|
||||
friendChatManager.get();
|
||||
itemManager.get();
|
||||
menuManager.get();
|
||||
chatMessageManager.get();
|
||||
commandManager.get();
|
||||
lootManager.get();
|
||||
xpDropManager.get();
|
||||
playerManager.get();
|
||||
chatboxPanelManager.get();
|
||||
partyService.get();
|
||||
|
||||
eventBus.subscribe(GameStateChanged.class, this, hooks::onGameStateChanged);
|
||||
eventBus.subscribe(ScriptCallbackEvent.class, this, hooks::onScriptCallbackEvent);
|
||||
eventBus.register(infoBoxManager.get());
|
||||
eventBus.register(partyService.get());
|
||||
eventBus.register(overlayRenderer.get());
|
||||
eventBus.register(friendsChatManager.get());
|
||||
eventBus.register(itemManager.get());
|
||||
eventBus.register(menuManager.get());
|
||||
eventBus.register(chatMessageManager.get());
|
||||
eventBus.register(commandManager.get());
|
||||
eventBus.register(lootManager.get());
|
||||
eventBus.register(chatboxPanelManager.get());
|
||||
eventBus.register(hooks.get());
|
||||
|
||||
// Add core overlays
|
||||
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
|
||||
overlayManager.add(worldMapOverlay.get());
|
||||
overlayManager.add(tooltipOverlay.get());
|
||||
overlayManager.add(arrowWorldOverlay.get());
|
||||
overlayManager.add(arrowMinimapOverlay.get());
|
||||
}
|
||||
|
||||
// Start plugins
|
||||
pluginManager.startPlugins();
|
||||
eventBus.post(ExternalPluginsLoaded.class, new ExternalPluginsLoaded());
|
||||
|
||||
// Register additional schedulers
|
||||
if (this.client != null)
|
||||
{
|
||||
scheduler.registerObject(modelOutlineRenderer.get());
|
||||
scheduler.registerObject(clientSessionManager);
|
||||
}
|
||||
|
||||
// Close the splash screen
|
||||
RuneLiteSplashScreen.close();
|
||||
SplashScreen.stop();
|
||||
|
||||
clientUI.show();
|
||||
}
|
||||
|
||||
private void setWorld(int cliWorld)
|
||||
@VisibleForTesting
|
||||
public static void setInjector(Injector injector)
|
||||
{
|
||||
int correctedWorld = cliWorld < 300 ? cliWorld + 300 : cliWorld;
|
||||
|
||||
if (correctedWorld <= 300 || client.getWorld() == correctedWorld)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final WorldResult worldResult = worldService.getWorlds();
|
||||
|
||||
if (worldResult == null)
|
||||
{
|
||||
log.warn("Failed to lookup worlds.");
|
||||
return;
|
||||
}
|
||||
|
||||
final World world = worldResult.findWorld(correctedWorld);
|
||||
|
||||
if (world != null)
|
||||
{
|
||||
final net.runelite.api.World rsWorld = client.createWorld();
|
||||
rsWorld.setActivity(world.getActivity());
|
||||
rsWorld.setAddress(world.getAddress());
|
||||
rsWorld.setId(world.getId());
|
||||
rsWorld.setPlayerCount(world.getPlayers());
|
||||
rsWorld.setLocation(world.getLocation());
|
||||
rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes()));
|
||||
|
||||
client.changeWorld(rsWorld);
|
||||
log.debug("Applied new world {}", correctedWorld);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn("World {} not found.", correctedWorld);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseLauncherConfig()
|
||||
{
|
||||
String launcherVersion = RuneLiteProperties.getLauncherVersion();
|
||||
|
||||
if (launcherVersion == null || !Version.valueOf(launcherVersion).greaterThanOrEqualTo(Version.valueOf("2.2.0")))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (launcherConfig.useProxy())
|
||||
{
|
||||
log.info("Setting proxy.");
|
||||
String[] proxy = launcherConfig.proxyDetails().split(":");
|
||||
|
||||
if (proxy.length >= 2)
|
||||
{
|
||||
System.setProperty("socksProxyHost", proxy[0]);
|
||||
System.setProperty("socksProxyPort", proxy[1]);
|
||||
}
|
||||
|
||||
if (proxy.length >= 4)
|
||||
{
|
||||
System.setProperty("java.net.socks.username", proxy[2]);
|
||||
System.setProperty("java.net.socks.password", proxy[3]);
|
||||
|
||||
final String user = proxy[2];
|
||||
final char[] pass = proxy[3].toCharArray();
|
||||
|
||||
Authenticator.setDefault(new Authenticator()
|
||||
{
|
||||
private final PasswordAuthentication auth = new PasswordAuthentication(user, pass);
|
||||
|
||||
protected PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return auth;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
RuneLite.injector = injector;
|
||||
}
|
||||
|
||||
private static class ConfigFileConverter implements ValueConverter<File>
|
||||
@@ -670,18 +442,6 @@ public class RuneLite
|
||||
}
|
||||
}
|
||||
|
||||
private static File resolveLinks(File f)
|
||||
{
|
||||
try
|
||||
{
|
||||
return f.toPath().toRealPath().toFile();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
private static void setupInsecureTrustManager(OkHttpClient.Builder okHttpClientBuilder)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -24,18 +24,13 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.name.Names;
|
||||
import java.applet.Applet;
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Singleton;
|
||||
@@ -47,8 +42,6 @@ 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;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
@@ -57,25 +50,27 @@ import net.runelite.client.plugins.PluginManager;
|
||||
import net.runelite.client.task.Scheduler;
|
||||
import net.runelite.client.util.DeferredEventBus;
|
||||
import net.runelite.client.util.ExecutorServiceExceptionLogger;
|
||||
import net.runelite.client.util.NonScheduledExecutorServiceExceptionLogger;
|
||||
import net.runelite.http.api.chat.ChatClient;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class RuneLiteModule extends AbstractModule
|
||||
{
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final Supplier<Applet> clientLoader;
|
||||
private final boolean developerMode;
|
||||
private final boolean safeMode;
|
||||
private final File sessionfile;
|
||||
private final File config;
|
||||
|
||||
@Override
|
||||
protected void configure()
|
||||
{
|
||||
bindConstant().annotatedWith(Names.named("developerMode")).to(developerMode);
|
||||
bindConstant().annotatedWith(Names.named("safeMode")).to(safeMode);
|
||||
bind(File.class).annotatedWith(Names.named("sessionfile")).toInstance(sessionfile);
|
||||
bind(File.class).annotatedWith(Names.named("config")).toInstance(config);
|
||||
bind(ScheduledExecutorService.class).toInstance(new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()));
|
||||
bind(OkHttpClient.class).toInstance(okHttpClient);
|
||||
bind(MenuManager.class);
|
||||
bind(ChatMessageManager.class);
|
||||
@@ -92,10 +87,6 @@ public class RuneLiteModule extends AbstractModule
|
||||
bind(EventBus.class)
|
||||
.annotatedWith(Names.named("Deferred EventBus"))
|
||||
.to(DeferredEventBus.class);
|
||||
|
||||
bind(Logger.class)
|
||||
.annotatedWith(Names.named("Core Logger"))
|
||||
.toInstance(LoggerFactory.getLogger(RuneLite.class));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -119,13 +110,6 @@ public class RuneLiteModule extends AbstractModule
|
||||
return configManager.getConfig(RuneLiteConfig.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
OpenOSRSConfig providePlusConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(OpenOSRSConfig.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ChatColorConfig provideChatColorConfig(ConfigManager configManager)
|
||||
@@ -133,39 +117,6 @@ public class RuneLiteModule extends AbstractModule
|
||||
return configManager.getConfig(ChatColorConfig.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
LauncherConfig provideLauncherConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(LauncherConfig.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ScheduledExecutorService provideScheduledExecutorService()
|
||||
{
|
||||
return new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder()
|
||||
.setNameFormat("scheduled-%d")
|
||||
.build()));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ExecutorService provideExecutorService()
|
||||
{
|
||||
int poolSize = 2 * Runtime.getRuntime().availableProcessors();
|
||||
|
||||
// Will start up to poolSize threads (because of allowCoreThreadTimeOut) as necessary, and times out
|
||||
// unused threads after 1 minute
|
||||
ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, poolSize,
|
||||
60L, TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(),
|
||||
new ThreadFactoryBuilder().setNameFormat("worker-%d").build());
|
||||
executor.allowCoreThreadTimeOut(true);
|
||||
|
||||
return new NonScheduledExecutorServiceExceptionLogger(executor);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ChatClient provideChatClient(OkHttpClient okHttpClient)
|
||||
|
||||
@@ -24,37 +24,38 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import javax.annotation.Nullable;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
public class RuneLiteProperties
|
||||
{
|
||||
private static final String RUNELITE_TITLE = "open.osrs.title";
|
||||
private static final String RUNELITE_TITLE = "runelite.title";
|
||||
private static final String RUNELITE_VERSION = "runelite.version";
|
||||
private static final String RUNELITE_PLUS_VERSION = "open.osrs.version";
|
||||
private static final String RUNELITE_PLUS_DATE = "open.osrs.builddate";
|
||||
private static final String RUNESCAPE_VERSION = "runescape.version";
|
||||
private static final String DISCORD_APP_ID = "open.osrs.discord.appid";
|
||||
private static final String DISCORD_APP_ID = "runelite.discord.appid";
|
||||
private static final String DISCORD_INVITE = "runelite.discord.invite";
|
||||
private static final String GITHUB_LINK = "runelite.github.link";
|
||||
private static final String WIKI_LINK = "runelite.wiki.link";
|
||||
private static final String PATREON_LINK = "runelite.patreon.link";
|
||||
private static final String LAUNCHER_VERSION_PROPERTY = "launcher.version";
|
||||
private static final String PLUGIN_PATH = "plugin.path";
|
||||
private static final String PLUGIN_DEVELOPMENT_PATH = "plugin.development.path";
|
||||
private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version";
|
||||
private static final String INSECURE_SKIP_TLS_VERIFICATION_PROPERTY = "runelite.insecure-skip-tls-verification";
|
||||
private static final String TROUBLESHOOTING_LINK = "runelite.wiki.troubleshooting.link";
|
||||
private static final String BUILDING_LINK = "runelite.wiki.building.link";
|
||||
private static final String DNS_CHANGE_LINK = "runelite.dnschange.link";
|
||||
private static final String JAV_CONFIG = "runelite.jav_config";
|
||||
private static final String JAV_CONFIG_BACKUP = "runelite.jav_config_backup";
|
||||
private static final String PLUGINHUB_BASE = "runelite.pluginhub.url";
|
||||
private static final String PLUGINHUB_VERSION = "runelite.pluginhub.version";
|
||||
private static final String IMGUR_CLIENT_ID = "runelite.imgur.client.id";
|
||||
|
||||
private static final Properties properties = new Properties();
|
||||
|
||||
static
|
||||
{
|
||||
try (InputStream in = RuneLiteProperties.class.getResourceAsStream("open.osrs.properties"))
|
||||
try (InputStream in = RuneLiteProperties.class.getResourceAsStream("runelite.properties"))
|
||||
{
|
||||
properties.load(in);
|
||||
}
|
||||
@@ -66,13 +67,7 @@ public class RuneLiteProperties
|
||||
|
||||
public static String getTitle()
|
||||
{
|
||||
final StringBuilder sb = new StringBuilder(properties.getProperty(RUNELITE_TITLE));
|
||||
String proxy;
|
||||
if ((proxy = System.getProperty("socksProxyHost")) != null)
|
||||
{
|
||||
sb.append(String.format(" (%s)", proxy));
|
||||
}
|
||||
return sb.toString();
|
||||
return properties.getProperty(RUNELITE_TITLE);
|
||||
}
|
||||
|
||||
public static String getVersion()
|
||||
@@ -80,16 +75,6 @@ public class RuneLiteProperties
|
||||
return properties.getProperty(RUNELITE_VERSION);
|
||||
}
|
||||
|
||||
public static String getPlusVersion()
|
||||
{
|
||||
return properties.getProperty(RUNELITE_PLUS_VERSION);
|
||||
}
|
||||
|
||||
public static String getPlusDate()
|
||||
{
|
||||
return properties.getProperty(RUNELITE_PLUS_DATE);
|
||||
}
|
||||
|
||||
public static String getRunescapeVersion()
|
||||
{
|
||||
return properties.getProperty(RUNESCAPE_VERSION);
|
||||
@@ -120,6 +105,17 @@ public class RuneLiteProperties
|
||||
return properties.getProperty(PATREON_LINK);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getLauncherVersion()
|
||||
{
|
||||
return System.getProperty(LAUNCHER_VERSION_PROPERTY);
|
||||
}
|
||||
|
||||
public static boolean isInsecureSkipTlsVerification()
|
||||
{
|
||||
return Boolean.getBoolean(INSECURE_SKIP_TLS_VERIFICATION_PROPERTY);
|
||||
}
|
||||
|
||||
public static String getTroubleshootingLink()
|
||||
{
|
||||
return properties.getProperty(TROUBLESHOOTING_LINK);
|
||||
@@ -135,31 +131,20 @@ public class RuneLiteProperties
|
||||
return properties.getProperty(DNS_CHANGE_LINK);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getLauncherVersion()
|
||||
public static String getJavConfig()
|
||||
{
|
||||
return System.getProperty(LAUNCHER_VERSION_PROPERTY);
|
||||
return properties.getProperty(JAV_CONFIG);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getPluginPath()
|
||||
public static String getJavConfigBackup()
|
||||
{
|
||||
String pluginPath = properties.getProperty(PLUGIN_PATH);
|
||||
return pluginPath.equals("") ? null : pluginPath;
|
||||
return properties.getProperty(JAV_CONFIG_BACKUP);
|
||||
}
|
||||
|
||||
public static String[] getPluginDevelopmentPath()
|
||||
public static HttpUrl getPluginHubBase()
|
||||
{
|
||||
// First check if property supplied as environment variable PLUGIN_DEVELOPMENT_PATHS
|
||||
String developmentPluginPaths = System.getenv(PLUGIN_DEVELOPMENT_PATH.replace('.', '_').toUpperCase());
|
||||
|
||||
if (Strings.isNullOrEmpty(developmentPluginPaths))
|
||||
{
|
||||
// Otherwise check the property file
|
||||
developmentPluginPaths = properties.getProperty(PLUGIN_DEVELOPMENT_PATH);
|
||||
}
|
||||
|
||||
return Strings.isNullOrEmpty(developmentPluginPaths) ? new String[0] : developmentPluginPaths.split(";");
|
||||
String version = System.getProperty(PLUGINHUB_VERSION, properties.getProperty(PLUGINHUB_VERSION));
|
||||
return HttpUrl.parse(properties.get(PLUGINHUB_BASE) + "/" + version);
|
||||
}
|
||||
|
||||
public static String getImgurClientId()
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import io.reactivex.rxjava3.core.Completable;
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -36,6 +35,7 @@ import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
@@ -44,73 +44,62 @@ class SessionClient
|
||||
{
|
||||
private final OkHttpClient okHttpClient;
|
||||
|
||||
Observable<UUID> openSession()
|
||||
UUID open() throws IOException
|
||||
{
|
||||
final HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
.addPathSegment("new")
|
||||
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
.build();
|
||||
|
||||
return Observable.fromCallable(() ->
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
ResponseBody body = response.body();
|
||||
|
||||
InputStream in = body.byteStream();
|
||||
try
|
||||
{
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), UUID.class);
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
ResponseBody body = response.body();
|
||||
|
||||
InputStream in = body.byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), UUID.class);
|
||||
}
|
||||
catch (JsonParseException | IllegalArgumentException ex) // UUID.fromString can throw IllegalArgumentException
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Completable pingSession(UUID uuid)
|
||||
void ping(UUID uuid, boolean loggedIn) throws IOException
|
||||
{
|
||||
final HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
.addPathSegment("ping")
|
||||
.addQueryParameter("uuid", uuid.toString())
|
||||
.addQueryParameter("session", uuid.toString())
|
||||
.addQueryParameter("logged-in", String.valueOf(loggedIn))
|
||||
.build();
|
||||
|
||||
return Completable.fromAction(() ->
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(null, new byte[0]))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
try (Response response = okHttpClient.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unsuccessful ping");
|
||||
}
|
||||
throw new IOException("Unsuccessful ping");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Completable delete(UUID uuid)
|
||||
void delete(UUID uuid) throws IOException
|
||||
{
|
||||
final HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
.addQueryParameter("session", uuid.toString())
|
||||
.build();
|
||||
|
||||
return Completable.fromAction(() ->
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.delete()
|
||||
.url(url)
|
||||
.build();
|
||||
Request request = new Request.Builder()
|
||||
.delete()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
okHttpClient.newCall(request).execute().close();
|
||||
});
|
||||
okHttpClient.newCall(request).execute().close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
package net.runelite.client.account;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -37,11 +36,13 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.util.LinkBrowser;
|
||||
@@ -55,31 +56,35 @@ import okhttp3.OkHttpClient;
|
||||
@Slf4j
|
||||
public class SessionManager
|
||||
{
|
||||
private static final File SESSION_FILE = new File(RuneLite.RUNELITE_DIR, "session");
|
||||
|
||||
@Getter
|
||||
private AccountSession accountSession;
|
||||
|
||||
private final EventBus eventBus;
|
||||
private final ConfigManager configManager;
|
||||
private final WSClient wsClient;
|
||||
private final File sessionFile;
|
||||
private final AccountClient accountClient;
|
||||
|
||||
@Inject
|
||||
private SessionManager(
|
||||
@Named("sessionfile") File sessionfile,
|
||||
ConfigManager configManager,
|
||||
EventBus eventBus,
|
||||
WSClient wsClient,
|
||||
OkHttpClient okHttpClient)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.eventBus = eventBus;
|
||||
this.wsClient = wsClient;
|
||||
this.sessionFile = sessionfile;
|
||||
this.accountClient = new AccountClient(okHttpClient);
|
||||
|
||||
this.eventBus.subscribe(LoginResponse.class, this, this::onLoginResponse);
|
||||
eventBus.register(this);
|
||||
}
|
||||
|
||||
public void loadSession()
|
||||
{
|
||||
if (!SESSION_FILE.exists())
|
||||
if (!sessionFile.exists())
|
||||
{
|
||||
log.info("No session file exists");
|
||||
return;
|
||||
@@ -87,7 +92,7 @@ public class SessionManager
|
||||
|
||||
AccountSession session;
|
||||
|
||||
try (FileInputStream in = new FileInputStream(SESSION_FILE))
|
||||
try (FileInputStream in = new FileInputStream(sessionFile))
|
||||
{
|
||||
session = new Gson().fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), AccountSession.class);
|
||||
|
||||
@@ -101,26 +106,13 @@ public class SessionManager
|
||||
|
||||
// Check if session is still valid
|
||||
accountClient.setUuid(session.getUuid());
|
||||
accountClient.sessionCheck()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(b ->
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
log.debug("Loaded session {} is invalid", session.getUuid());
|
||||
}
|
||||
else
|
||||
{
|
||||
openSession(session, false);
|
||||
}
|
||||
}, ex ->
|
||||
{
|
||||
if (ex instanceof IOException)
|
||||
{
|
||||
log.debug("Unable to verify session", ex);
|
||||
openSession(session, false);
|
||||
}
|
||||
});
|
||||
if (!accountClient.sessionCheck())
|
||||
{
|
||||
log.debug("Loaded session {} is invalid", session.getUuid());
|
||||
return;
|
||||
}
|
||||
|
||||
openSession(session, false);
|
||||
}
|
||||
|
||||
private void saveSession()
|
||||
@@ -130,11 +122,11 @@ public class SessionManager
|
||||
return;
|
||||
}
|
||||
|
||||
try (Writer fw = new OutputStreamWriter(new FileOutputStream(SESSION_FILE), StandardCharsets.UTF_8))
|
||||
try (Writer fw = new OutputStreamWriter(new FileOutputStream(sessionFile), StandardCharsets.UTF_8))
|
||||
{
|
||||
new Gson().toJson(accountSession, fw);
|
||||
|
||||
log.debug("Saved session to {}", SESSION_FILE);
|
||||
log.debug("Saved session to {}", sessionFile);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
@@ -144,7 +136,7 @@ public class SessionManager
|
||||
|
||||
private void deleteSession()
|
||||
{
|
||||
SESSION_FILE.delete();
|
||||
sessionFile.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +155,14 @@ public class SessionManager
|
||||
|
||||
accountSession = session;
|
||||
|
||||
eventBus.post(SessionOpen.class, new SessionOpen());
|
||||
if (session.getUsername() != null)
|
||||
{
|
||||
// Initialize config for new session
|
||||
// If the session isn't logged in yet, don't switch to the new config
|
||||
configManager.switchSession(session);
|
||||
}
|
||||
|
||||
eventBus.post(new SessionOpen());
|
||||
}
|
||||
|
||||
private void closeSession()
|
||||
@@ -189,7 +188,10 @@ public class SessionManager
|
||||
|
||||
accountSession = null; // No more account
|
||||
|
||||
eventBus.post(SessionClose.class, new SessionClose());
|
||||
// Restore config
|
||||
configManager.switchSession(null);
|
||||
|
||||
eventBus.post(new SessionClose());
|
||||
}
|
||||
|
||||
public void login()
|
||||
@@ -217,7 +219,8 @@ public class SessionManager
|
||||
LinkBrowser.browse(login.getOauthUrl());
|
||||
}
|
||||
|
||||
private void onLoginResponse(LoginResponse loginResponse)
|
||||
@Subscribe
|
||||
public void onLoginResponse(LoginResponse loginResponse)
|
||||
{
|
||||
log.debug("Now logged in as {}", loginResponse.getUsername());
|
||||
|
||||
|
||||
@@ -25,34 +25,22 @@
|
||||
package net.runelite.client.callback;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
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;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ClientThread implements Executor
|
||||
public class ClientThread
|
||||
{
|
||||
private final ConcurrentLinkedQueue<BooleanSupplier> invokes = new ConcurrentLinkedQueue<>();
|
||||
|
||||
@Inject
|
||||
@Nullable
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread()
|
||||
{
|
||||
RxJavaPlugins.setSingleSchedulerHandler(old -> Schedulers.from(this));
|
||||
}
|
||||
|
||||
public void invoke(Runnable r)
|
||||
{
|
||||
invoke(() ->
|
||||
@@ -124,14 +112,4 @@ public class ClientThread implements Executor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull Runnable r)
|
||||
{
|
||||
invoke(() ->
|
||||
{
|
||||
r.run();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.callback;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
@@ -40,31 +39,25 @@ import java.awt.image.VolatileImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.BufferProvider;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Entity;
|
||||
import net.runelite.api.MainBufferProvider;
|
||||
import net.runelite.api.NullItemID;
|
||||
import net.runelite.api.RenderOverview;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.WorldMapManager;
|
||||
import net.runelite.api.events.BeforeMenuRender;
|
||||
import net.runelite.api.events.BeforeRender;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.api.events.FakeXpDrop;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.hooks.Callbacks;
|
||||
import net.runelite.api.hooks.DrawCallbacks;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_VIEW;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.events.DrawFinished;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.task.Scheduler;
|
||||
@@ -75,7 +68,6 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.DeferredEventBus;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.RSTimeUnit;
|
||||
|
||||
/**
|
||||
@@ -89,19 +81,17 @@ public class Hooks implements Callbacks
|
||||
{
|
||||
private static final long CHECK = RSTimeUnit.GAME_TICKS.getDuration().toNanos(); // ns - how often to run checks
|
||||
|
||||
private static final Injector injector = RuneLite.getInjector();
|
||||
private static final Client client = injector.getInstance(Client.class);
|
||||
public static final OverlayRenderer renderer = injector.getInstance(OverlayRenderer.class);
|
||||
private static final OverlayManager overlayManager = injector.getInstance(OverlayManager.class);
|
||||
private static final GameTick GAME_TICK = new GameTick();
|
||||
private static final BeforeRender BEFORE_RENDER = new BeforeRender();
|
||||
|
||||
private static final GameTick GAME_TICK = GameTick.INSTANCE;
|
||||
private static final BeforeRender BEFORE_RENDER = BeforeRender.INSTANCE;
|
||||
private static final DrawFinished drawFinishedEvent = new DrawFinished();
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
private int mouseX = 0;
|
||||
private int mouseY = 0;
|
||||
private final Image cursor = ImageUtil.getResourceStreamFromClass(Hooks.class, "cursor.png");
|
||||
@Inject
|
||||
private OverlayRenderer renderer;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
@@ -145,7 +135,7 @@ public class Hooks implements Callbacks
|
||||
private boolean shouldProcessGameTick;
|
||||
|
||||
private static MainBufferProvider lastMainBufferProvider;
|
||||
public static Graphics2D lastGraphics;
|
||||
private static Graphics2D lastGraphics;
|
||||
|
||||
/**
|
||||
* Get the Graphics2D for the MainBufferProvider image
|
||||
@@ -170,15 +160,15 @@ public class Hooks implements Callbacks
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Event, E extends T> void post(Class<T> eventClass, E event)
|
||||
public void post(Object event)
|
||||
{
|
||||
eventBus.post(eventClass, event);
|
||||
eventBus.post(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Event, E extends T> void postDeferred(Class<T> eventClass, E event)
|
||||
public void postDeferred(Object event)
|
||||
{
|
||||
deferredEventBus.post(eventClass, event);
|
||||
deferredEventBus.post(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -190,13 +180,13 @@ public class Hooks implements Callbacks
|
||||
|
||||
deferredEventBus.replay();
|
||||
|
||||
eventBus.post(GameTick.class, GameTick.INSTANCE);
|
||||
eventBus.post(GAME_TICK);
|
||||
|
||||
int tick = client.getTickCount();
|
||||
client.setTickCount(tick + 1);
|
||||
}
|
||||
|
||||
eventBus.post(BeforeRender.class, BeforeRender.INSTANCE);
|
||||
eventBus.post(BEFORE_RENDER);
|
||||
|
||||
clientThread.invoke();
|
||||
|
||||
@@ -293,16 +283,12 @@ public class Hooks implements Callbacks
|
||||
@Override
|
||||
public MouseEvent mouseDragged(MouseEvent mouseEvent)
|
||||
{
|
||||
mouseX = mouseEvent.getX();
|
||||
mouseY = mouseEvent.getY();
|
||||
return mouseManager.processMouseDragged(mouseEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseMoved(MouseEvent mouseEvent)
|
||||
{
|
||||
mouseX = mouseEvent.getX();
|
||||
mouseY = mouseEvent.getY();
|
||||
return mouseManager.processMouseMoved(mouseEvent);
|
||||
}
|
||||
|
||||
@@ -405,22 +391,6 @@ public class Hooks implements Callbacks
|
||||
finalImage = image;
|
||||
}
|
||||
|
||||
if (client.isMirrored())
|
||||
{
|
||||
drawFinishedEvent.image = copy(finalImage);
|
||||
drawFinishedEvent.image.getGraphics().drawImage(cursor, mouseX, mouseY, null);
|
||||
eventBus.post(DrawFinished.class, drawFinishedEvent);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
renderer.render((Graphics2D)finalImage.getGraphics(), OverlayLayer.AFTER_MIRROR);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn("Error during post-mirror rendering", ex);
|
||||
}
|
||||
|
||||
// Draw the image onto the game canvas
|
||||
graphics.drawImage(finalImage, 0, 0, client.getCanvas());
|
||||
|
||||
@@ -431,6 +401,8 @@ public class Hooks implements Callbacks
|
||||
|
||||
/**
|
||||
* Copy an image
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
private static Image copy(Image src)
|
||||
{
|
||||
@@ -475,7 +447,8 @@ public class Hooks implements Callbacks
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawAfterWidgets()
|
||||
@Override
|
||||
public void drawAfterWidgets()
|
||||
{
|
||||
MainBufferProvider bufferProvider = (MainBufferProvider) client.getBufferProvider();
|
||||
Graphics2D graphics2d = getGraphics(bufferProvider);
|
||||
@@ -495,6 +468,7 @@ public class Hooks implements Callbacks
|
||||
overlayManager.getItemWidgets().clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
switch (gameStateChanged.getGameState())
|
||||
@@ -530,38 +504,6 @@ public class Hooks implements Callbacks
|
||||
deferredEventBus.replay();
|
||||
}
|
||||
|
||||
public static void renderDraw(Entity entity, int orientation, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y, int z, long hash)
|
||||
{
|
||||
DrawCallbacks drawCallbacks = client.getDrawCallbacks();
|
||||
if (drawCallbacks != null)
|
||||
{
|
||||
drawCallbacks.draw(entity, orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.draw(orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash);
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearColorBuffer(int x, int y, int width, int height, int color)
|
||||
{
|
||||
BufferProvider bp = client.getBufferProvider();
|
||||
int canvasWidth = bp.getWidth();
|
||||
int[] pixels = bp.getPixels();
|
||||
|
||||
int pixelPos = y * canvasWidth + x;
|
||||
int pixelJump = canvasWidth - width;
|
||||
|
||||
for (int cy = y; cy < y + height; cy++)
|
||||
{
|
||||
for (int cx = x; cx < x + width; cx++)
|
||||
{
|
||||
pixels[pixelPos++] = 0;
|
||||
}
|
||||
pixelPos += pixelJump;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawItem(int itemId, WidgetItem widgetItem)
|
||||
{
|
||||
@@ -572,13 +514,7 @@ public class Hooks implements Callbacks
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean drawMenu()
|
||||
{
|
||||
BeforeMenuRender event = new BeforeMenuRender();
|
||||
client.getCallbacks().post(BeforeMenuRender.class, event);
|
||||
return event.isConsumed();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
|
||||
{
|
||||
if (!scriptCallbackEvent.getEventName().equals("fakeXpDrop"))
|
||||
@@ -597,6 +533,6 @@ public class Hooks implements Callbacks
|
||||
skill,
|
||||
xp
|
||||
);
|
||||
eventBus.post(FakeXpDrop.class, fakeXpDrop);
|
||||
eventBus.post(fakeXpDrop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,21 +41,20 @@ import net.runelite.client.events.ChatboxInput;
|
||||
import net.runelite.client.events.PrivateMessageInput;
|
||||
|
||||
@Singleton
|
||||
public class ChatCommandManager
|
||||
public class ChatCommandManager implements ChatboxInputListener
|
||||
{
|
||||
private final Map<String, ChatCommand> commands = new ConcurrentHashMap<>();
|
||||
|
||||
private final Client client;
|
||||
private final ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
@Inject
|
||||
private ChatCommandManager(EventBus eventBus, Client client, ScheduledExecutorService scheduledExecutorService)
|
||||
private ChatCommandManager(EventBus eventBus, CommandManager commandManager, Client client, ScheduledExecutorService scheduledExecutorService)
|
||||
{
|
||||
this.client = client;
|
||||
this.scheduledExecutorService = scheduledExecutorService;
|
||||
|
||||
eventBus.subscribe(ChatboxInput.class, this, this::onChatboxInput);
|
||||
eventBus.subscribe(PrivateMessageInput.class, this, this::onPrivateMessageInput);
|
||||
eventBus.subscribe(ChatMessage.class, this, this::onChatMessage);
|
||||
eventBus.register(this);
|
||||
commandManager.register(this);
|
||||
}
|
||||
|
||||
public void registerCommand(String command, BiConsumer<ChatMessage, String> execute)
|
||||
@@ -83,7 +82,8 @@ public class ChatCommandManager
|
||||
commands.remove(command.toLowerCase());
|
||||
}
|
||||
|
||||
private void onChatMessage(ChatMessage chatMessage)
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
@@ -106,6 +106,11 @@ public class ChatCommandManager
|
||||
String message = chatMessage.getMessage();
|
||||
|
||||
String command = extractCommand(message);
|
||||
if (command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChatCommand chatCommand = commands.get(command.toLowerCase());
|
||||
if (chatCommand == null)
|
||||
{
|
||||
@@ -122,8 +127,8 @@ public class ChatCommandManager
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe // just for show
|
||||
private void onChatboxInput(ChatboxInput chatboxInput)
|
||||
@Override
|
||||
public boolean onChatboxInput(ChatboxInput chatboxInput)
|
||||
{
|
||||
String message = chatboxInput.getValue();
|
||||
if (message.startsWith("/"))
|
||||
@@ -131,30 +136,51 @@ public class ChatCommandManager
|
||||
message = message.substring(1); // friends chat input
|
||||
}
|
||||
|
||||
onInput(chatboxInput, message);
|
||||
}
|
||||
|
||||
@Subscribe // just for show
|
||||
private void onPrivateMessageInput(PrivateMessageInput input)
|
||||
{
|
||||
onInput(input, input.getMessage());
|
||||
}
|
||||
|
||||
private void onInput(ChatInput chatInput, String message)
|
||||
{
|
||||
String command = extractCommand(message);
|
||||
if (command == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ChatCommand chatCommand = commands.get(command.toLowerCase());
|
||||
if (chatCommand == null)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
BiPredicate<ChatInput, String> input = chatCommand.getInput();
|
||||
if (input != null && input.test(chatInput, message))
|
||||
if (input == null)
|
||||
{
|
||||
chatInput.setStop();
|
||||
return false;
|
||||
}
|
||||
|
||||
return input.test(chatboxInput, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrivateMessageInput(PrivateMessageInput privateMessageInput)
|
||||
{
|
||||
final String message = privateMessageInput.getMessage();
|
||||
|
||||
String command = extractCommand(message);
|
||||
if (command == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ChatCommand chatCommand = commands.get(command.toLowerCase());
|
||||
if (chatCommand == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BiPredicate<ChatInput, String> input = chatCommand.getInput();
|
||||
if (input == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return input.test(privateMessageInput, message);
|
||||
}
|
||||
|
||||
private static String extractCommand(String message)
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
package net.runelite.client.chat;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
public class ChatMessageBuilder
|
||||
{
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
*/
|
||||
package net.runelite.client.chat;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.awt.Color;
|
||||
import java.util.Arrays;
|
||||
@@ -44,20 +46,20 @@ import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.api.events.ResizeableChanged;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ChatColorConfig;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.ui.JagexColors;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@Singleton
|
||||
public class ChatMessageManager
|
||||
{
|
||||
private static final Set<Integer> TUTORIAL_ISLAND_REGIONS = Set.of(12336, 12335, 12592, 12080, 12079, 12436);
|
||||
private static final Set<Integer> TUTORIAL_ISLAND_REGIONS = ImmutableSet.of(12336, 12335, 12592, 12080, 12079, 12436);
|
||||
|
||||
private final Multimap<ChatMessageType, ChatColor> colorCache = HashMultimap.create();
|
||||
private final Client client;
|
||||
@@ -68,23 +70,17 @@ public class ChatMessageManager
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager(
|
||||
final Client client,
|
||||
final ChatColorConfig chatColorConfig,
|
||||
final ClientThread clientThread,
|
||||
final EventBus eventbus)
|
||||
Client client,
|
||||
ChatColorConfig chatColorConfig,
|
||||
ClientThread clientThread)
|
||||
{
|
||||
this.client = client;
|
||||
this.chatColorConfig = chatColorConfig;
|
||||
this.clientThread = clientThread;
|
||||
|
||||
eventbus.subscribe(VarbitChanged.class, this, this::onVarbitChanged);
|
||||
eventbus.subscribe(ResizeableChanged.class, this, this::onResizeableChanged);
|
||||
eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventbus.subscribe(ChatMessage.class, this, this::onChatMessage);
|
||||
eventbus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent);
|
||||
}
|
||||
|
||||
private void onVarbitChanged(VarbitChanged event)
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
int setting = client.getVar(Varbits.TRANSPARENT_CHATBOX);
|
||||
|
||||
@@ -95,12 +91,14 @@ public class ChatMessageManager
|
||||
}
|
||||
}
|
||||
|
||||
private void onResizeableChanged(ResizeableChanged event)
|
||||
@Subscribe
|
||||
public void onResizeableChanged(ResizeableChanged event)
|
||||
{
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("textrecolor"))
|
||||
{
|
||||
@@ -109,7 +107,8 @@ public class ChatMessageManager
|
||||
}
|
||||
}
|
||||
|
||||
void onChatMessage(ChatMessage chatMessage)
|
||||
@Subscribe(priority = -1) // run after all plugins
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
MessageNode messageNode = chatMessage.getMessageNode();
|
||||
ChatMessageType chatMessageType = chatMessage.getType();
|
||||
@@ -174,7 +173,8 @@ public class ChatMessageManager
|
||||
}
|
||||
}
|
||||
|
||||
private void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
|
||||
{
|
||||
final String eventName = scriptCallbackEvent.getEventName();
|
||||
|
||||
@@ -571,17 +571,11 @@ public class ChatMessageManager
|
||||
return;
|
||||
}
|
||||
|
||||
//guard case for google MoreObjects#firstNonNull
|
||||
if (message.getValue() == null && message.getRuneLiteFormattedMessage() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// this updates chat cycle
|
||||
client.addChatMessage(
|
||||
message.getType(),
|
||||
Objects.requireNonNullElse(message.getName(), ""),
|
||||
Objects.requireNonNullElse(message.getValue(), message.getRuneLiteFormattedMessage()),
|
||||
MoreObjects.firstNonNull(message.getName(), ""),
|
||||
MoreObjects.firstNonNull(message.getValue(), message.getRuneLiteFormattedMessage()),
|
||||
message.getSender());
|
||||
|
||||
// Get last message from line buffer (the one we just added)
|
||||
@@ -591,7 +585,7 @@ public class ChatMessageManager
|
||||
|
||||
// Update the message with RuneLite additions
|
||||
line.setRuneLiteFormatMessage(message.getRuneLiteFormattedMessage());
|
||||
|
||||
|
||||
if (message.getTimestamp() != 0)
|
||||
{
|
||||
line.setTimestamp(message.getTimestamp());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,25 +22,14 @@
|
||||
* (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.discord;
|
||||
package net.runelite.client.chat;
|
||||
|
||||
/**
|
||||
* Discord reply type for request
|
||||
*/
|
||||
public enum DiscordReplyType
|
||||
import net.runelite.client.events.ChatboxInput;
|
||||
import net.runelite.client.events.PrivateMessageInput;
|
||||
|
||||
public interface ChatboxInputListener
|
||||
{
|
||||
/**
|
||||
* Used to decline a request
|
||||
*/
|
||||
NO,
|
||||
boolean onChatboxInput(ChatboxInput chatboxInput);
|
||||
|
||||
/**
|
||||
* Used to accept a request
|
||||
*/
|
||||
YES,
|
||||
|
||||
/**
|
||||
* Currently unused response, treated like NO.
|
||||
*/
|
||||
IGNORE
|
||||
boolean onPrivateMessageInput(PrivateMessageInput privateMessageInput);
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
package net.runelite.client.chat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -36,6 +38,7 @@ import net.runelite.api.events.CommandExecuted;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ChatboxInput;
|
||||
import net.runelite.client.events.PrivateMessageInput;
|
||||
|
||||
@@ -52,20 +55,27 @@ public class CommandManager
|
||||
private final ClientThread clientThread;
|
||||
private boolean sending;
|
||||
|
||||
private final List<ChatboxInputListener> chatboxInputListenerList = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Inject
|
||||
private CommandManager(
|
||||
final Client client,
|
||||
final EventBus eventBus,
|
||||
final ClientThread clientThread
|
||||
)
|
||||
private CommandManager(Client client, EventBus eventBus, ClientThread clientThread)
|
||||
{
|
||||
this.client = client;
|
||||
this.eventBus = eventBus;
|
||||
this.clientThread = clientThread;
|
||||
|
||||
eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent);
|
||||
}
|
||||
|
||||
public void register(ChatboxInputListener chatboxInputListener)
|
||||
{
|
||||
chatboxInputListenerList.add(chatboxInputListener);
|
||||
}
|
||||
|
||||
public void unregister(ChatboxInputListener chatboxInputListener)
|
||||
{
|
||||
chatboxInputListenerList.remove(chatboxInputListener);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
if (sending)
|
||||
@@ -105,7 +115,7 @@ public class CommandManager
|
||||
String[] args = Arrays.copyOfRange(split, 1, split.length);
|
||||
|
||||
CommandExecuted commandExecuted = new CommandExecuted(command, args);
|
||||
eventBus.post(CommandExecuted.class, commandExecuted);
|
||||
eventBus.post(commandExecuted);
|
||||
}
|
||||
|
||||
private void handleInput(ScriptCallbackEvent event)
|
||||
@@ -134,10 +144,13 @@ public class CommandManager
|
||||
clientThread.invoke(() -> sendChatboxInput(chatType, typedText));
|
||||
}
|
||||
};
|
||||
boolean stop = false;
|
||||
for (ChatboxInputListener chatboxInputListener : chatboxInputListenerList)
|
||||
{
|
||||
stop |= chatboxInputListener.onChatboxInput(chatboxInput);
|
||||
}
|
||||
|
||||
eventBus.post(ChatboxInput.class, chatboxInput);
|
||||
|
||||
if (chatboxInput.isStop())
|
||||
if (stop)
|
||||
{
|
||||
// input was blocked.
|
||||
stringStack[stringStackCount - 1] = ""; // prevent script from sending
|
||||
@@ -171,9 +184,13 @@ public class CommandManager
|
||||
}
|
||||
};
|
||||
|
||||
eventBus.post(PrivateMessageInput.class, privateMessageInput);
|
||||
boolean stop = false;
|
||||
for (ChatboxInputListener chatboxInputListener : chatboxInputListenerList)
|
||||
{
|
||||
stop |= chatboxInputListener.onPrivateMessageInput(privateMessageInput);
|
||||
}
|
||||
|
||||
if (privateMessageInput.isStop())
|
||||
if (stop)
|
||||
{
|
||||
intStack[intStackCount - 1] = 1;
|
||||
client.setStringStackSize(stringStackCount - 2); // remove both target and message
|
||||
|
||||
@@ -37,4 +37,6 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Documented
|
||||
public @interface Alpha {}
|
||||
public @interface Alpha
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
package net.runelite.client.config;
|
||||
|
||||
public class Button {}
|
||||
@@ -30,34 +30,28 @@ import net.runelite.client.ui.JagexColors;
|
||||
@ConfigGroup("textrecolor")
|
||||
public interface ChatColorConfig extends Config
|
||||
{
|
||||
@ConfigTitleSection(
|
||||
keyName = "opaqueTitle",
|
||||
@ConfigSection(
|
||||
name = "Opaque",
|
||||
description = "",
|
||||
position = 1
|
||||
description = "The options that control the colours for the Opaque Chatbox",
|
||||
position = 0,
|
||||
closedByDefault = true
|
||||
)
|
||||
default Title opaqueTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
String opaqueSection = "opaqueSection";
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "transparentTitle",
|
||||
@ConfigSection(
|
||||
name = "Transparent",
|
||||
description = "",
|
||||
position = 1
|
||||
description = "The options that control the colours for the Transparent Chatbox",
|
||||
position = 50,
|
||||
closedByDefault = true
|
||||
)
|
||||
default Title transparentTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
String transparentSection = "transparentSection";
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "opaquePublicChat",
|
||||
name = "Public chat",
|
||||
description = "Color of Public chat",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaquePublicChat();
|
||||
|
||||
@@ -66,7 +60,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaquePublicChatHighlight",
|
||||
name = "Public chat highlight",
|
||||
description = "Color of highlights in Public chat",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaquePublicChatHighlight()
|
||||
{
|
||||
@@ -78,7 +72,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaquePrivateMessageSent",
|
||||
name = "Sent private messages",
|
||||
description = "Color of Private messages you've sent",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaquePrivateMessageSent();
|
||||
|
||||
@@ -87,7 +81,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaquePrivateMessageSentHighlight",
|
||||
name = "Sent private messages highlight",
|
||||
description = "Color of highlights in Private messages you've sent",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaquePrivateMessageSentHighlight()
|
||||
{
|
||||
@@ -99,7 +93,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaquePrivateMessageReceived",
|
||||
name = "Received private messages",
|
||||
description = "Color of Private messages you've received",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaquePrivateMessageReceived();
|
||||
|
||||
@@ -108,7 +102,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaquePrivateMessageReceivedHighlight",
|
||||
name = "Received private messages highlight",
|
||||
description = "Color of highlights in Private messages you've received",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaquePrivateMessageReceivedHighlight()
|
||||
{
|
||||
@@ -120,7 +114,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueClanChatInfo",
|
||||
name = "Friends chat info",
|
||||
description = "Friends Chat Information (eg. when joining a channel)",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaqueFriendsChatInfo()
|
||||
{
|
||||
@@ -132,7 +126,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueClanChatInfoHighlight",
|
||||
name = "Friends chat info highlight",
|
||||
description = "Friends Chat Information highlight (used for the Raids plugin)",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaqueFriendsChatInfoHighlight()
|
||||
{
|
||||
@@ -144,7 +138,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueClanChatMessage",
|
||||
name = "Friends chat message",
|
||||
description = "Color of Friends chat messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueFriendsChatMessage();
|
||||
|
||||
@@ -153,7 +147,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueClanChatMessageHighlight",
|
||||
name = "Friends chat message highlight",
|
||||
description = "Color of highlights in Friends Chat messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaqueFriendsChatMessageHighlight()
|
||||
{
|
||||
@@ -165,7 +159,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueAutochatMessage",
|
||||
name = "Autochat",
|
||||
description = "Color of Autochat messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueAutochatMessage();
|
||||
|
||||
@@ -174,7 +168,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueAutochatMessageHighlight",
|
||||
name = "Autochat highlight",
|
||||
description = "Color of highlights in Autochat messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueAutochatMessageHighlight();
|
||||
|
||||
@@ -183,7 +177,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueTradeChatMessage",
|
||||
name = "Trade chat",
|
||||
description = "Color of Trade Chat Messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueTradeChatMessage();
|
||||
|
||||
@@ -192,7 +186,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueTradeChatMessageHighlight",
|
||||
name = "Trade chat highlight",
|
||||
description = "Color of highlights in Trade Chat Messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueTradeChatMessageHighlight();
|
||||
|
||||
@@ -201,7 +195,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueServerMessage",
|
||||
name = "Server message",
|
||||
description = "Color of Server Messages (eg. 'Welcome to RuneScape')",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueServerMessage();
|
||||
|
||||
@@ -210,7 +204,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueServerMessageHighlight",
|
||||
name = "Server message highlight",
|
||||
description = "Color of highlights in Server Messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueServerMessageHighlight();
|
||||
|
||||
@@ -219,7 +213,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueGameMessage",
|
||||
name = "Game message",
|
||||
description = "Color of Game Messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueGameMessage();
|
||||
|
||||
@@ -228,7 +222,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueGameMessageHighlight",
|
||||
name = "Game message highlight",
|
||||
description = "Color of highlights in Game Messages",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaqueGameMessageHighlight()
|
||||
{
|
||||
@@ -240,7 +234,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueExamine",
|
||||
name = "Examine",
|
||||
description = "Color of Examine Text",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueExamine();
|
||||
|
||||
@@ -249,7 +243,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueExamineHighlight",
|
||||
name = "Examine highlight",
|
||||
description = "Color of highlights in Examine Text",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
default Color opaqueExamineHighlight()
|
||||
{
|
||||
@@ -261,7 +255,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueFiltered",
|
||||
name = "Filtered",
|
||||
description = "Color of Filtered Text (messages that aren't shown when Game messages are filtered)",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueFiltered();
|
||||
|
||||
@@ -270,7 +264,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueFilteredHighlight",
|
||||
name = "Filtered highlight",
|
||||
description = "Color of highlights in Filtered Text",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueFilteredHighlight();
|
||||
|
||||
@@ -279,7 +273,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueUsername",
|
||||
name = "Usernames",
|
||||
description = "Color of Usernames",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueUsername();
|
||||
|
||||
@@ -288,7 +282,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaquePrivateUsernames",
|
||||
name = "Private chat usernames",
|
||||
description = "Color of Usernames in Private Chat",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaquePrivateUsernames();
|
||||
|
||||
@@ -297,7 +291,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueClanChannelName",
|
||||
name = "Friends chat channel name",
|
||||
description = "Color of Friends chat channel name",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueFriendsChatChannelName();
|
||||
|
||||
@@ -306,7 +300,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaqueClanUsernames",
|
||||
name = "Friends chat usernames",
|
||||
description = "Color of usernames in Friends chat",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaqueFriendsChatUsernames();
|
||||
|
||||
@@ -315,7 +309,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "opaquePublicFriendUsernames",
|
||||
name = "Public friend usernames",
|
||||
description = "Color of Friend Usernames in Public Chat",
|
||||
titleSection = "opaqueTitle"
|
||||
section = opaqueSection
|
||||
)
|
||||
Color opaquePublicFriendUsernames();
|
||||
|
||||
@@ -324,7 +318,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPublicChat",
|
||||
name = "Public chat (transparent)",
|
||||
description = "Color of Public chat (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentPublicChat();
|
||||
|
||||
@@ -333,7 +327,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPublicChatHighlight",
|
||||
name = "Public chat highlight (transparent)",
|
||||
description = "Color of highlights in Public chat (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentPublicChatHighlight()
|
||||
{
|
||||
@@ -345,7 +339,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPrivateMessageSent",
|
||||
name = "Sent private messages (transparent)",
|
||||
description = "Color of Private messages you've sent (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentPrivateMessageSent();
|
||||
|
||||
@@ -354,7 +348,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPrivateMessageSentHighlight",
|
||||
name = "Sent private messages highlight (transparent)",
|
||||
description = "Color of highlights in Private messages you've sent (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentPrivateMessageSentHighlight()
|
||||
{
|
||||
@@ -366,7 +360,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPrivateMessageReceived",
|
||||
name = "Received private messages (transparent)",
|
||||
description = "Color of Private messages you've received (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentPrivateMessageReceived();
|
||||
|
||||
@@ -375,7 +369,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPrivateMessageReceivedHighlight",
|
||||
name = "Received private messages highlight (transparent)",
|
||||
description = "Color of highlights in Private messages you've received (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentPrivateMessageReceivedHighlight()
|
||||
{
|
||||
@@ -387,7 +381,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentClanChatInfo",
|
||||
name = "Friends chat info (transparent)",
|
||||
description = "Friends chat information (eg. when joining a channel) (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentFriendsChatInfo()
|
||||
{
|
||||
@@ -399,7 +393,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentClanChatInfoHighlight",
|
||||
name = "Friends chat info highlight (transparent)",
|
||||
description = "Friends chat information highlight (used for the Raids plugin) (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentFriendsChatInfoHighlight()
|
||||
{
|
||||
@@ -411,7 +405,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentClanChatMessage",
|
||||
name = "Friends chat message (transparent)",
|
||||
description = "Color of Friends chat messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentFriendsChatMessage();
|
||||
|
||||
@@ -420,7 +414,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentClanChatMessageHighlight",
|
||||
name = "Friends chat message highlight (transparent)",
|
||||
description = "Color of highlights in Friends chat messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentFriendsChatMessageHighlight()
|
||||
{
|
||||
@@ -432,7 +426,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentAutochatMessage",
|
||||
name = "Autochat (transparent)",
|
||||
description = "Color of Autochat messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentAutochatMessage();
|
||||
|
||||
@@ -441,7 +435,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentAutochatMessageHighlight",
|
||||
name = "Autochat highlight (transparent)",
|
||||
description = "Color of highlights in Autochat messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentAutochatMessageHighlight();
|
||||
|
||||
@@ -450,7 +444,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentTradeChatMessage",
|
||||
name = "Trade chat (transparent)",
|
||||
description = "Color of Trade Chat Messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentTradeChatMessage();
|
||||
|
||||
@@ -459,7 +453,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentTradeChatMessageHighlight",
|
||||
name = "Trade chat highlight (transparent)",
|
||||
description = "Color of highlights in Trade Chat Messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentTradeChatMessageHighlight();
|
||||
|
||||
@@ -468,7 +462,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentServerMessage",
|
||||
name = "Server message (transparent)",
|
||||
description = "Color of Server Messages (eg. 'Welcome to RuneScape') (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentServerMessage();
|
||||
|
||||
@@ -477,7 +471,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentServerMessageHighlight",
|
||||
name = "Server message highlight (transparent)",
|
||||
description = "Color of highlights in Server Messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentServerMessageHighlight();
|
||||
|
||||
@@ -486,7 +480,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentGameMessage",
|
||||
name = "Game message (transparent)",
|
||||
description = "Color of Game Messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentGameMessage();
|
||||
|
||||
@@ -495,7 +489,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentGameMessageHighlight",
|
||||
name = "Game message highlight (transparent)",
|
||||
description = "Color of highlights in Game Messages (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentGameMessageHighlight()
|
||||
{
|
||||
@@ -507,7 +501,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentExamine",
|
||||
name = "Examine (transparent)",
|
||||
description = "Color of Examine Text (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentExamine();
|
||||
|
||||
@@ -516,7 +510,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentExamineHighlight",
|
||||
name = "Examine highlight (transparent)",
|
||||
description = "Color of highlights in Examine Text (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
default Color transparentExamineHighlight()
|
||||
{
|
||||
@@ -528,7 +522,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentFiltered",
|
||||
name = "Filtered (transparent)",
|
||||
description = "Color of Filtered Text (messages that aren't shown when Game messages are filtered) (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentFiltered();
|
||||
|
||||
@@ -537,7 +531,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentFilteredHighlight",
|
||||
name = "Filtered highlight (transparent)",
|
||||
description = "Color of highlights in Filtered Text (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentFilteredHighlight();
|
||||
|
||||
@@ -546,7 +540,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentUsername",
|
||||
name = "Usernames (transparent)",
|
||||
description = "Color of Usernames (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentUsername();
|
||||
|
||||
@@ -555,7 +549,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPrivateUsernames",
|
||||
name = "Private chat usernames (transparent)",
|
||||
description = "Color of Usernames in Private Chat (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentPrivateUsernames();
|
||||
|
||||
@@ -564,7 +558,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentClanChannelName",
|
||||
name = "Friends chat channel name (transparent)",
|
||||
description = "Color of Friends chat channel name (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentFriendsChatChannelName();
|
||||
|
||||
@@ -573,7 +567,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentClanUsernames",
|
||||
name = "Friends chat usernames (transparent)",
|
||||
description = "Color of usernames in Friends chat (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentFriendsChatUsernames();
|
||||
|
||||
@@ -582,7 +576,7 @@ public interface ChatColorConfig extends Config
|
||||
keyName = "transparentPublicFriendUsernames",
|
||||
name = "Public friend usernames (transparent)",
|
||||
description = "Color of Friend Usernames in Public Chat (transparent)",
|
||||
titleSection = "transparentTitle"
|
||||
section = transparentSection
|
||||
)
|
||||
Color transparentPublicFriendUsernames();
|
||||
}
|
||||
|
||||
@@ -24,4 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
public interface Config {}
|
||||
public interface Config
|
||||
{
|
||||
}
|
||||
|
||||
@@ -24,22 +24,20 @@
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import lombok.Getter;
|
||||
import java.util.Collection;
|
||||
|
||||
@Getter
|
||||
public class ConfigDescriptor
|
||||
{
|
||||
private final ConfigGroup group;
|
||||
private final Collection<ConfigSection> sections;
|
||||
private final Collection<ConfigTitleSection> titleSections;
|
||||
private final Collection<ConfigSectionDescriptor> sections;
|
||||
private final Collection<ConfigItemDescriptor> items;
|
||||
|
||||
public ConfigDescriptor(ConfigGroup group, Collection<ConfigSection> sections, Collection<ConfigTitleSection> titleSections, Collection<ConfigItemDescriptor> items)
|
||||
public ConfigDescriptor(ConfigGroup group, Collection<ConfigSectionDescriptor> sections, Collection<ConfigItemDescriptor> items)
|
||||
{
|
||||
this.group = group;
|
||||
this.sections = sections;
|
||||
this.titleSections = titleSections;
|
||||
this.items = items;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@ package net.runelite.client.config;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.util.ReflectUtil;
|
||||
|
||||
@Slf4j
|
||||
class ConfigInvocationHandler implements InvocationHandler
|
||||
@@ -100,7 +100,7 @@ class ConfigInvocationHandler implements InvocationHandler
|
||||
|
||||
// Convert value to return type
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Object objectValue = ConfigManager.stringToObject(value, returnType);
|
||||
@@ -112,11 +112,7 @@ class ConfigInvocationHandler implements InvocationHandler
|
||||
log.warn("Unable to unmarshal {}.{} ", group.value(), item.keyName(), e);
|
||||
if (method.isDefault())
|
||||
{
|
||||
Object defaultValue = callDefaultMethod(proxy, method, null);
|
||||
|
||||
manager.setConfiguration(group.value(), item.keyName(), defaultValue);
|
||||
|
||||
return defaultValue;
|
||||
return callDefaultMethod(proxy, method, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -127,7 +123,7 @@ class ConfigInvocationHandler implements InvocationHandler
|
||||
|
||||
if (args.length != 1)
|
||||
{
|
||||
throw new RuntimeException("Invalid number of arguents to configuration method");
|
||||
throw new RuntimeException("Invalid number of arguments to configuration method");
|
||||
}
|
||||
|
||||
Object newValue = args[0];
|
||||
@@ -169,7 +165,7 @@ class ConfigInvocationHandler implements InvocationHandler
|
||||
static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
return MethodHandles.privateLookupIn(declaringClass, MethodHandles.lookup())
|
||||
return ReflectUtil.privateLookupIn(declaringClass)
|
||||
.unreflectSpecial(method, declaringClass)
|
||||
.bindTo(proxy)
|
||||
.invokeWithArguments(args);
|
||||
@@ -180,4 +176,4 @@ class ConfigInvocationHandler implements InvocationHandler
|
||||
log.trace("cache invalidate");
|
||||
cache.invalidateAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,143 +33,19 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ConfigItem
|
||||
{
|
||||
/**
|
||||
* If there is a section set, it will display in order
|
||||
* starting from lowest value and ending at highest value
|
||||
* in that specific section. Else, it will display in order
|
||||
* for the config panel in a whole.
|
||||
*
|
||||
* @return The index of the config item.
|
||||
*/
|
||||
int position() default -1;
|
||||
|
||||
/**
|
||||
* This is not visible to users
|
||||
*
|
||||
* @return name used for finding the config item
|
||||
* from the properties map. Hence, KEY name.
|
||||
*/
|
||||
String keyName();
|
||||
|
||||
/**
|
||||
* This is the name that is shown to users when looking
|
||||
* at the config panel.
|
||||
* <p>
|
||||
* Choose a name carefully, as there is a maximum width
|
||||
* that depends on the users DPI scaling. Short is best.
|
||||
*
|
||||
* @return display name for the config item.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* This will be shown to the user if they are hovering
|
||||
* the config item in the config panel.
|
||||
*
|
||||
* @return the description of the config item.
|
||||
*/
|
||||
String description();
|
||||
|
||||
/**
|
||||
* If this is set to true, the config field will be
|
||||
* hidden. You are able to change this value at runtime
|
||||
* by having another config field unhide it {@link #unhide()}
|
||||
*/
|
||||
boolean hidden() default false;
|
||||
|
||||
/**
|
||||
* This is only used for {@link Boolean} config fields.
|
||||
* <p>
|
||||
* If this is set, then a warning(y/n) will be displayed
|
||||
* when the user enables said config field. If they accept
|
||||
* then the value will be set updated.
|
||||
*
|
||||
* @return a warning for enabling the config field.
|
||||
*/
|
||||
String warning() default "";
|
||||
|
||||
/**
|
||||
* This is only used for {@link String} config fields.
|
||||
* <p>
|
||||
* If this is set to true, any input from the user
|
||||
* will be hidden, and not displayed. This should
|
||||
* be used for any sensitive information that may
|
||||
* be accidentally leaked.
|
||||
* <p>
|
||||
* For example; api keys.
|
||||
*/
|
||||
boolean secret() default false;
|
||||
|
||||
/**
|
||||
* If this is set, it will look for a section
|
||||
* by that {@link ConfigSection#name()}, if it exists,
|
||||
* it will insert the config item under that
|
||||
* section in order.
|
||||
*
|
||||
* @return title of the section.
|
||||
*/
|
||||
String section() default "";
|
||||
|
||||
/**
|
||||
* If this is set, it will look for a title section
|
||||
* by that {@link ConfigTitleSection#name()}, if it exists,
|
||||
* it will insert the config item under that
|
||||
* section in order.
|
||||
*
|
||||
* @return title of the section.
|
||||
*/
|
||||
String titleSection() default "";
|
||||
|
||||
/**
|
||||
* If this is set, it will look for a config item
|
||||
* by that name. If it is hidden, it will unhide the item.
|
||||
*
|
||||
* @return {@link #name()} to unhide.
|
||||
*/
|
||||
String unhide() default "";
|
||||
|
||||
String unhideValue() default "";
|
||||
|
||||
/**
|
||||
* If this is set, it will look for a config item
|
||||
* by that name. If it is not hidden, it will hide the item.
|
||||
*
|
||||
* @return {@link #name()} to hide.
|
||||
*/
|
||||
String hide() default "";
|
||||
|
||||
String hideValue() default "";
|
||||
|
||||
/**
|
||||
* If this is set, it will look for a config item
|
||||
* by the name provided, if that config item is enabled
|
||||
* then this item will also be enabled.
|
||||
*/
|
||||
String enabledBy() default "";
|
||||
|
||||
String enabledByValue() default "";
|
||||
|
||||
/**
|
||||
* If this is set, it will look for a config item
|
||||
* by the name provided, if that config item is disabled
|
||||
* then this item will also be disabled.
|
||||
*/
|
||||
String disabledBy() default "";
|
||||
|
||||
String disabledByValue() default "";
|
||||
|
||||
boolean parse() default false;
|
||||
|
||||
Class<?> clazz() default void.class;
|
||||
|
||||
String method() default "";
|
||||
|
||||
/**
|
||||
* Use this to indicate the enum class that is going to be used in the multiple select config.
|
||||
* This implementation made debugging problems with multiple selects a lot easier
|
||||
*
|
||||
* @return The Enum that will be used for the multiple select
|
||||
*/
|
||||
Class<? extends Enum> enumClass() default Enum.class;
|
||||
|
||||
}
|
||||
|
||||
@@ -27,11 +27,29 @@ package net.runelite.client.config;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class ConfigItemDescriptor
|
||||
public class ConfigItemDescriptor implements ConfigObject
|
||||
{
|
||||
private final ConfigItem item;
|
||||
private final Class<?> type;
|
||||
private final Range range;
|
||||
private final Alpha alpha;
|
||||
private final Units units;
|
||||
|
||||
@Override
|
||||
public String key()
|
||||
{
|
||||
return item.keyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return item.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int position()
|
||||
{
|
||||
return item.position();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* Copyright (c) 2020, Hydrox6 <ikada@protonmail.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,11 +22,11 @@
|
||||
* (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.overlay.components.table;
|
||||
package net.runelite.client.config;
|
||||
|
||||
public enum TableAlignment
|
||||
public interface ConfigObject
|
||||
{
|
||||
LEFT,
|
||||
CENTER,
|
||||
RIGHT
|
||||
String key();
|
||||
String name();
|
||||
int position();
|
||||
}
|
||||
@@ -30,79 +30,14 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ConfigSection
|
||||
{
|
||||
/**
|
||||
* Displayed position of the section.
|
||||
*
|
||||
* @return The index of the section.
|
||||
*/
|
||||
int position();
|
||||
|
||||
/**
|
||||
* This is not visible to users
|
||||
*
|
||||
* @return name used for finding the config section
|
||||
* from the properties map. Hence, KEY name.
|
||||
*/
|
||||
String keyName();
|
||||
|
||||
/**
|
||||
* This is the name that is shown to users when looking
|
||||
* at the config panel.
|
||||
* <p>
|
||||
* Choose a name carefully, as there is a maximum width
|
||||
* that depends on the users DPI scaling. Short is best.
|
||||
*
|
||||
* @return display name for the config section.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* This will be shown to the user if they are hovering
|
||||
* the config item in the config panel.
|
||||
*
|
||||
* @return the description of the config item.
|
||||
*/
|
||||
String description();
|
||||
|
||||
/**
|
||||
* Setting this will tell the panel
|
||||
* that this section should be placed beneath
|
||||
* said section.
|
||||
*
|
||||
* @return parent section.
|
||||
*/
|
||||
String section() default "";
|
||||
int position();
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String titleSection() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
boolean hidden() default false;
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String unhide() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String unhideValue() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String hide() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String hideValue() default "";
|
||||
boolean closedByDefault() default false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* Copyright (c) 2020, Hydrox6 <ikada@protonmail.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,15 +22,31 @@
|
||||
* (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.graphics;
|
||||
package net.runelite.client.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@RequiredArgsConstructor
|
||||
class PixelDistanceAlpha
|
||||
public class ConfigSectionDescriptor implements ConfigObject
|
||||
{
|
||||
private final int outerAlpha;
|
||||
private final int distArrayPos;
|
||||
private final String key;
|
||||
private final ConfigSection section;
|
||||
|
||||
@Override
|
||||
public String key()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return section.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int position()
|
||||
{
|
||||
return section.position();
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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.config;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ConfigTitleSection
|
||||
{
|
||||
/**
|
||||
* Displayed position of the title section.
|
||||
*
|
||||
* @return The index of the title section.
|
||||
*/
|
||||
int position();
|
||||
|
||||
/**
|
||||
* This is not visible to users
|
||||
*
|
||||
* @return name used for finding the config section
|
||||
* from the properties map. Hence, KEY name.
|
||||
*/
|
||||
String keyName();
|
||||
|
||||
/**
|
||||
* This is the name that is shown to users when looking
|
||||
* at the config panel.
|
||||
* <p>
|
||||
* Choose a name carefully, as there is a maximum width
|
||||
* that depends on the users DPI scaling. Short is best.
|
||||
*
|
||||
* @return display name for the config title section.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* This will be shown to the user if they are hovering
|
||||
* the config item in the config panel.
|
||||
*
|
||||
* @return the description of the config item.
|
||||
*/
|
||||
String description();
|
||||
|
||||
/**
|
||||
* Setting this will tell the panel
|
||||
* that this title should be placed beneath
|
||||
* said section.
|
||||
*
|
||||
* @return parent section.
|
||||
*/
|
||||
String section() default "";
|
||||
|
||||
/**
|
||||
* Setting this will tell the panel
|
||||
* that this title should be placed beneath
|
||||
* said title.
|
||||
*
|
||||
* @return parent title section.
|
||||
*/
|
||||
String titleSection() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
boolean hidden() default false;
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String unhide() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String unhideValue() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String hide() default "";
|
||||
|
||||
/**
|
||||
* NOT USED.
|
||||
*/
|
||||
String hideValue() default "";
|
||||
}
|
||||
@@ -24,11 +24,12 @@
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import java.awt.Font;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
|
||||
import java.awt.Font;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum FontType
|
||||
|
||||
@@ -60,7 +60,7 @@ public class Keybind
|
||||
private final int keyCode;
|
||||
private final int modifiers;
|
||||
|
||||
Keybind(int keyCode, int modifiers, boolean ignoreModifiers)
|
||||
protected Keybind(int keyCode, int modifiers, boolean ignoreModifiers)
|
||||
{
|
||||
modifiers &= KEYBOARD_MODIFIER_MASK;
|
||||
|
||||
@@ -108,7 +108,7 @@ public class Keybind
|
||||
return matches(e, false);
|
||||
}
|
||||
|
||||
boolean matches(KeyEvent e, boolean ignoreModifiers)
|
||||
protected boolean matches(KeyEvent e, boolean ignoreModifiers)
|
||||
{
|
||||
if (NOT_SET.equals(this))
|
||||
{
|
||||
@@ -177,7 +177,7 @@ public class Keybind
|
||||
return mod;
|
||||
}
|
||||
|
||||
private static String getModifiersExText(int modifiers)
|
||||
public static String getModifiersExText(int modifiers)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if ((modifiers & InputEvent.META_DOWN_MASK) != 0)
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* 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 "";
|
||||
}
|
||||
}
|
||||
@@ -1,373 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2019, Zeruth <TheRealNull@gmail.com>
|
||||
* 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 java.awt.Color;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.plugins.ExternalPluginManager;
|
||||
|
||||
@ConfigGroup("openosrs")
|
||||
public interface OpenOSRSConfig extends Config
|
||||
{
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
@AllArgsConstructor
|
||||
enum SortStyle
|
||||
{
|
||||
CATEGORY("Category"),
|
||||
ALPHABETICALLY("Alphabetically"),
|
||||
REPOSITORY("Repository");
|
||||
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "logTitle",
|
||||
name = "Error data",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
default Title logTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "shareLogs",
|
||||
name = "Share anonymous error data",
|
||||
description = "Share anonymous error data with the OpenOSRS developers",
|
||||
titleSection = "logTitle"
|
||||
)
|
||||
default boolean shareLogs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "pluginsTitle",
|
||||
name = "Plugins",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
default Title pluginsTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "pluginSortingTitle",
|
||||
name = "Sorting",
|
||||
description = "",
|
||||
position = 2,
|
||||
titleSection = "pluginsTitle"
|
||||
)
|
||||
default Title pluginSortingTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "pluginSortMode",
|
||||
name = "Sorting mode",
|
||||
description = "Sorts plugins ",
|
||||
titleSection = "pluginSortingTitle"
|
||||
)
|
||||
default SortStyle pluginSortMode()
|
||||
{
|
||||
return SortStyle.CATEGORY;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "enableCategories",
|
||||
name = "Categorize plugins",
|
||||
description = "Show sections in the plugin list for each plugin type",
|
||||
titleSection = "pluginSortingTitle",
|
||||
hidden = true,
|
||||
unhide = "pluginSortMode",
|
||||
unhideValue = "Category"
|
||||
)
|
||||
default boolean enableCategories()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "pluginsColorTitle",
|
||||
name = "Colors",
|
||||
description = "",
|
||||
position = 5,
|
||||
titleSection = "pluginsTitle"
|
||||
)
|
||||
default Title pluginsColorTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "enabledColors",
|
||||
name = "Enable plugin colors",
|
||||
description = "Configure whether or not the plugins list should be colorcoded",
|
||||
titleSection = "pluginsColorTitle"
|
||||
)
|
||||
default boolean enabledColors()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "pvmColor",
|
||||
name = "PvM color",
|
||||
description = "Configure the color of PvM related plugins",
|
||||
titleSection = "pluginsColorTitle",
|
||||
hidden = true,
|
||||
unhide = "enabledColors"
|
||||
)
|
||||
default Color pvmColor()
|
||||
{
|
||||
return new Color(119, 221, 119, 255);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "skillingColor",
|
||||
name = "Skilling color",
|
||||
description = "Configure the color of skilling related plugins",
|
||||
titleSection = "pluginsColorTitle",
|
||||
hidden = true,
|
||||
unhide = "enabledColors"
|
||||
)
|
||||
default Color skillingColor()
|
||||
{
|
||||
return new Color(252, 252, 100, 255);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "pvpColor",
|
||||
name = "PvP color",
|
||||
description = "Configure the color of PvP related plugins",
|
||||
titleSection = "pluginsColorTitle",
|
||||
hidden = true,
|
||||
unhide = "enabledColors"
|
||||
)
|
||||
default Color pvpColor()
|
||||
{
|
||||
return new Color(255, 105, 97, 255);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "utilityColor",
|
||||
name = "Utility color",
|
||||
description = "Configure the color of utility related plugins",
|
||||
titleSection = "pluginsColorTitle",
|
||||
hidden = true,
|
||||
unhide = "enabledColors"
|
||||
)
|
||||
default Color utilityColor()
|
||||
{
|
||||
return new Color(144, 212, 237, 255);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "minigameColor",
|
||||
name = "Minigame color",
|
||||
description = "Configure the color of minigame related plugins",
|
||||
titleSection = "pluginsColorTitle",
|
||||
hidden = true,
|
||||
unhide = "enabledColors"
|
||||
)
|
||||
default Color minigameColor()
|
||||
{
|
||||
return new Color(235, 130, 66, 255);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "miscellaneousColor",
|
||||
name = "Miscellaneous color",
|
||||
description = "Configure the color of miscellaneous related plugins",
|
||||
titleSection = "pluginsColorTitle",
|
||||
hidden = true,
|
||||
unhide = "enabledColors"
|
||||
)
|
||||
default Color miscellaneousColor()
|
||||
{
|
||||
return new Color(243, 85, 136, 255);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "gamemodeColor",
|
||||
name = "Gamemode color",
|
||||
description = "Configure the color of gamemode plugins",
|
||||
titleSection = "pluginsColorTitle",
|
||||
hidden = true,
|
||||
unhide = "enabledColors"
|
||||
)
|
||||
default Color gamemodeColor()
|
||||
{
|
||||
return new Color(244, 239, 211, 255);
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "opacityTitle",
|
||||
name = "Opacity",
|
||||
description = "",
|
||||
position = 17
|
||||
)
|
||||
default Title opacityTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "enableOpacity",
|
||||
name = "Enable opacity",
|
||||
description = "Enables opacity for the whole window.<br>NOTE: This only stays enabled if your pc supports this!",
|
||||
position = 18,
|
||||
titleSection = "opacityTitle"
|
||||
)
|
||||
default boolean enableOpacity()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 15,
|
||||
max = 100
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "opacityPercentage",
|
||||
name = "Opacity percentage",
|
||||
description = "Changes the opacity of the window if opacity is enabled",
|
||||
position = 19,
|
||||
titleSection = "opacityTitle"
|
||||
)
|
||||
@Units(Units.PERCENT)
|
||||
default int opacityPercentage()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "miscTitle",
|
||||
name = "Miscellaneous",
|
||||
description = "",
|
||||
position = 20
|
||||
)
|
||||
default Title miscTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "localSync",
|
||||
name = "Sync local instances",
|
||||
description = "Enables multiple local instances of OpenOSRS to communicate (this enables syncing plugin state and config options)",
|
||||
position = 21,
|
||||
titleSection = "miscTitle"
|
||||
)
|
||||
default boolean localSync()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "keyboardPin",
|
||||
name = "Keyboard bank pin",
|
||||
description = "Enables you to type your bank pin",
|
||||
position = 22,
|
||||
titleSection = "miscTitle"
|
||||
)
|
||||
default boolean keyboardPin()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "detachHotkey",
|
||||
name = "Detach Cam",
|
||||
description = "Detach Camera hotkey, press this and it will activate detatched camera.",
|
||||
position = 23,
|
||||
titleSection = "miscTitle"
|
||||
)
|
||||
default Keybind detachHotkey()
|
||||
{
|
||||
return Keybind.NOT_SET;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "externalRepositories",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default String getExternalRepositories()
|
||||
{
|
||||
return ExternalPluginManager.DEFAULT_PLUGIN_REPOS;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "externalRepositories",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
void setExternalRepositories(String val);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warning",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default boolean warning()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -38,25 +38,34 @@ public interface RuneLiteConfig extends Config
|
||||
{
|
||||
String GROUP_NAME = "runelite";
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "uiTitle",
|
||||
name = "User interface",
|
||||
description = "",
|
||||
@ConfigSection(
|
||||
name = "Window Settings",
|
||||
description = "Settings relating to the client's window and frame",
|
||||
position = 0
|
||||
)
|
||||
String windowSettings = "windowSettings";
|
||||
|
||||
@ConfigSection(
|
||||
name = "Notification Settings",
|
||||
description = "Settings relating to notifications",
|
||||
position = 1
|
||||
)
|
||||
default Title uiTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
String notificationSettings = "notificationSettings";
|
||||
|
||||
@ConfigSection(
|
||||
name = "Overlay Settings",
|
||||
description = "Settings relating to fonts",
|
||||
position = 2
|
||||
)
|
||||
String overlaySettings = "overlaySettings";
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gameSize",
|
||||
name = "Game size",
|
||||
description = "The game will resize to this resolution upon starting the client",
|
||||
position = 2,
|
||||
titleSection = "uiTitle"
|
||||
position = 10,
|
||||
section = windowSettings
|
||||
)
|
||||
@Units(Units.PIXELS)
|
||||
default Dimension gameSize()
|
||||
{
|
||||
return Constants.GAME_FIXED_SIZE;
|
||||
@@ -66,8 +75,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "automaticResizeType",
|
||||
name = "Resize type",
|
||||
description = "Choose how the window should resize when opening and closing panels",
|
||||
position = 3,
|
||||
titleSection = "uiTitle"
|
||||
position = 11,
|
||||
section = windowSettings
|
||||
)
|
||||
default ExpandResizeType automaticResizeType()
|
||||
{
|
||||
@@ -78,8 +87,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "lockWindowSize",
|
||||
name = "Lock window size",
|
||||
description = "Determines if the window resizing is allowed or not",
|
||||
position = 4,
|
||||
titleSection = "uiTitle"
|
||||
position = 12,
|
||||
section = windowSettings
|
||||
)
|
||||
default boolean lockWindowSize()
|
||||
{
|
||||
@@ -90,82 +99,61 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "containInScreen2",
|
||||
name = "Contain in screen",
|
||||
description = "Makes the client stay contained in the screen when attempted to move out of it.<br>Note: 'Always' only works if custom chrome is enabled.",
|
||||
position = 5,
|
||||
titleSection = "uiTitle"
|
||||
position = 13,
|
||||
section = windowSettings
|
||||
)
|
||||
default ContainableFrame.Mode containInScreen()
|
||||
{
|
||||
return ContainableFrame.Mode.RESIZING;
|
||||
}
|
||||
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "uiEnableCustomChrome",
|
||||
name = "Enable custom window chrome",
|
||||
description = "Use Runelite's custom window title and borders.",
|
||||
warning = "Please restart your client after changing this setting.",
|
||||
position = 6,
|
||||
titleSection = "uiTitle"
|
||||
)
|
||||
default boolean enableCustomChrome()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "borderless",
|
||||
name = "Windowed borderless",
|
||||
description = "Use windowed borderless mode",
|
||||
warning = "Please restart your client after changing this setting.",
|
||||
position = 7,
|
||||
titleSection = "uiTitle"
|
||||
)
|
||||
default boolean borderless()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "usernameInTitle",
|
||||
name = "Show display name in title",
|
||||
description = "Toggles displaying of local player's display name in client title",
|
||||
position = 8,
|
||||
titleSection = "uiTitle"
|
||||
)
|
||||
default boolean usernameInTitle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "miscTitle",
|
||||
name = "Miscellaneous",
|
||||
description = "",
|
||||
position = 9
|
||||
)
|
||||
default Title miscTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rememberScreenBounds",
|
||||
name = "Remember client position",
|
||||
description = "Save the position and size of the client after exiting",
|
||||
position = 10,
|
||||
titleSection = "miscTitle"
|
||||
position = 14,
|
||||
section = windowSettings
|
||||
)
|
||||
default boolean rememberScreenBounds()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "uiEnableCustomChrome",
|
||||
name = "Enable custom window chrome",
|
||||
description = "Use Runelite's custom window title and borders.",
|
||||
warning = "Please restart your client after changing this setting",
|
||||
position = 15,
|
||||
section = windowSettings
|
||||
)
|
||||
default boolean enableCustomChrome()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 10,
|
||||
max = 100
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "uiWindowOpacity",
|
||||
name = "Window opacity",
|
||||
description = "Set the windows opacity. Requires \"Enable custom window chrome\" to be enabled.",
|
||||
position = 16,
|
||||
section = windowSettings
|
||||
)
|
||||
default int windowOpacity()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gameAlwaysOnTop",
|
||||
name = "Enable client always on top",
|
||||
description = "The game will always be on the top of the screen",
|
||||
position = 11,
|
||||
titleSection = "miscTitle"
|
||||
position = 17,
|
||||
section = windowSettings
|
||||
)
|
||||
default boolean gameAlwaysOnTop()
|
||||
{
|
||||
@@ -176,57 +164,32 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "warningOnExit",
|
||||
name = "Display warning on exit",
|
||||
description = "Toggles a warning popup when trying to exit the client",
|
||||
position = 12,
|
||||
titleSection = "miscTitle"
|
||||
position = 18,
|
||||
section = windowSettings
|
||||
)
|
||||
default WarningOnExit warningOnExit()
|
||||
{
|
||||
return WarningOnExit.LOGGED_IN;
|
||||
}
|
||||
|
||||
@Range(max = 100, min = 0)
|
||||
@ConfigItem(
|
||||
keyName = "volume",
|
||||
name = "Runelite Volume",
|
||||
description = "Sets the volume of custom Runelite sounds (not the client sounds)",
|
||||
position = 13,
|
||||
titleSection = "miscTitle"
|
||||
keyName = "usernameInTitle",
|
||||
name = "Show display name in title",
|
||||
description = "Toggles displaying of local player's display name in client title",
|
||||
position = 19,
|
||||
section = windowSettings
|
||||
)
|
||||
@Units(Units.PERCENT)
|
||||
default int volume()
|
||||
default boolean usernameInTitle()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tooltipPosition",
|
||||
name = "Tooltip Position",
|
||||
description = "Configures whether to show the tooltip above or under the cursor",
|
||||
position = 14,
|
||||
titleSection = "miscTitle"
|
||||
)
|
||||
default TooltipPositionType tooltipPosition()
|
||||
{
|
||||
return TooltipPositionType.UNDER_CURSOR;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "notificationsTitle",
|
||||
name = "Notifications",
|
||||
description = "",
|
||||
position = 15
|
||||
)
|
||||
default Title notificationsTitle()
|
||||
{
|
||||
return new Title();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationTray",
|
||||
name = "Enable tray notifications",
|
||||
description = "Enables tray notifications",
|
||||
position = 16,
|
||||
titleSection = "notificationsTitle"
|
||||
position = 20,
|
||||
section = notificationSettings
|
||||
)
|
||||
default boolean enableTrayNotifications()
|
||||
{
|
||||
@@ -237,8 +200,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "notificationRequestFocus",
|
||||
name = "Request focus on notification",
|
||||
description = "Configures the window focus request type on notification",
|
||||
position = 17,
|
||||
titleSection = "notificationsTitle"
|
||||
position = 21,
|
||||
section = notificationSettings
|
||||
)
|
||||
default RequestFocusType notificationRequestFocus()
|
||||
{
|
||||
@@ -249,8 +212,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "notificationSound",
|
||||
name = "Notification sound",
|
||||
description = "Enables the playing of a beep sound when notifications are displayed",
|
||||
position = 18,
|
||||
titleSection = "notificationsTitle"
|
||||
position = 22,
|
||||
section = notificationSettings
|
||||
)
|
||||
default Notifier.NativeCustomOff notificationSound()
|
||||
{
|
||||
@@ -261,8 +224,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "notificationGameMessage",
|
||||
name = "Enable game message notifications",
|
||||
description = "Puts a notification message in the chatbox",
|
||||
position = 19,
|
||||
titleSection = "notificationsTitle"
|
||||
position = 23,
|
||||
section = notificationSettings
|
||||
)
|
||||
default boolean enableGameMessageNotification()
|
||||
{
|
||||
@@ -270,11 +233,11 @@ public interface RuneLiteConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationFlash",
|
||||
name = "Enable flash notification",
|
||||
keyName = "flashNotification",
|
||||
name = "Flash notification",
|
||||
description = "Flashes the game frame as a notification",
|
||||
position = 20,
|
||||
titleSection = "notificationsTitle"
|
||||
position = 24,
|
||||
section = notificationSettings
|
||||
)
|
||||
default FlashNotification flashNotification()
|
||||
{
|
||||
@@ -285,8 +248,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "notificationFocused",
|
||||
name = "Send notifications when focused",
|
||||
description = "Toggles all notifications for when the client is focused",
|
||||
position = 21,
|
||||
titleSection = "notificationsTitle"
|
||||
position = 25,
|
||||
section = notificationSettings
|
||||
)
|
||||
default boolean sendNotificationsWhenFocused()
|
||||
{
|
||||
@@ -298,31 +261,20 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "notificationFlashColor",
|
||||
name = "Notification Flash Color",
|
||||
description = "Sets the color of the notification flashes.",
|
||||
position = 22,
|
||||
titleSection = "notificationsTitle"
|
||||
position = 26,
|
||||
section = notificationSettings
|
||||
)
|
||||
default Color notificationFlashColor()
|
||||
{
|
||||
return new Color(255, 0, 0, 70);
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "fontTitle",
|
||||
name = "Font",
|
||||
description = "",
|
||||
position = 23
|
||||
)
|
||||
default Title fontTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fontType",
|
||||
name = "Dynamic Overlay Font",
|
||||
description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.",
|
||||
position = 24,
|
||||
titleSection = "fontTitle"
|
||||
position = 30,
|
||||
section = overlaySettings
|
||||
)
|
||||
default FontType fontType()
|
||||
{
|
||||
@@ -333,8 +285,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "tooltipFontType",
|
||||
name = "Tooltip Font",
|
||||
description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.",
|
||||
position = 25,
|
||||
titleSection = "fontTitle"
|
||||
position = 31,
|
||||
section = overlaySettings
|
||||
)
|
||||
default FontType tooltipFontType()
|
||||
{
|
||||
@@ -345,31 +297,20 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "interfaceFontType",
|
||||
name = "Interface Overlay Font",
|
||||
description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.",
|
||||
position = 26,
|
||||
titleSection = "fontTitle"
|
||||
position = 32,
|
||||
section = overlaySettings
|
||||
)
|
||||
default FontType interfaceFontType()
|
||||
{
|
||||
return FontType.REGULAR;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "overlayTitle",
|
||||
name = "Overlays",
|
||||
description = "",
|
||||
position = 27
|
||||
)
|
||||
default Title overlayTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "menuEntryShift",
|
||||
name = "Require Shift for overlay menu",
|
||||
description = "Overlay right-click menu will require shift to be added",
|
||||
position = 28,
|
||||
titleSection = "overlayTitle"
|
||||
position = 33,
|
||||
section = overlaySettings
|
||||
)
|
||||
default boolean menuEntryShift()
|
||||
{
|
||||
@@ -377,47 +318,23 @@ public interface RuneLiteConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "overlayBackgroundColor",
|
||||
name = "Overlay Color",
|
||||
description = "Configures the background color of infoboxes and overlays",
|
||||
position = 29,
|
||||
titleSection = "overlayTitle"
|
||||
keyName = "tooltipPosition",
|
||||
name = "Tooltip Position",
|
||||
description = "Configures whether to show the tooltip above or under the cursor",
|
||||
position = 35,
|
||||
section = overlaySettings
|
||||
)
|
||||
@Alpha
|
||||
default Color overlayBackgroundColor()
|
||||
default TooltipPositionType tooltipPosition()
|
||||
{
|
||||
return ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "infoboxTitle",
|
||||
name = "Infoboxes",
|
||||
description = "",
|
||||
position = 30
|
||||
)
|
||||
default Title infoboxTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "infoBoxTextOutline",
|
||||
name = "Outline infobox text",
|
||||
description = "Draw a full outline instead of a simple shadow for infobox text",
|
||||
position = 31,
|
||||
titleSection = "infoboxTitle"
|
||||
)
|
||||
default boolean infoBoxTextOutline()
|
||||
{
|
||||
return false;
|
||||
return TooltipPositionType.UNDER_CURSOR;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "infoBoxVertical",
|
||||
name = "Display infoboxes vertically",
|
||||
description = "Toggles the infoboxes to display vertically",
|
||||
position = 32,
|
||||
titleSection = "infoboxTitle",
|
||||
position = 40,
|
||||
section = overlaySettings,
|
||||
hidden = true
|
||||
)
|
||||
default boolean infoBoxVertical()
|
||||
@@ -429,8 +346,8 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "infoBoxSize",
|
||||
name = "Infobox size",
|
||||
description = "Configures the size of each infobox in pixels",
|
||||
position = 33,
|
||||
titleSection = "infoboxTitle"
|
||||
position = 42,
|
||||
section = overlaySettings
|
||||
)
|
||||
@Units(Units.PIXELS)
|
||||
default int infoBoxSize()
|
||||
@@ -438,23 +355,48 @@ public interface RuneLiteConfig extends Config
|
||||
return 35;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "keybindsTitle",
|
||||
name = "Key binds",
|
||||
description = "",
|
||||
position = 34
|
||||
@ConfigItem(
|
||||
keyName = "infoBoxTextOutline",
|
||||
name = "Outline infobox text",
|
||||
description = "Draw a full outline instead of a simple shadow for infobox text",
|
||||
position = 43,
|
||||
section = overlaySettings
|
||||
)
|
||||
default Title keybindsTitle()
|
||||
default boolean infoBoxTextOutline()
|
||||
{
|
||||
return new Title();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "overlayBackgroundColor",
|
||||
name = "Overlay Color",
|
||||
description = "Configures the background color of infoboxes and overlays",
|
||||
position = 44,
|
||||
section = overlaySettings
|
||||
)
|
||||
@Alpha
|
||||
default Color overlayBackgroundColor()
|
||||
{
|
||||
return ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "blockExtraMouseButtons",
|
||||
name = "Block Extra Mouse Buttons",
|
||||
description = "Blocks extra mouse buttons (4 and above)",
|
||||
position = 44
|
||||
)
|
||||
default boolean blockExtraMouseButtons()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "sidebarToggleKey",
|
||||
name = "Sidebar Toggle Key",
|
||||
description = "The key that will toggle the sidebar (accepts modifiers)",
|
||||
position = 35,
|
||||
titleSection = "keybindsTitle"
|
||||
position = 45,
|
||||
section = windowSettings
|
||||
)
|
||||
default Keybind sidebarToggleKey()
|
||||
{
|
||||
@@ -465,23 +407,11 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "panelToggleKey",
|
||||
name = "Plugin Panel Toggle Key",
|
||||
description = "The key that will toggle the current or last opened plugin panel (accepts modifiers)",
|
||||
position = 36,
|
||||
titleSection = "keybindsTitle"
|
||||
position = 46,
|
||||
section = windowSettings
|
||||
)
|
||||
default Keybind panelToggleKey()
|
||||
{
|
||||
return new Keybind(KeyEvent.VK_F12, InputEvent.CTRL_DOWN_MASK);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "blockExtraMouseButtons",
|
||||
name = "Block Extra Mouse Buttons",
|
||||
description = "Blocks extra mouse buttons (4 and above)",
|
||||
position = 37,
|
||||
titleSection = "keybindsTitle"
|
||||
)
|
||||
default boolean blockExtraMouseButtons()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* Copyright (c) 2020 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,20 +22,24 @@
|
||||
* (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.overlay.components.table;
|
||||
package net.runelite.client.config;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* A profile/save of a OSRS account. Each account can 1 profile per {@link RuneScapeProfileType}
|
||||
* (ie Standard/League/DMM}.
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class TableRow
|
||||
public class RuneScapeProfile
|
||||
{
|
||||
Color rowColor;
|
||||
TableAlignment rowAlignment;
|
||||
@Builder.Default
|
||||
List<TableElement> elements = Collections.emptyList();
|
||||
private final String displayName;
|
||||
private final RuneScapeProfileType type;
|
||||
private final byte[] loginHash;
|
||||
|
||||
/**
|
||||
* Profile key used to save configs for this profile to the config store. This will
|
||||
* always start with {@link ConfigManager#RSPROFILE_GROUP}
|
||||
*/
|
||||
private final String key;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Craftiii4 <craftiii4@gmail.com>
|
||||
* Copyright (c) 2020 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -24,27 +24,36 @@
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import java.util.function.Predicate;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.WorldType;
|
||||
|
||||
public class ConfigPanelItem
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum RuneScapeProfileType
|
||||
{
|
||||
STANDARD(client -> true),
|
||||
BETA(client -> client.getWorldType().contains(WorldType.TOURNAMENT)),
|
||||
DEADMAN(client -> client.getWorldType().contains(WorldType.DEADMAN)),
|
||||
TRAILBLAZER_LEAGUE(client -> client.getWorldType().contains(WorldType.LEAGUE)),
|
||||
;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private ConfigPanelItem parent;
|
||||
private final Predicate<Client> test;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private List<ConfigPanelItem> children;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private ConfigItemDescriptor item;
|
||||
|
||||
public ConfigPanelItem(ConfigPanelItem parent, ConfigItemDescriptor item)
|
||||
public static RuneScapeProfileType getCurrent(Client client)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.children = new ArrayList<>();
|
||||
this.item = item;
|
||||
RuneScapeProfileType[] types = values();
|
||||
for (int i = types.length - 1; i >= 0; i--)
|
||||
{
|
||||
RuneScapeProfileType type = types[i];
|
||||
if (types[i].test.test(client))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return STANDARD;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
package net.runelite.client.config;
|
||||
|
||||
public class Title {}
|
||||
@@ -42,12 +42,8 @@ public @interface Units
|
||||
String MINUTES = " mins";
|
||||
String PERCENT = "%";
|
||||
String PIXELS = "px";
|
||||
String POINTS = "pt";
|
||||
String SECONDS = "s";
|
||||
String TICKS = " ticks";
|
||||
String LEVELS = " lvls";
|
||||
String FPS = " fps";
|
||||
String GP = " GP";
|
||||
|
||||
String value();
|
||||
}
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
package net.runelite.client.database;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import static net.runelite.client.RuneLite.RUNELITE_DIR;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class DatabaseManager
|
||||
{
|
||||
private static final String DB_URL = "jdbc:h2:" + RUNELITE_DIR + File.separator + "RunelitePlus;AUTO_SERVER=TRUE";
|
||||
|
||||
// Database credentials
|
||||
private static final String USER = "RLP";
|
||||
private static final String PASS = "";
|
||||
|
||||
private Connection connection;
|
||||
|
||||
DatabaseManager()
|
||||
{
|
||||
System.getProperties().setProperty("org.jooq.no-logo", "true");
|
||||
}
|
||||
|
||||
private void connect()
|
||||
{
|
||||
if (connection != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JdbcDataSource ds = new JdbcDataSource();
|
||||
ds.setURL(DatabaseManager.DB_URL);
|
||||
ds.setUser(DatabaseManager.USER);
|
||||
ds.setPassword(DatabaseManager.PASS);
|
||||
|
||||
try
|
||||
{
|
||||
connection = ds.getConnection();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Connection getConnection()
|
||||
{
|
||||
connect();
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
public DSLContext getDsl()
|
||||
{
|
||||
Settings settings = new Settings();
|
||||
settings.setExecuteLogging(false);
|
||||
|
||||
return DSL.using(connection, SQLDialect.H2, settings);
|
||||
}
|
||||
|
||||
public boolean checkTableExists(String table)
|
||||
{
|
||||
boolean tableExists = false;
|
||||
|
||||
connect();
|
||||
|
||||
try
|
||||
{
|
||||
ResultSet rset = connection.getMetaData().getTables(null, null, table.toUpperCase(), null);
|
||||
if (rset.next())
|
||||
{
|
||||
tableExists = true;
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return tableExists;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package net.runelite.client.database;
|
||||
|
||||
import java.sql.Connection;
|
||||
import org.jooq.codegen.GenerationTool;
|
||||
import org.jooq.meta.h2.H2Database;
|
||||
import org.jooq.meta.jaxb.Configuration;
|
||||
import org.jooq.meta.jaxb.Database;
|
||||
import org.jooq.meta.jaxb.Generator;
|
||||
import org.jooq.meta.jaxb.Target;
|
||||
|
||||
public class GenerateClasses
|
||||
{
|
||||
public static void main(String... args)
|
||||
{
|
||||
DatabaseManager databaseManager = new DatabaseManager();
|
||||
|
||||
try (Connection c = databaseManager.getConnection())
|
||||
{
|
||||
Configuration configuration = new Configuration()
|
||||
.withGenerator(new Generator()
|
||||
.withDatabase(new Database()
|
||||
.withName(H2Database.class.getCanonicalName())
|
||||
.withIncludes(".*")
|
||||
.withExcludes("")
|
||||
.withInputSchema("PUBLIC")
|
||||
)
|
||||
.withTarget(new Target()
|
||||
.withPackageName("net.runelite.client.database.data")
|
||||
.withDirectory("runelite-client/src/main/java/")
|
||||
)
|
||||
);
|
||||
|
||||
GenerationTool tool = new GenerationTool();
|
||||
tool.setConnection(c);
|
||||
tool.run(configuration);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.annotation.processing.Generated;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.impl.CatalogImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class DefaultCatalog extends CatalogImpl
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -102989253;
|
||||
|
||||
/**
|
||||
* The reference instance of <code></code>
|
||||
*/
|
||||
public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog();
|
||||
|
||||
/**
|
||||
* The schema <code>PUBLIC</code>.
|
||||
*/
|
||||
public final Public PUBLIC = net.runelite.client.database.data.Public.PUBLIC;
|
||||
|
||||
/**
|
||||
* No further instances allowed
|
||||
*/
|
||||
private DefaultCatalog()
|
||||
{
|
||||
super("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Schema> getSchemas()
|
||||
{
|
||||
List result = new ArrayList();
|
||||
result.addAll(getSchemas0());
|
||||
return result;
|
||||
}
|
||||
|
||||
private final List<Schema> getSchemas0()
|
||||
{
|
||||
return Arrays.<Schema>asList(
|
||||
Public.PUBLIC);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data;
|
||||
|
||||
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.Loottrackerevents;
|
||||
import net.runelite.client.database.data.tables.Loottrackerlink;
|
||||
import net.runelite.client.database.data.tables.Loottrackerloot;
|
||||
import net.runelite.client.database.data.tables.TmorphSets;
|
||||
import net.runelite.client.database.data.tables.User;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.OrderField;
|
||||
import org.jooq.impl.Internal;
|
||||
|
||||
|
||||
/**
|
||||
* A class modelling indexes of tables of the <code>PUBLIC</code> schema.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class Indexes
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// INDEX definitions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final Index PRIMARY_KEY_B = Indexes0.PRIMARY_KEY_B;
|
||||
public static final Index FK_LOOTTRACKERDROP_INDEX_6 = Indexes0.FK_LOOTTRACKERDROP_INDEX_6;
|
||||
public static final Index FK_LOOTTRACKEREVENT_INDEX_6 = Indexes0.FK_LOOTTRACKEREVENT_INDEX_6;
|
||||
public static final Index FK_USER_INDEX_6 = Indexes0.FK_USER_INDEX_6;
|
||||
public static final Index PRIMARY_KEY_6 = Indexes0.PRIMARY_KEY_6;
|
||||
public static final Index TMORPH_SETS_SET_NAME_UINDEX = Indexes0.TMORPH_SETS_SET_NAME_UINDEX;
|
||||
public static final Index PRIMARY_KEY_2 = Indexes0.PRIMARY_KEY_2;
|
||||
public static final Index UN_USERNAME_INDEX_2 = Indexes0.UN_USERNAME_INDEX_2;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// [#1459] distribute members to avoid static initialisers > 64kb
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static class Indexes0
|
||||
{
|
||||
public static Index PRIMARY_KEY_B = Internal.createIndex("PRIMARY_KEY_B", Loottrackerevents.LOOTTRACKEREVENTS, new OrderField[]{Loottrackerevents.LOOTTRACKEREVENTS.UNIQUEID}, true);
|
||||
public static Index FK_LOOTTRACKERDROP_INDEX_6 = Internal.createIndex("FK_LOOTTRACKERDROP_INDEX_6", Loottrackerlink.LOOTTRACKERLINK, new OrderField[]{Loottrackerlink.LOOTTRACKERLINK.DROPUNIQUEID}, false);
|
||||
public static Index FK_LOOTTRACKEREVENT_INDEX_6 = Internal.createIndex("FK_LOOTTRACKEREVENT_INDEX_6", Loottrackerlink.LOOTTRACKERLINK, new OrderField[]{Loottrackerlink.LOOTTRACKERLINK.EVENTUNIQUEID}, false);
|
||||
public static Index FK_USER_INDEX_6 = Internal.createIndex("FK_USER_INDEX_6", Loottrackerlink.LOOTTRACKERLINK, new OrderField[]{Loottrackerlink.LOOTTRACKERLINK.USERUNIQUEID}, false);
|
||||
public static Index PRIMARY_KEY_6 = Internal.createIndex("PRIMARY_KEY_6", Loottrackerloot.LOOTTRACKERLOOT, new OrderField[]{Loottrackerloot.LOOTTRACKERLOOT.UNIQUEID}, true);
|
||||
public static Index TMORPH_SETS_SET_NAME_UINDEX = Internal.createIndex("TMORPH_SETS_SET_NAME_UINDEX", TmorphSets.TMORPH_SETS, new OrderField[]{TmorphSets.TMORPH_SETS.SET_NAME}, true);
|
||||
public static Index PRIMARY_KEY_2 = Internal.createIndex("PRIMARY_KEY_2", User.USER, new OrderField[]{User.USER.UNIQUEID}, true);
|
||||
public static Index UN_USERNAME_INDEX_2 = Internal.createIndex("UN_USERNAME_INDEX_2", User.USER, new OrderField[]{User.USER.USERNAME}, true);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data;
|
||||
|
||||
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.Loottrackerevents;
|
||||
import net.runelite.client.database.data.tables.Loottrackerlink;
|
||||
import net.runelite.client.database.data.tables.Loottrackerloot;
|
||||
import net.runelite.client.database.data.tables.User;
|
||||
import net.runelite.client.database.data.tables.records.LoottrackereventsRecord;
|
||||
import net.runelite.client.database.data.tables.records.LoottrackerlinkRecord;
|
||||
import net.runelite.client.database.data.tables.records.LoottrackerlootRecord;
|
||||
import net.runelite.client.database.data.tables.records.UserRecord;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.UniqueKey;
|
||||
import org.jooq.impl.Internal;
|
||||
|
||||
|
||||
/**
|
||||
* A class modelling foreign key relationships and constraints of tables of
|
||||
* the <code>PUBLIC</code> schema.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class Keys
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// IDENTITY definitions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// UNIQUE and PRIMARY KEY definitions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final UniqueKey<LoottrackereventsRecord> PK_LOOTTRACKEREVENTS = UniqueKeys0.PK_LOOTTRACKEREVENTS;
|
||||
public static final UniqueKey<LoottrackerlootRecord> PK_LOOTTRACKERDROPS = UniqueKeys0.PK_LOOTTRACKERDROPS;
|
||||
public static final UniqueKey<UserRecord> PK_USER = UniqueKeys0.PK_USER;
|
||||
public static final UniqueKey<UserRecord> UN_USERNAME = UniqueKeys0.UN_USERNAME;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// FOREIGN KEY definitions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public static final ForeignKey<LoottrackerlinkRecord, LoottrackereventsRecord> FK_LOOTTRACKEREVENT = ForeignKeys0.FK_LOOTTRACKEREVENT;
|
||||
public static final ForeignKey<LoottrackerlinkRecord, LoottrackerlootRecord> FK_LOOTTRACKERDROP = ForeignKeys0.FK_LOOTTRACKERDROP;
|
||||
public static final ForeignKey<LoottrackerlinkRecord, UserRecord> FK_USER = ForeignKeys0.FK_USER;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// [#1459] distribute members to avoid static initialisers > 64kb
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static class UniqueKeys0
|
||||
{
|
||||
public static final UniqueKey<LoottrackereventsRecord> PK_LOOTTRACKEREVENTS = Internal.createUniqueKey(Loottrackerevents.LOOTTRACKEREVENTS, "PK_LOOTTRACKEREVENTS", Loottrackerevents.LOOTTRACKEREVENTS.UNIQUEID);
|
||||
public static final UniqueKey<LoottrackerlootRecord> PK_LOOTTRACKERDROPS = Internal.createUniqueKey(Loottrackerloot.LOOTTRACKERLOOT, "PK_LOOTTRACKERDROPS", Loottrackerloot.LOOTTRACKERLOOT.UNIQUEID);
|
||||
public static final UniqueKey<UserRecord> PK_USER = Internal.createUniqueKey(User.USER, "PK_USER", User.USER.UNIQUEID);
|
||||
public static final UniqueKey<UserRecord> UN_USERNAME = Internal.createUniqueKey(User.USER, "UN_USERNAME", User.USER.USERNAME);
|
||||
}
|
||||
|
||||
private static class ForeignKeys0
|
||||
{
|
||||
public static final ForeignKey<LoottrackerlinkRecord, LoottrackereventsRecord> FK_LOOTTRACKEREVENT = Internal.createForeignKey(net.runelite.client.database.data.Keys.PK_LOOTTRACKEREVENTS, Loottrackerlink.LOOTTRACKERLINK, "FK_LOOTTRACKEREVENT", Loottrackerlink.LOOTTRACKERLINK.EVENTUNIQUEID);
|
||||
public static final ForeignKey<LoottrackerlinkRecord, LoottrackerlootRecord> FK_LOOTTRACKERDROP = Internal.createForeignKey(net.runelite.client.database.data.Keys.PK_LOOTTRACKERDROPS, Loottrackerlink.LOOTTRACKERLINK, "FK_LOOTTRACKERDROP", Loottrackerlink.LOOTTRACKERLINK.DROPUNIQUEID);
|
||||
public static final ForeignKey<LoottrackerlinkRecord, UserRecord> FK_USER = Internal.createForeignKey(net.runelite.client.database.data.Keys.PK_USER, Loottrackerlink.LOOTTRACKERLINK, "FK_USER", Loottrackerlink.LOOTTRACKERLINK.USERUNIQUEID);
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.Loottrackerevents;
|
||||
import net.runelite.client.database.data.tables.Loottrackerlink;
|
||||
import net.runelite.client.database.data.tables.Loottrackerloot;
|
||||
import net.runelite.client.database.data.tables.TmorphSets;
|
||||
import net.runelite.client.database.data.tables.User;
|
||||
import org.jooq.Catalog;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.impl.SchemaImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class Public extends SchemaImpl
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 1268129010;
|
||||
|
||||
/**
|
||||
* The reference instance of <code>PUBLIC</code>
|
||||
*/
|
||||
public static final Public PUBLIC = new Public();
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.LOOTTRACKEREVENTS</code>.
|
||||
*/
|
||||
public final Loottrackerevents LOOTTRACKEREVENTS = net.runelite.client.database.data.tables.Loottrackerevents.LOOTTRACKEREVENTS;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.LOOTTRACKERLINK</code>.
|
||||
*/
|
||||
public final Loottrackerlink LOOTTRACKERLINK = net.runelite.client.database.data.tables.Loottrackerlink.LOOTTRACKERLINK;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.LOOTTRACKERLOOT</code>.
|
||||
*/
|
||||
public final Loottrackerloot LOOTTRACKERLOOT = net.runelite.client.database.data.tables.Loottrackerloot.LOOTTRACKERLOOT;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.TMORPH_SETS</code>.
|
||||
*/
|
||||
public final TmorphSets TMORPH_SETS = net.runelite.client.database.data.tables.TmorphSets.TMORPH_SETS;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.USER</code>.
|
||||
*/
|
||||
public final User USER = net.runelite.client.database.data.tables.User.USER;
|
||||
|
||||
/**
|
||||
* No further instances allowed
|
||||
*/
|
||||
private Public()
|
||||
{
|
||||
super("PUBLIC", null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Catalog getCatalog()
|
||||
{
|
||||
return DefaultCatalog.DEFAULT_CATALOG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Table<?>> getTables()
|
||||
{
|
||||
List result = new ArrayList();
|
||||
result.addAll(getTables0());
|
||||
return result;
|
||||
}
|
||||
|
||||
private final List<Table<?>> getTables0()
|
||||
{
|
||||
return Arrays.<Table<?>>asList(
|
||||
Loottrackerevents.LOOTTRACKEREVENTS,
|
||||
Loottrackerlink.LOOTTRACKERLINK,
|
||||
Loottrackerloot.LOOTTRACKERLOOT,
|
||||
TmorphSets.TMORPH_SETS,
|
||||
User.USER);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data;
|
||||
|
||||
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.Loottrackerevents;
|
||||
import net.runelite.client.database.data.tables.Loottrackerlink;
|
||||
import net.runelite.client.database.data.tables.Loottrackerloot;
|
||||
import net.runelite.client.database.data.tables.TmorphSets;
|
||||
import net.runelite.client.database.data.tables.User;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience access to all tables in PUBLIC
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class Tables
|
||||
{
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.LOOTTRACKEREVENTS</code>.
|
||||
*/
|
||||
public static final Loottrackerevents LOOTTRACKEREVENTS = Loottrackerevents.LOOTTRACKEREVENTS;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.LOOTTRACKERLINK</code>.
|
||||
*/
|
||||
public static final Loottrackerlink LOOTTRACKERLINK = Loottrackerlink.LOOTTRACKERLINK;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.LOOTTRACKERLOOT</code>.
|
||||
*/
|
||||
public static final Loottrackerloot LOOTTRACKERLOOT = Loottrackerloot.LOOTTRACKERLOOT;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.TMORPH_SETS</code>.
|
||||
*/
|
||||
public static final TmorphSets TMORPH_SETS = TmorphSets.TMORPH_SETS;
|
||||
|
||||
/**
|
||||
* The table <code>PUBLIC.USER</code>.
|
||||
*/
|
||||
public static final User USER = User.USER;
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables;
|
||||
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.Indexes;
|
||||
import net.runelite.client.database.data.Keys;
|
||||
import net.runelite.client.database.data.Public;
|
||||
import net.runelite.client.database.data.tables.records.LoottrackereventsRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Row4;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.UniqueKey;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.impl.TableImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class Loottrackerevents extends TableImpl<LoottrackereventsRecord>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 1578403652;
|
||||
|
||||
/**
|
||||
* The reference instance of <code>PUBLIC.LOOTTRACKEREVENTS</code>
|
||||
*/
|
||||
public static final Loottrackerevents LOOTTRACKEREVENTS = new Loottrackerevents();
|
||||
|
||||
/**
|
||||
* The class holding records for this type
|
||||
*/
|
||||
@Override
|
||||
public Class<LoottrackereventsRecord> getRecordType()
|
||||
{
|
||||
return LoottrackereventsRecord.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKEREVENTS.UNIQUEID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackereventsRecord, UUID> UNIQUEID = createField(DSL.name("UNIQUEID"), org.jooq.impl.SQLDataType.UUID.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKEREVENTS.EVENTID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackereventsRecord, String> EVENTID = createField(DSL.name("EVENTID"), org.jooq.impl.SQLDataType.VARCHAR(255).nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKEREVENTS.TYPE</code>.
|
||||
*/
|
||||
public final TableField<LoottrackereventsRecord, String> TYPE = createField(DSL.name("TYPE"), org.jooq.impl.SQLDataType.VARCHAR(255).nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKEREVENTS.TIME</code>.
|
||||
*/
|
||||
public final TableField<LoottrackereventsRecord, Timestamp> TIME = createField(DSL.name("TIME"), org.jooq.impl.SQLDataType.TIMESTAMP.precision(6).nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* Create a <code>PUBLIC.LOOTTRACKEREVENTS</code> table reference
|
||||
*/
|
||||
public Loottrackerevents()
|
||||
{
|
||||
this(DSL.name("LOOTTRACKEREVENTS"), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.LOOTTRACKEREVENTS</code> table reference
|
||||
*/
|
||||
public Loottrackerevents(String alias)
|
||||
{
|
||||
this(DSL.name(alias), LOOTTRACKEREVENTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.LOOTTRACKEREVENTS</code> table reference
|
||||
*/
|
||||
public Loottrackerevents(Name alias)
|
||||
{
|
||||
this(alias, LOOTTRACKEREVENTS);
|
||||
}
|
||||
|
||||
private Loottrackerevents(Name alias, Table<LoottrackereventsRecord> aliased)
|
||||
{
|
||||
this(alias, aliased, null);
|
||||
}
|
||||
|
||||
private Loottrackerevents(Name alias, Table<LoottrackereventsRecord> aliased, Field<?>[] parameters)
|
||||
{
|
||||
super(alias, null, aliased, parameters, DSL.comment(""));
|
||||
}
|
||||
|
||||
public <O extends Record> Loottrackerevents(Table<O> child, ForeignKey<O, LoottrackereventsRecord> key)
|
||||
{
|
||||
super(child, key, LOOTTRACKEREVENTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getSchema()
|
||||
{
|
||||
return Public.PUBLIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Index> getIndexes()
|
||||
{
|
||||
return Arrays.<Index>asList(Indexes.PRIMARY_KEY_B);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueKey<LoottrackereventsRecord> getPrimaryKey()
|
||||
{
|
||||
return Keys.PK_LOOTTRACKEREVENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UniqueKey<LoottrackereventsRecord>> getKeys()
|
||||
{
|
||||
return Arrays.<UniqueKey<LoottrackereventsRecord>>asList(Keys.PK_LOOTTRACKEREVENTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loottrackerevents as(String alias)
|
||||
{
|
||||
return new Loottrackerevents(DSL.name(alias), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loottrackerevents as(Name alias)
|
||||
{
|
||||
return new Loottrackerevents(alias, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public Loottrackerevents rename(String name)
|
||||
{
|
||||
return new Loottrackerevents(DSL.name(name), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public Loottrackerevents rename(Name name)
|
||||
{
|
||||
return new Loottrackerevents(name, null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Row4 type methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row4<UUID, String, String, Timestamp> fieldsRow()
|
||||
{
|
||||
return (Row4) super.fieldsRow();
|
||||
}
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.Indexes;
|
||||
import net.runelite.client.database.data.Keys;
|
||||
import net.runelite.client.database.data.Public;
|
||||
import net.runelite.client.database.data.tables.records.LoottrackerlinkRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Row4;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.impl.TableImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class Loottrackerlink extends TableImpl<LoottrackerlinkRecord>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -1694278583;
|
||||
|
||||
/**
|
||||
* The reference instance of <code>PUBLIC.LOOTTRACKERLINK</code>
|
||||
*/
|
||||
public static final Loottrackerlink LOOTTRACKERLINK = new Loottrackerlink();
|
||||
|
||||
/**
|
||||
* The class holding records for this type
|
||||
*/
|
||||
@Override
|
||||
public Class<LoottrackerlinkRecord> getRecordType()
|
||||
{
|
||||
return LoottrackerlinkRecord.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKERLINK.LINKUNIQUEID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackerlinkRecord, UUID> LINKUNIQUEID = createField(DSL.name("LINKUNIQUEID"), org.jooq.impl.SQLDataType.UUID.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKERLINK.EVENTUNIQUEID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackerlinkRecord, UUID> EVENTUNIQUEID = createField(DSL.name("EVENTUNIQUEID"), org.jooq.impl.SQLDataType.UUID.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKERLINK.DROPUNIQUEID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackerlinkRecord, UUID> DROPUNIQUEID = createField(DSL.name("DROPUNIQUEID"), org.jooq.impl.SQLDataType.UUID.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKERLINK.USERUNIQUEID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackerlinkRecord, UUID> USERUNIQUEID = createField(DSL.name("USERUNIQUEID"), org.jooq.impl.SQLDataType.UUID.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* Create a <code>PUBLIC.LOOTTRACKERLINK</code> table reference
|
||||
*/
|
||||
public Loottrackerlink()
|
||||
{
|
||||
this(DSL.name("LOOTTRACKERLINK"), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.LOOTTRACKERLINK</code> table reference
|
||||
*/
|
||||
public Loottrackerlink(String alias)
|
||||
{
|
||||
this(DSL.name(alias), LOOTTRACKERLINK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.LOOTTRACKERLINK</code> table reference
|
||||
*/
|
||||
public Loottrackerlink(Name alias)
|
||||
{
|
||||
this(alias, LOOTTRACKERLINK);
|
||||
}
|
||||
|
||||
private Loottrackerlink(Name alias, Table<LoottrackerlinkRecord> aliased)
|
||||
{
|
||||
this(alias, aliased, null);
|
||||
}
|
||||
|
||||
private Loottrackerlink(Name alias, Table<LoottrackerlinkRecord> aliased, Field<?>[] parameters)
|
||||
{
|
||||
super(alias, null, aliased, parameters, DSL.comment(""));
|
||||
}
|
||||
|
||||
public <O extends Record> Loottrackerlink(Table<O> child, ForeignKey<O, LoottrackerlinkRecord> key)
|
||||
{
|
||||
super(child, key, LOOTTRACKERLINK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getSchema()
|
||||
{
|
||||
return Public.PUBLIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Index> getIndexes()
|
||||
{
|
||||
return Arrays.<Index>asList(Indexes.FK_LOOTTRACKERDROP_INDEX_6, Indexes.FK_LOOTTRACKEREVENT_INDEX_6, Indexes.FK_USER_INDEX_6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ForeignKey<LoottrackerlinkRecord, ?>> getReferences()
|
||||
{
|
||||
return Arrays.<ForeignKey<LoottrackerlinkRecord, ?>>asList(Keys.FK_LOOTTRACKEREVENT, Keys.FK_LOOTTRACKERDROP, Keys.FK_USER);
|
||||
}
|
||||
|
||||
public Loottrackerevents loottrackerevents()
|
||||
{
|
||||
return new Loottrackerevents(this, Keys.FK_LOOTTRACKEREVENT);
|
||||
}
|
||||
|
||||
public Loottrackerloot loottrackerloot()
|
||||
{
|
||||
return new Loottrackerloot(this, Keys.FK_LOOTTRACKERDROP);
|
||||
}
|
||||
|
||||
public User user()
|
||||
{
|
||||
return new User(this, Keys.FK_USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loottrackerlink as(String alias)
|
||||
{
|
||||
return new Loottrackerlink(DSL.name(alias), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loottrackerlink as(Name alias)
|
||||
{
|
||||
return new Loottrackerlink(alias, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public Loottrackerlink rename(String name)
|
||||
{
|
||||
return new Loottrackerlink(DSL.name(name), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public Loottrackerlink rename(Name name)
|
||||
{
|
||||
return new Loottrackerlink(name, null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Row4 type methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row4<UUID, UUID, UUID, UUID> fieldsRow()
|
||||
{
|
||||
return (Row4) super.fieldsRow();
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.Indexes;
|
||||
import net.runelite.client.database.data.Keys;
|
||||
import net.runelite.client.database.data.Public;
|
||||
import net.runelite.client.database.data.tables.records.LoottrackerlootRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Row3;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.UniqueKey;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.impl.TableImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class Loottrackerloot extends TableImpl<LoottrackerlootRecord>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 1461948279;
|
||||
|
||||
/**
|
||||
* The reference instance of <code>PUBLIC.LOOTTRACKERLOOT</code>
|
||||
*/
|
||||
public static final Loottrackerloot LOOTTRACKERLOOT = new Loottrackerloot();
|
||||
|
||||
/**
|
||||
* The class holding records for this type
|
||||
*/
|
||||
@Override
|
||||
public Class<LoottrackerlootRecord> getRecordType()
|
||||
{
|
||||
return LoottrackerlootRecord.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKERLOOT.UNIQUEID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackerlootRecord, UUID> UNIQUEID = createField(DSL.name("UNIQUEID"), org.jooq.impl.SQLDataType.UUID.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKERLOOT.ITEMID</code>.
|
||||
*/
|
||||
public final TableField<LoottrackerlootRecord, Integer> ITEMID = createField(DSL.name("ITEMID"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.LOOTTRACKERLOOT.QUANTITY</code>.
|
||||
*/
|
||||
public final TableField<LoottrackerlootRecord, Integer> QUANTITY = createField(DSL.name("QUANTITY"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* Create a <code>PUBLIC.LOOTTRACKERLOOT</code> table reference
|
||||
*/
|
||||
public Loottrackerloot()
|
||||
{
|
||||
this(DSL.name("LOOTTRACKERLOOT"), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.LOOTTRACKERLOOT</code> table reference
|
||||
*/
|
||||
public Loottrackerloot(String alias)
|
||||
{
|
||||
this(DSL.name(alias), LOOTTRACKERLOOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.LOOTTRACKERLOOT</code> table reference
|
||||
*/
|
||||
public Loottrackerloot(Name alias)
|
||||
{
|
||||
this(alias, LOOTTRACKERLOOT);
|
||||
}
|
||||
|
||||
private Loottrackerloot(Name alias, Table<LoottrackerlootRecord> aliased)
|
||||
{
|
||||
this(alias, aliased, null);
|
||||
}
|
||||
|
||||
private Loottrackerloot(Name alias, Table<LoottrackerlootRecord> aliased, Field<?>[] parameters)
|
||||
{
|
||||
super(alias, null, aliased, parameters, DSL.comment(""));
|
||||
}
|
||||
|
||||
public <O extends Record> Loottrackerloot(Table<O> child, ForeignKey<O, LoottrackerlootRecord> key)
|
||||
{
|
||||
super(child, key, LOOTTRACKERLOOT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getSchema()
|
||||
{
|
||||
return Public.PUBLIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Index> getIndexes()
|
||||
{
|
||||
return Arrays.<Index>asList(Indexes.PRIMARY_KEY_6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueKey<LoottrackerlootRecord> getPrimaryKey()
|
||||
{
|
||||
return Keys.PK_LOOTTRACKERDROPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UniqueKey<LoottrackerlootRecord>> getKeys()
|
||||
{
|
||||
return Arrays.<UniqueKey<LoottrackerlootRecord>>asList(Keys.PK_LOOTTRACKERDROPS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loottrackerloot as(String alias)
|
||||
{
|
||||
return new Loottrackerloot(DSL.name(alias), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loottrackerloot as(Name alias)
|
||||
{
|
||||
return new Loottrackerloot(alias, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public Loottrackerloot rename(String name)
|
||||
{
|
||||
return new Loottrackerloot(DSL.name(name), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public Loottrackerloot rename(Name name)
|
||||
{
|
||||
return new Loottrackerloot(name, null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Row3 type methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row3<UUID, Integer, Integer> fieldsRow()
|
||||
{
|
||||
return (Row3) super.fieldsRow();
|
||||
}
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.Indexes;
|
||||
import net.runelite.client.database.data.Public;
|
||||
import net.runelite.client.database.data.tables.records.TmorphSetsRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Row10;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.impl.TableImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class TmorphSets extends TableImpl<TmorphSetsRecord>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -2027086786;
|
||||
|
||||
/**
|
||||
* The reference instance of <code>PUBLIC.TMORPH_SETS</code>
|
||||
*/
|
||||
public static final TmorphSets TMORPH_SETS = new TmorphSets();
|
||||
|
||||
/**
|
||||
* The class holding records for this type
|
||||
*/
|
||||
@Override
|
||||
public Class<TmorphSetsRecord> getRecordType()
|
||||
{
|
||||
return TmorphSetsRecord.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.SET_NAME</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, String> SET_NAME = createField(DSL.name("SET_NAME"), org.jooq.impl.SQLDataType.VARCHAR(255).nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.HELMET</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> HELMET = createField(DSL.name("HELMET"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.CAPE</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> CAPE = createField(DSL.name("CAPE"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.AMULET</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> AMULET = createField(DSL.name("AMULET"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.WEAPON</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> WEAPON = createField(DSL.name("WEAPON"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.TORSO</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> TORSO = createField(DSL.name("TORSO"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.SHIELD</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> SHIELD = createField(DSL.name("SHIELD"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.LEGS</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> LEGS = createField(DSL.name("LEGS"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.HANDS</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> HANDS = createField(DSL.name("HANDS"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.TMORPH_SETS.BOOTS</code>.
|
||||
*/
|
||||
public final TableField<TmorphSetsRecord, Integer> BOOTS = createField(DSL.name("BOOTS"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* Create a <code>PUBLIC.TMORPH_SETS</code> table reference
|
||||
*/
|
||||
public TmorphSets()
|
||||
{
|
||||
this(DSL.name("TMORPH_SETS"), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.TMORPH_SETS</code> table reference
|
||||
*/
|
||||
public TmorphSets(String alias)
|
||||
{
|
||||
this(DSL.name(alias), TMORPH_SETS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.TMORPH_SETS</code> table reference
|
||||
*/
|
||||
public TmorphSets(Name alias)
|
||||
{
|
||||
this(alias, TMORPH_SETS);
|
||||
}
|
||||
|
||||
private TmorphSets(Name alias, Table<TmorphSetsRecord> aliased)
|
||||
{
|
||||
this(alias, aliased, null);
|
||||
}
|
||||
|
||||
private TmorphSets(Name alias, Table<TmorphSetsRecord> aliased, Field<?>[] parameters)
|
||||
{
|
||||
super(alias, null, aliased, parameters, DSL.comment(""));
|
||||
}
|
||||
|
||||
public <O extends Record> TmorphSets(Table<O> child, ForeignKey<O, TmorphSetsRecord> key)
|
||||
{
|
||||
super(child, key, TMORPH_SETS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getSchema()
|
||||
{
|
||||
return Public.PUBLIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Index> getIndexes()
|
||||
{
|
||||
return Arrays.<Index>asList(Indexes.TMORPH_SETS_SET_NAME_UINDEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSets as(String alias)
|
||||
{
|
||||
return new TmorphSets(DSL.name(alias), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSets as(Name alias)
|
||||
{
|
||||
return new TmorphSets(alias, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public TmorphSets rename(String name)
|
||||
{
|
||||
return new TmorphSets(DSL.name(name), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public TmorphSets rename(Name name)
|
||||
{
|
||||
return new TmorphSets(name, null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Row10 type methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row10<String, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer> fieldsRow()
|
||||
{
|
||||
return (Row10) super.fieldsRow();
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.Indexes;
|
||||
import net.runelite.client.database.data.Keys;
|
||||
import net.runelite.client.database.data.Public;
|
||||
import net.runelite.client.database.data.tables.records.UserRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Row2;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.UniqueKey;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.impl.TableImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class User extends TableImpl<UserRecord>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -668009102;
|
||||
|
||||
/**
|
||||
* The reference instance of <code>PUBLIC.USER</code>
|
||||
*/
|
||||
public static final User USER = new User();
|
||||
|
||||
/**
|
||||
* The class holding records for this type
|
||||
*/
|
||||
@Override
|
||||
public Class<UserRecord> getRecordType()
|
||||
{
|
||||
return UserRecord.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.USER.UNIQUEID</code>.
|
||||
*/
|
||||
public final TableField<UserRecord, UUID> UNIQUEID = createField(DSL.name("UNIQUEID"), org.jooq.impl.SQLDataType.UUID.nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* The column <code>PUBLIC.USER.USERNAME</code>.
|
||||
*/
|
||||
public final TableField<UserRecord, String> USERNAME = createField(DSL.name("USERNAME"), org.jooq.impl.SQLDataType.VARCHAR(12).nullable(false), this, "");
|
||||
|
||||
/**
|
||||
* Create a <code>PUBLIC.USER</code> table reference
|
||||
*/
|
||||
public User()
|
||||
{
|
||||
this(DSL.name("USER"), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.USER</code> table reference
|
||||
*/
|
||||
public User(String alias)
|
||||
{
|
||||
this(DSL.name(alias), USER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an aliased <code>PUBLIC.USER</code> table reference
|
||||
*/
|
||||
public User(Name alias)
|
||||
{
|
||||
this(alias, USER);
|
||||
}
|
||||
|
||||
private User(Name alias, Table<UserRecord> aliased)
|
||||
{
|
||||
this(alias, aliased, null);
|
||||
}
|
||||
|
||||
private User(Name alias, Table<UserRecord> aliased, Field<?>[] parameters)
|
||||
{
|
||||
super(alias, null, aliased, parameters, DSL.comment(""));
|
||||
}
|
||||
|
||||
public <O extends Record> User(Table<O> child, ForeignKey<O, UserRecord> key)
|
||||
{
|
||||
super(child, key, USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getSchema()
|
||||
{
|
||||
return Public.PUBLIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Index> getIndexes()
|
||||
{
|
||||
return Arrays.<Index>asList(Indexes.PRIMARY_KEY_2, Indexes.UN_USERNAME_INDEX_2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueKey<UserRecord> getPrimaryKey()
|
||||
{
|
||||
return Keys.PK_USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UniqueKey<UserRecord>> getKeys()
|
||||
{
|
||||
return Arrays.<UniqueKey<UserRecord>>asList(Keys.PK_USER, Keys.UN_USERNAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User as(String alias)
|
||||
{
|
||||
return new User(DSL.name(alias), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User as(Name alias)
|
||||
{
|
||||
return new User(alias, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public User rename(String name)
|
||||
{
|
||||
return new User(DSL.name(name), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename this table
|
||||
*/
|
||||
@Override
|
||||
public User rename(Name name)
|
||||
{
|
||||
return new User(name, null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Row2 type methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row2<UUID, String> fieldsRow()
|
||||
{
|
||||
return (Row2) super.fieldsRow();
|
||||
}
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables.records;
|
||||
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.Loottrackerevents;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.Record4;
|
||||
import org.jooq.Row4;
|
||||
import org.jooq.impl.UpdatableRecordImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class LoottrackereventsRecord extends UpdatableRecordImpl<LoottrackereventsRecord> implements Record4<UUID, String, String, Timestamp>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -1418522415;
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKEREVENTS.UNIQUEID</code>.
|
||||
*/
|
||||
public void setUniqueid(UUID value)
|
||||
{
|
||||
set(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKEREVENTS.UNIQUEID</code>.
|
||||
*/
|
||||
public UUID getUniqueid()
|
||||
{
|
||||
return (UUID) get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKEREVENTS.EVENTID</code>.
|
||||
*/
|
||||
public void setEventid(String value)
|
||||
{
|
||||
set(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKEREVENTS.EVENTID</code>.
|
||||
*/
|
||||
public String getEventid()
|
||||
{
|
||||
return (String) get(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKEREVENTS.TYPE</code>.
|
||||
*/
|
||||
public void setType(String value)
|
||||
{
|
||||
set(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKEREVENTS.TYPE</code>.
|
||||
*/
|
||||
public String getType()
|
||||
{
|
||||
return (String) get(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKEREVENTS.TIME</code>.
|
||||
*/
|
||||
public void setTime(Timestamp value)
|
||||
{
|
||||
set(3, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKEREVENTS.TIME</code>.
|
||||
*/
|
||||
public Timestamp getTime()
|
||||
{
|
||||
return (Timestamp) get(3);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Primary key information
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Record1<UUID> key()
|
||||
{
|
||||
return (Record1) super.key();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Record4 type implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row4<UUID, String, String, Timestamp> fieldsRow()
|
||||
{
|
||||
return (Row4) super.fieldsRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row4<UUID, String, String, Timestamp> valuesRow()
|
||||
{
|
||||
return (Row4) super.valuesRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<UUID> field1()
|
||||
{
|
||||
return Loottrackerevents.LOOTTRACKEREVENTS.UNIQUEID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<String> field2()
|
||||
{
|
||||
return Loottrackerevents.LOOTTRACKEREVENTS.EVENTID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<String> field3()
|
||||
{
|
||||
return Loottrackerevents.LOOTTRACKEREVENTS.TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Timestamp> field4()
|
||||
{
|
||||
return Loottrackerevents.LOOTTRACKEREVENTS.TIME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID component1()
|
||||
{
|
||||
return getUniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String component2()
|
||||
{
|
||||
return getEventid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String component3()
|
||||
{
|
||||
return getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp component4()
|
||||
{
|
||||
return getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID value1()
|
||||
{
|
||||
return getUniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value2()
|
||||
{
|
||||
return getEventid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value3()
|
||||
{
|
||||
return getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp value4()
|
||||
{
|
||||
return getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackereventsRecord value1(UUID value)
|
||||
{
|
||||
setUniqueid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackereventsRecord value2(String value)
|
||||
{
|
||||
setEventid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackereventsRecord value3(String value)
|
||||
{
|
||||
setType(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackereventsRecord value4(Timestamp value)
|
||||
{
|
||||
setTime(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackereventsRecord values(UUID value1, String value2, String value3, Timestamp value4)
|
||||
{
|
||||
value1(value1);
|
||||
value2(value2);
|
||||
value3(value3);
|
||||
value4(value4);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a detached LoottrackereventsRecord
|
||||
*/
|
||||
public LoottrackereventsRecord()
|
||||
{
|
||||
super(Loottrackerevents.LOOTTRACKEREVENTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a detached, initialised LoottrackereventsRecord
|
||||
*/
|
||||
public LoottrackereventsRecord(UUID uniqueid, String eventid, String type, Timestamp time)
|
||||
{
|
||||
super(Loottrackerevents.LOOTTRACKEREVENTS);
|
||||
|
||||
set(0, uniqueid);
|
||||
set(1, eventid);
|
||||
set(2, type);
|
||||
set(3, time);
|
||||
}
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables.records;
|
||||
|
||||
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.Loottrackerlink;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record4;
|
||||
import org.jooq.Row4;
|
||||
import org.jooq.impl.TableRecordImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class LoottrackerlinkRecord extends TableRecordImpl<LoottrackerlinkRecord> implements Record4<UUID, UUID, UUID, UUID>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -1701074584;
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKERLINK.LINKUNIQUEID</code>.
|
||||
*/
|
||||
public void setLinkuniqueid(UUID value)
|
||||
{
|
||||
set(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKERLINK.LINKUNIQUEID</code>.
|
||||
*/
|
||||
public UUID getLinkuniqueid()
|
||||
{
|
||||
return (UUID) get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKERLINK.EVENTUNIQUEID</code>.
|
||||
*/
|
||||
public void setEventuniqueid(UUID value)
|
||||
{
|
||||
set(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKERLINK.EVENTUNIQUEID</code>.
|
||||
*/
|
||||
public UUID getEventuniqueid()
|
||||
{
|
||||
return (UUID) get(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKERLINK.DROPUNIQUEID</code>.
|
||||
*/
|
||||
public void setDropuniqueid(UUID value)
|
||||
{
|
||||
set(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKERLINK.DROPUNIQUEID</code>.
|
||||
*/
|
||||
public UUID getDropuniqueid()
|
||||
{
|
||||
return (UUID) get(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKERLINK.USERUNIQUEID</code>.
|
||||
*/
|
||||
public void setUseruniqueid(UUID value)
|
||||
{
|
||||
set(3, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKERLINK.USERUNIQUEID</code>.
|
||||
*/
|
||||
public UUID getUseruniqueid()
|
||||
{
|
||||
return (UUID) get(3);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Record4 type implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row4<UUID, UUID, UUID, UUID> fieldsRow()
|
||||
{
|
||||
return (Row4) super.fieldsRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row4<UUID, UUID, UUID, UUID> valuesRow()
|
||||
{
|
||||
return (Row4) super.valuesRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<UUID> field1()
|
||||
{
|
||||
return Loottrackerlink.LOOTTRACKERLINK.LINKUNIQUEID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<UUID> field2()
|
||||
{
|
||||
return Loottrackerlink.LOOTTRACKERLINK.EVENTUNIQUEID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<UUID> field3()
|
||||
{
|
||||
return Loottrackerlink.LOOTTRACKERLINK.DROPUNIQUEID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<UUID> field4()
|
||||
{
|
||||
return Loottrackerlink.LOOTTRACKERLINK.USERUNIQUEID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID component1()
|
||||
{
|
||||
return getLinkuniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID component2()
|
||||
{
|
||||
return getEventuniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID component3()
|
||||
{
|
||||
return getDropuniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID component4()
|
||||
{
|
||||
return getUseruniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID value1()
|
||||
{
|
||||
return getLinkuniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID value2()
|
||||
{
|
||||
return getEventuniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID value3()
|
||||
{
|
||||
return getDropuniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID value4()
|
||||
{
|
||||
return getUseruniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlinkRecord value1(UUID value)
|
||||
{
|
||||
setLinkuniqueid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlinkRecord value2(UUID value)
|
||||
{
|
||||
setEventuniqueid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlinkRecord value3(UUID value)
|
||||
{
|
||||
setDropuniqueid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlinkRecord value4(UUID value)
|
||||
{
|
||||
setUseruniqueid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlinkRecord values(UUID value1, UUID value2, UUID value3, UUID value4)
|
||||
{
|
||||
value1(value1);
|
||||
value2(value2);
|
||||
value3(value3);
|
||||
value4(value4);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a detached LoottrackerlinkRecord
|
||||
*/
|
||||
public LoottrackerlinkRecord()
|
||||
{
|
||||
super(Loottrackerlink.LOOTTRACKERLINK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a detached, initialised LoottrackerlinkRecord
|
||||
*/
|
||||
public LoottrackerlinkRecord(UUID linkuniqueid, UUID eventuniqueid, UUID dropuniqueid, UUID useruniqueid)
|
||||
{
|
||||
super(Loottrackerlink.LOOTTRACKERLINK);
|
||||
|
||||
set(0, linkuniqueid);
|
||||
set(1, eventuniqueid);
|
||||
set(2, dropuniqueid);
|
||||
set(3, useruniqueid);
|
||||
}
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables.records;
|
||||
|
||||
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.Loottrackerloot;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.Record3;
|
||||
import org.jooq.Row3;
|
||||
import org.jooq.impl.UpdatableRecordImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class LoottrackerlootRecord extends UpdatableRecordImpl<LoottrackerlootRecord> implements Record3<UUID, Integer, Integer>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 693470968;
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKERLOOT.UNIQUEID</code>.
|
||||
*/
|
||||
public void setUniqueid(UUID value)
|
||||
{
|
||||
set(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKERLOOT.UNIQUEID</code>.
|
||||
*/
|
||||
public UUID getUniqueid()
|
||||
{
|
||||
return (UUID) get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKERLOOT.ITEMID</code>.
|
||||
*/
|
||||
public void setItemid(Integer value)
|
||||
{
|
||||
set(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKERLOOT.ITEMID</code>.
|
||||
*/
|
||||
public Integer getItemid()
|
||||
{
|
||||
return (Integer) get(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.LOOTTRACKERLOOT.QUANTITY</code>.
|
||||
*/
|
||||
public void setQuantity(Integer value)
|
||||
{
|
||||
set(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.LOOTTRACKERLOOT.QUANTITY</code>.
|
||||
*/
|
||||
public Integer getQuantity()
|
||||
{
|
||||
return (Integer) get(2);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Primary key information
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Record1<UUID> key()
|
||||
{
|
||||
return (Record1) super.key();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Record3 type implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row3<UUID, Integer, Integer> fieldsRow()
|
||||
{
|
||||
return (Row3) super.fieldsRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row3<UUID, Integer, Integer> valuesRow()
|
||||
{
|
||||
return (Row3) super.valuesRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<UUID> field1()
|
||||
{
|
||||
return Loottrackerloot.LOOTTRACKERLOOT.UNIQUEID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field2()
|
||||
{
|
||||
return Loottrackerloot.LOOTTRACKERLOOT.ITEMID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field3()
|
||||
{
|
||||
return Loottrackerloot.LOOTTRACKERLOOT.QUANTITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID component1()
|
||||
{
|
||||
return getUniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component2()
|
||||
{
|
||||
return getItemid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component3()
|
||||
{
|
||||
return getQuantity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID value1()
|
||||
{
|
||||
return getUniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value2()
|
||||
{
|
||||
return getItemid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value3()
|
||||
{
|
||||
return getQuantity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlootRecord value1(UUID value)
|
||||
{
|
||||
setUniqueid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlootRecord value2(Integer value)
|
||||
{
|
||||
setItemid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlootRecord value3(Integer value)
|
||||
{
|
||||
setQuantity(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoottrackerlootRecord values(UUID value1, Integer value2, Integer value3)
|
||||
{
|
||||
value1(value1);
|
||||
value2(value2);
|
||||
value3(value3);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a detached LoottrackerlootRecord
|
||||
*/
|
||||
public LoottrackerlootRecord()
|
||||
{
|
||||
super(Loottrackerloot.LOOTTRACKERLOOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a detached, initialised LoottrackerlootRecord
|
||||
*/
|
||||
public LoottrackerlootRecord(UUID uniqueid, Integer itemid, Integer quantity)
|
||||
{
|
||||
super(Loottrackerloot.LOOTTRACKERLOOT);
|
||||
|
||||
set(0, uniqueid);
|
||||
set(1, itemid);
|
||||
set(2, quantity);
|
||||
}
|
||||
}
|
||||
@@ -1,503 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables.records;
|
||||
|
||||
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.TmorphSets;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record10;
|
||||
import org.jooq.Row10;
|
||||
import org.jooq.impl.TableRecordImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class TmorphSetsRecord extends TableRecordImpl<TmorphSetsRecord> implements Record10<String, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 546214401;
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.SET_NAME</code>.
|
||||
*/
|
||||
public void setSetName(String value)
|
||||
{
|
||||
set(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.SET_NAME</code>.
|
||||
*/
|
||||
public String getSetName()
|
||||
{
|
||||
return (String) get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.HELMET</code>.
|
||||
*/
|
||||
public void setHelmet(Integer value)
|
||||
{
|
||||
set(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.HELMET</code>.
|
||||
*/
|
||||
public Integer getHelmet()
|
||||
{
|
||||
return (Integer) get(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.CAPE</code>.
|
||||
*/
|
||||
public void setCape(Integer value)
|
||||
{
|
||||
set(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.CAPE</code>.
|
||||
*/
|
||||
public Integer getCape()
|
||||
{
|
||||
return (Integer) get(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.AMULET</code>.
|
||||
*/
|
||||
public void setAmulet(Integer value)
|
||||
{
|
||||
set(3, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.AMULET</code>.
|
||||
*/
|
||||
public Integer getAmulet()
|
||||
{
|
||||
return (Integer) get(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.WEAPON</code>.
|
||||
*/
|
||||
public void setWeapon(Integer value)
|
||||
{
|
||||
set(4, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.WEAPON</code>.
|
||||
*/
|
||||
public Integer getWeapon()
|
||||
{
|
||||
return (Integer) get(4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.TORSO</code>.
|
||||
*/
|
||||
public void setTorso(Integer value)
|
||||
{
|
||||
set(5, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.TORSO</code>.
|
||||
*/
|
||||
public Integer getTorso()
|
||||
{
|
||||
return (Integer) get(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.SHIELD</code>.
|
||||
*/
|
||||
public void setShield(Integer value)
|
||||
{
|
||||
set(6, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.SHIELD</code>.
|
||||
*/
|
||||
public Integer getShield()
|
||||
{
|
||||
return (Integer) get(6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.LEGS</code>.
|
||||
*/
|
||||
public void setLegs(Integer value)
|
||||
{
|
||||
set(7, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.LEGS</code>.
|
||||
*/
|
||||
public Integer getLegs()
|
||||
{
|
||||
return (Integer) get(7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.HANDS</code>.
|
||||
*/
|
||||
public void setHands(Integer value)
|
||||
{
|
||||
set(8, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.HANDS</code>.
|
||||
*/
|
||||
public Integer getHands()
|
||||
{
|
||||
return (Integer) get(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.TMORPH_SETS.BOOTS</code>.
|
||||
*/
|
||||
public void setBoots(Integer value)
|
||||
{
|
||||
set(9, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.TMORPH_SETS.BOOTS</code>.
|
||||
*/
|
||||
public Integer getBoots()
|
||||
{
|
||||
return (Integer) get(9);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Record10 type implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row10<String, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer> fieldsRow()
|
||||
{
|
||||
return (Row10) super.fieldsRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row10<String, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer> valuesRow()
|
||||
{
|
||||
return (Row10) super.valuesRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<String> field1()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.SET_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field2()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.HELMET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field3()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.CAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field4()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.AMULET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field5()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.WEAPON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field6()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.TORSO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field7()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.SHIELD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field8()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.LEGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field9()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.HANDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<Integer> field10()
|
||||
{
|
||||
return TmorphSets.TMORPH_SETS.BOOTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String component1()
|
||||
{
|
||||
return getSetName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component2()
|
||||
{
|
||||
return getHelmet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component3()
|
||||
{
|
||||
return getCape();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component4()
|
||||
{
|
||||
return getAmulet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component5()
|
||||
{
|
||||
return getWeapon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component6()
|
||||
{
|
||||
return getTorso();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component7()
|
||||
{
|
||||
return getShield();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component8()
|
||||
{
|
||||
return getLegs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component9()
|
||||
{
|
||||
return getHands();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer component10()
|
||||
{
|
||||
return getBoots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value1()
|
||||
{
|
||||
return getSetName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value2()
|
||||
{
|
||||
return getHelmet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value3()
|
||||
{
|
||||
return getCape();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value4()
|
||||
{
|
||||
return getAmulet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value5()
|
||||
{
|
||||
return getWeapon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value6()
|
||||
{
|
||||
return getTorso();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value7()
|
||||
{
|
||||
return getShield();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value8()
|
||||
{
|
||||
return getLegs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value9()
|
||||
{
|
||||
return getHands();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer value10()
|
||||
{
|
||||
return getBoots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value1(String value)
|
||||
{
|
||||
setSetName(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value2(Integer value)
|
||||
{
|
||||
setHelmet(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value3(Integer value)
|
||||
{
|
||||
setCape(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value4(Integer value)
|
||||
{
|
||||
setAmulet(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value5(Integer value)
|
||||
{
|
||||
setWeapon(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value6(Integer value)
|
||||
{
|
||||
setTorso(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value7(Integer value)
|
||||
{
|
||||
setShield(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value8(Integer value)
|
||||
{
|
||||
setLegs(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value9(Integer value)
|
||||
{
|
||||
setHands(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord value10(Integer value)
|
||||
{
|
||||
setBoots(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmorphSetsRecord values(String value1, Integer value2, Integer value3, Integer value4, Integer value5, Integer value6, Integer value7, Integer value8, Integer value9, Integer value10)
|
||||
{
|
||||
value1(value1);
|
||||
value2(value2);
|
||||
value3(value3);
|
||||
value4(value4);
|
||||
value5(value5);
|
||||
value6(value6);
|
||||
value7(value7);
|
||||
value8(value8);
|
||||
value9(value9);
|
||||
value10(value10);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a detached TmorphSetsRecord
|
||||
*/
|
||||
public TmorphSetsRecord()
|
||||
{
|
||||
super(TmorphSets.TMORPH_SETS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a detached, initialised TmorphSetsRecord
|
||||
*/
|
||||
public TmorphSetsRecord(String setName, Integer helmet, Integer cape, Integer amulet, Integer weapon, Integer torso, Integer shield, Integer legs, Integer hands, Integer boots)
|
||||
{
|
||||
super(TmorphSets.TMORPH_SETS);
|
||||
|
||||
set(0, setName);
|
||||
set(1, helmet);
|
||||
set(2, cape);
|
||||
set(3, amulet);
|
||||
set(4, weapon);
|
||||
set(5, torso);
|
||||
set(6, shield);
|
||||
set(7, legs);
|
||||
set(8, hands);
|
||||
set(9, boots);
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
* This file is generated by jOOQ.
|
||||
*/
|
||||
package net.runelite.client.database.data.tables.records;
|
||||
|
||||
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.Generated;
|
||||
import net.runelite.client.database.data.tables.User;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.Record2;
|
||||
import org.jooq.Row2;
|
||||
import org.jooq.impl.UpdatableRecordImpl;
|
||||
|
||||
|
||||
/**
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@Generated(
|
||||
value = {
|
||||
"http://www.jooq.org",
|
||||
"jOOQ version:3.12.3"
|
||||
},
|
||||
comments = "This class is generated by jOOQ"
|
||||
)
|
||||
@SuppressWarnings({"all", "unchecked", "rawtypes"})
|
||||
public class UserRecord extends UpdatableRecordImpl<UserRecord> implements Record2<UUID, String>
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 2077804101;
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.USER.UNIQUEID</code>.
|
||||
*/
|
||||
public void setUniqueid(UUID value)
|
||||
{
|
||||
set(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.USER.UNIQUEID</code>.
|
||||
*/
|
||||
public UUID getUniqueid()
|
||||
{
|
||||
return (UUID) get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.USER.USERNAME</code>.
|
||||
*/
|
||||
public void setUsername(String value)
|
||||
{
|
||||
set(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for <code>PUBLIC.USER.USERNAME</code>.
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return (String) get(1);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Primary key information
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Record1<UUID> key()
|
||||
{
|
||||
return (Record1) super.key();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Record2 type implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Row2<UUID, String> fieldsRow()
|
||||
{
|
||||
return (Row2) super.fieldsRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row2<UUID, String> valuesRow()
|
||||
{
|
||||
return (Row2) super.valuesRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<UUID> field1()
|
||||
{
|
||||
return User.USER.UNIQUEID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field<String> field2()
|
||||
{
|
||||
return User.USER.USERNAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID component1()
|
||||
{
|
||||
return getUniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String component2()
|
||||
{
|
||||
return getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID value1()
|
||||
{
|
||||
return getUniqueid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value2()
|
||||
{
|
||||
return getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserRecord value1(UUID value)
|
||||
{
|
||||
setUniqueid(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserRecord value2(String value)
|
||||
{
|
||||
setUsername(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserRecord values(UUID value1, String value2)
|
||||
{
|
||||
value1(value1);
|
||||
value2(value2);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a detached UserRecord
|
||||
*/
|
||||
public UserRecord()
|
||||
{
|
||||
super(User.USER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a detached, initialised UserRecord
|
||||
*/
|
||||
public UserRecord(UUID uniqueid, String username)
|
||||
{
|
||||
super(User.USER);
|
||||
|
||||
set(0, uniqueid);
|
||||
set(1, username);
|
||||
}
|
||||
}
|
||||
@@ -198,7 +198,7 @@ public class DiscordService implements AutoCloseable
|
||||
{
|
||||
log.info("Discord RPC service is ready with user {}.", user.username);
|
||||
currentUser = user;
|
||||
eventBus.post(DiscordReady.class, new DiscordReady(
|
||||
eventBus.post(new DiscordReady(
|
||||
user.userId,
|
||||
user.username,
|
||||
user.discriminator,
|
||||
@@ -208,31 +208,31 @@ public class DiscordService implements AutoCloseable
|
||||
private void disconnected(int errorCode, String message)
|
||||
{
|
||||
log.debug("Discord disconnected {}: {}", errorCode, message);
|
||||
eventBus.post(DiscordDisconnected.class, new DiscordDisconnected(errorCode, message));
|
||||
eventBus.post(new DiscordDisconnected(errorCode, message));
|
||||
}
|
||||
|
||||
private void errored(int errorCode, String message)
|
||||
{
|
||||
log.warn("Discord error: {} - {}", errorCode, message);
|
||||
eventBus.post(DiscordErrored.class, new DiscordErrored(errorCode, message));
|
||||
eventBus.post(new DiscordErrored(errorCode, message));
|
||||
}
|
||||
|
||||
private void joinGame(String joinSecret)
|
||||
{
|
||||
log.debug("Discord join game: {}", joinSecret);
|
||||
eventBus.post(DiscordJoinGame.class, new DiscordJoinGame(joinSecret));
|
||||
eventBus.post(new DiscordJoinGame(joinSecret));
|
||||
}
|
||||
|
||||
private void spectateGame(String spectateSecret)
|
||||
{
|
||||
log.debug("Discord spectate game: {}", spectateSecret);
|
||||
eventBus.post(DiscordSpectateGame.class, new DiscordSpectateGame(spectateSecret));
|
||||
eventBus.post(new DiscordSpectateGame(spectateSecret));
|
||||
}
|
||||
|
||||
private void joinRequest(DiscordUser user)
|
||||
{
|
||||
log.debug("Discord join request: {}", user);
|
||||
eventBus.post(DiscordJoinRequest.class, new DiscordJoinRequest(
|
||||
eventBus.post(new DiscordJoinRequest(
|
||||
user.userId,
|
||||
user.username,
|
||||
user.discriminator,
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
package net.runelite.client.discord.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* Called when the RPC connection has been severed
|
||||
*/
|
||||
@Value
|
||||
public class DiscordDisconnected implements Event
|
||||
public class DiscordDisconnected
|
||||
{
|
||||
/**
|
||||
* Discord error code
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
package net.runelite.client.discord.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* Called when an internal error is caught within the SDK
|
||||
*/
|
||||
@Value
|
||||
public class DiscordErrored implements Event
|
||||
public class DiscordErrored
|
||||
{
|
||||
/**
|
||||
* Discord error code.
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
package net.runelite.client.discord.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* Called when the logged in user joined a game
|
||||
*/
|
||||
@Value
|
||||
public class DiscordJoinGame implements Event
|
||||
public class DiscordJoinGame
|
||||
{
|
||||
/**
|
||||
* Obfuscated data of your choosing used as join secret
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
package net.runelite.client.discord.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* Called when another discord user wants to join the game of the logged in user
|
||||
*/
|
||||
@Value
|
||||
public class DiscordJoinRequest implements Event
|
||||
public class DiscordJoinRequest
|
||||
{
|
||||
/**
|
||||
* The userId for the user that requests to join
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
package net.runelite.client.discord.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* Called when the RPC connection has been established
|
||||
*/
|
||||
@Value
|
||||
public class DiscordReady implements Event
|
||||
public class DiscordReady
|
||||
{
|
||||
/**
|
||||
* The userId for the active user
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
package net.runelite.client.discord.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* Called when the logged in user joined to spectate a game
|
||||
*/
|
||||
@Value
|
||||
public class DiscordSpectateGame implements Event
|
||||
public class DiscordSpectateGame
|
||||
{
|
||||
/**
|
||||
* Obfuscated data of your choosing used as spectate secret
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
package net.runelite.client.eventbus;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import io.reactivex.rxjava3.functions.Consumer;
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.LambdaMetafactory;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.MethodType;
|
||||
import static java.lang.invoke.MethodType.methodType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
@Slf4j
|
||||
public class AccessorGenerator
|
||||
{
|
||||
public static Set<Subscription> scanSubscribes(Lookup caller, Object ref)
|
||||
{
|
||||
ImmutableSet.Builder<Subscription> builder = ImmutableSet.builder();
|
||||
|
||||
final Class<?> refClass = ref.getClass();
|
||||
caller = getPrivateAccess(refClass, caller).in(refClass);
|
||||
|
||||
for (Method method : refClass.getDeclaredMethods())
|
||||
{
|
||||
Subscribe sub = method.getAnnotation(Subscribe.class);
|
||||
if (sub != null)
|
||||
{
|
||||
final Consumer accessor;
|
||||
final Class paramType = method.getParameterTypes()[0];
|
||||
|
||||
try
|
||||
{
|
||||
accessor = getConsumerFor(caller, ref, method);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
log.warn("Creating consumer lambda for {} failed!", method, t);
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.add(new Subscription(paramType, accessor, sub.takeUntil(), sub.subscribe(), sub.observe()));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <EVENT extends Event> Consumer<EVENT> getConsumerFor(Lookup caller, Object ref, Method method) throws Throwable
|
||||
{
|
||||
final MethodHandle methodHandle = caller.unreflect(method);
|
||||
|
||||
final MethodType actualConsumer = methodHandle.type().dropParameterTypes(0, 1);
|
||||
final MethodType eventsConsumer = actualConsumer.erase();
|
||||
final MethodType factoryType = methodType(Consumer.class, ref.getClass());
|
||||
|
||||
final CallSite callsite = LambdaMetafactory.metafactory(
|
||||
caller, // To get past security checks
|
||||
"accept", // The name of the method to implement inside the lambda type
|
||||
factoryType, // Signature of the factory method
|
||||
eventsConsumer, // Signature of function implementation
|
||||
methodHandle, // Target method
|
||||
actualConsumer // Target method signature
|
||||
);
|
||||
|
||||
final MethodHandle factory = callsite.getTarget();
|
||||
return (Consumer<EVENT>) factory.invoke(ref);
|
||||
}
|
||||
|
||||
private static Lookup getPrivateAccess(Class<?> into, Lookup from)
|
||||
{
|
||||
try
|
||||
{
|
||||
return MethodHandles.privateLookupIn(into, from);
|
||||
}
|
||||
catch (IllegalAccessException a)
|
||||
{
|
||||
log.warn("Failed to get private access in {} from {}", into, from, a);
|
||||
return from;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018, Abex
|
||||
* 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.eventbus;
|
||||
|
||||
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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.LambdaMetafactory;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Comparator;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.config.OpenOSRSConfig;
|
||||
import net.runelite.client.util.ReflectUtil;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class EventBus implements EventBusInterface
|
||||
@RequiredArgsConstructor
|
||||
@ThreadSafe
|
||||
public class EventBus
|
||||
{
|
||||
private final Map<Object, Object> subscriptionList = new HashMap<>();
|
||||
private final Map<Class<?>, Relay<Object>> subjectList = new HashMap<>();
|
||||
private final Map<Object, CompositeDisposable> subscriptionsMap = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
private OpenOSRSConfig openOSRSConfig;
|
||||
|
||||
@NonNull
|
||||
private <T extends Event> Relay<Object> getSubject(Class<T> eventClass)
|
||||
@FunctionalInterface
|
||||
public interface SubscriberMethod
|
||||
{
|
||||
return subjectList.computeIfAbsent(eventClass, k -> PublishRelay.create().toSerialized());
|
||||
void invoke(Object event);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private CompositeDisposable getCompositeDisposable(@NonNull Object object)
|
||||
@Value
|
||||
private static class Subscriber
|
||||
{
|
||||
CompositeDisposable compositeDisposable = subscriptionsMap.get(object);
|
||||
if (compositeDisposable == null)
|
||||
private final Object object;
|
||||
private final Method method;
|
||||
private final float priority;
|
||||
@EqualsAndHashCode.Exclude
|
||||
private final SubscriberMethod lamda;
|
||||
|
||||
void invoke(final Object arg) throws Exception
|
||||
{
|
||||
compositeDisposable = new CompositeDisposable();
|
||||
subscriptionsMap.put(object, compositeDisposable);
|
||||
if (lamda != null)
|
||||
{
|
||||
lamda.invoke(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
method.invoke(object, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Consumer<Throwable> exceptionHandler;
|
||||
private ImmutableMultimap<Class, Subscriber> subscribers = ImmutableMultimap.of();
|
||||
|
||||
/**
|
||||
* Instantiates EventBus with default exception handler
|
||||
*/
|
||||
public EventBus()
|
||||
{
|
||||
this((e) -> log.warn("Uncaught exception in event subscriber", e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers subscriber to EventBus. All methods in subscriber and it's parent classes are checked for
|
||||
* {@link Subscribe} annotation and then added to map of subscriptions.
|
||||
*
|
||||
* @param object subscriber to register
|
||||
* @throws IllegalArgumentException in case subscriber method name is wrong (correct format is 'on' + EventName
|
||||
*/
|
||||
public synchronized void register(@Nonnull final Object object)
|
||||
{
|
||||
final ImmutableMultimap.Builder<Class, Subscriber> builder = ImmutableMultimap.builder();
|
||||
|
||||
if (subscribers != null)
|
||||
{
|
||||
builder.putAll(subscribers);
|
||||
}
|
||||
|
||||
return compositeDisposable;
|
||||
builder.orderValuesBy(Comparator.comparing(Subscriber::getPriority).reversed()
|
||||
.thenComparing(s -> s.object.getClass().getName()));
|
||||
|
||||
for (Class<?> clazz = object.getClass(); clazz != null; clazz = clazz.getSuperclass())
|
||||
{
|
||||
for (final Method method : clazz.getDeclaredMethods())
|
||||
{
|
||||
final Subscribe sub = method.getAnnotation(Subscribe.class);
|
||||
|
||||
if (sub == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Preconditions.checkArgument(method.getReturnType() == Void.TYPE, "@Subscribed method \"" + method + "\" cannot return a value");
|
||||
Preconditions.checkArgument(method.getParameterCount() == 1, "@Subscribed method \"" + method + "\" must take exactly 1 argument");
|
||||
Preconditions.checkArgument(!Modifier.isStatic(method.getModifiers()), "@Subscribed method \"" + method + "\" cannot be static");
|
||||
|
||||
final Class<?> parameterClazz = method.getParameterTypes()[0];
|
||||
|
||||
Preconditions.checkArgument(!parameterClazz.isPrimitive(), "@Subscribed method \"" + method + "\" cannot subscribe to primitives");
|
||||
Preconditions.checkArgument((parameterClazz.getModifiers() & (Modifier.ABSTRACT | Modifier.INTERFACE)) == 0, "@Subscribed method \"" + method + "\" cannot subscribe to polymorphic classes");
|
||||
|
||||
for (Class<?> psc = parameterClazz.getSuperclass(); psc != null; psc = psc.getSuperclass())
|
||||
{
|
||||
if (subscribers.containsKey(psc))
|
||||
{
|
||||
throw new IllegalArgumentException("@Subscribed method \"" + method + "\" cannot subscribe to class which inherits from subscribed class \"" + psc + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
final String preferredName = "on" + parameterClazz.getSimpleName();
|
||||
Preconditions.checkArgument(method.getName().equals(preferredName), "Subscribed method " + method + " should be named " + preferredName);
|
||||
|
||||
method.setAccessible(true);
|
||||
SubscriberMethod lambda = null;
|
||||
|
||||
try
|
||||
{
|
||||
final MethodHandles.Lookup caller = ReflectUtil.privateLookupIn(clazz);
|
||||
final MethodType subscription = MethodType.methodType(void.class, parameterClazz);
|
||||
final MethodHandle target = caller.findVirtual(clazz, method.getName(), subscription);
|
||||
final CallSite site = LambdaMetafactory.metafactory(
|
||||
caller,
|
||||
"invoke",
|
||||
MethodType.methodType(SubscriberMethod.class, clazz),
|
||||
subscription.changeParameterType(0, Object.class),
|
||||
target,
|
||||
subscription);
|
||||
|
||||
final MethodHandle factory = site.getTarget();
|
||||
lambda = (SubscriberMethod) factory.bindTo(object).invokeExact();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
log.warn("Unable to create lambda for method {}", method, e);
|
||||
}
|
||||
|
||||
final Subscriber subscriber = new Subscriber(object, method, sub.priority(), lambda);
|
||||
builder.put(parameterClazz, subscriber);
|
||||
log.debug("Registering {} - {}", parameterClazz, subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
subscribers = builder.build();
|
||||
}
|
||||
|
||||
private <T> ObservableTransformer<T, T> applyTake(int until)
|
||||
/**
|
||||
* Unregisters all subscribed methods from provided subscriber object.
|
||||
*
|
||||
* @param object object to unsubscribe from
|
||||
*/
|
||||
public synchronized void unregister(@Nonnull final Object object)
|
||||
{
|
||||
return observable -> until > 0 ? observable.take(until) : observable;
|
||||
}
|
||||
|
||||
private <T> ObservableTransformer<T, T> applyScheduler(EventScheduler eventScheduler, boolean subscribe)
|
||||
{
|
||||
Scheduler scheduler = eventScheduler.get();
|
||||
|
||||
return observable -> scheduler == null ? observable : subscribe ? observable.subscribeOn(scheduler) : observable.observeOn(scheduler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Event> void subscribe(Class<T> eventClass, @NonNull Object lifecycle, @NonNull Consumer<T> action)
|
||||
{
|
||||
subscribe(eventClass, lifecycle, action, -1, EventScheduler.DEFAULT, EventScheduler.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Event> void subscribe(Class<T> eventClass, @NonNull Object lifecycle, @NonNull Consumer<T> action, int takeUtil)
|
||||
{
|
||||
subscribe(eventClass, lifecycle, action, takeUtil, EventScheduler.DEFAULT, EventScheduler.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
// Subscribe on lifecycle (for example from plugin startUp -> shutdown)
|
||||
public <T extends Event> void subscribe(Class<T> eventClass, @NonNull Object lifecycle, @NonNull Consumer<T> action, int takeUntil, @Nullable EventScheduler subscribe, @Nullable EventScheduler observe)
|
||||
{
|
||||
assert Event.class.isAssignableFrom(eventClass) : "Parameters of methods annotated with @Subscribe should implement net.runelite.api.events.Event";
|
||||
|
||||
if (subscriptionList.containsKey(lifecycle) && eventClass.equals(subscriptionList.get(lifecycle)))
|
||||
if (subscribers == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Disposable disposable = getSubject(eventClass)
|
||||
.compose(applyTake(takeUntil))
|
||||
.filter(Objects::nonNull) // Filter out null objects, better safe than sorry
|
||||
.cast(eventClass) // Cast it for easier usage
|
||||
.doFinally(() -> unregister(lifecycle))
|
||||
.compose(applyScheduler(subscribe, true))
|
||||
.compose(applyScheduler(observe, false))
|
||||
.subscribe(action, error ->
|
||||
log.error("Exception in eventbus", error));
|
||||
final Multimap<Class, Subscriber> map = HashMultimap.create();
|
||||
map.putAll(subscribers);
|
||||
|
||||
getCompositeDisposable(lifecycle).add(disposable);
|
||||
subscriptionList.put(lifecycle, eventClass);
|
||||
for (Class<?> clazz = object.getClass(); clazz != null; clazz = clazz.getSuperclass())
|
||||
{
|
||||
for (final Method method : clazz.getDeclaredMethods())
|
||||
{
|
||||
final Subscribe sub = method.getAnnotation(Subscribe.class);
|
||||
|
||||
if (sub == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Class<?> parameterClazz = method.getParameterTypes()[0];
|
||||
map.remove(parameterClazz, new Subscriber(object, method, sub.priority(), null));
|
||||
}
|
||||
}
|
||||
|
||||
subscribers = ImmutableMultimap.copyOf(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(@NonNull Object lifecycle)
|
||||
/**
|
||||
* Posts provided event to all registered subscribers. Subscriber calls are invoked immediately,
|
||||
* ordered by priority then their declaring class' name.
|
||||
*
|
||||
* @param event event to post
|
||||
*/
|
||||
public void post(@Nonnull final Object event)
|
||||
{
|
||||
//We have to remove the composition from the map, because once you dispose it can't be used anymore
|
||||
CompositeDisposable compositeDisposable = subscriptionsMap.remove(lifecycle);
|
||||
subscriptionList.remove(lifecycle);
|
||||
if (compositeDisposable != null)
|
||||
for (final Subscriber subscriber : subscribers.get(event.getClass()))
|
||||
{
|
||||
compositeDisposable.dispose();
|
||||
try
|
||||
{
|
||||
subscriber.invoke(event);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptionHandler.accept(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Event> void post(Class<? extends T> eventClass, @NonNull T event)
|
||||
{
|
||||
getSubject(eventClass).accept(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package net.runelite.client.eventbus;
|
||||
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.functions.Consumer;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
public interface EventBusInterface
|
||||
{
|
||||
<T extends Event> void subscribe(Class<T> eventClass, @NonNull Object lifecycle, @NonNull Consumer<T> action);
|
||||
|
||||
<T extends Event> void subscribe(Class<T> eventClass, @NonNull Object lifecycle, @NonNull Consumer<T> action, int takeUntil);
|
||||
|
||||
<T extends Event> void subscribe(Class<T> eventClass, @NonNull Object lifecycle, @NonNull Consumer<T> action, int takeUntil, EventScheduler subscribe, EventScheduler observe);
|
||||
|
||||
void unregister(@NonNull Object lifecycle);
|
||||
|
||||
<T extends Event> void post(Class<? extends T> eventClass, @NonNull T event);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package net.runelite.client.eventbus;
|
||||
|
||||
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
|
||||
public enum EventScheduler
|
||||
{
|
||||
DEFAULT(() -> null),
|
||||
COMPUTATION(Schedulers::computation),
|
||||
IO(Schedulers::io),
|
||||
NEWTHREAD(Schedulers::newThread),
|
||||
SINGLE(Schedulers::single),
|
||||
TRAMPOLINE(Schedulers::trampoline),
|
||||
CLIENT(Schedulers::single);
|
||||
|
||||
private Supplier<Scheduler> scheduler;
|
||||
|
||||
@Nullable
|
||||
public Scheduler get()
|
||||
{
|
||||
try
|
||||
{
|
||||
return scheduler.get();
|
||||
}
|
||||
catch (Throwable ignored)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,5 @@ import java.lang.annotation.Target;
|
||||
@Documented
|
||||
public @interface Subscribe
|
||||
{
|
||||
int takeUntil() default -1;
|
||||
EventScheduler subscribe() default EventScheduler.DEFAULT;
|
||||
EventScheduler observe() default EventScheduler.DEFAULT;
|
||||
float priority() default 0;
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package net.runelite.client.eventbus;
|
||||
|
||||
import io.reactivex.rxjava3.functions.Consumer;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class Subscription
|
||||
{
|
||||
private final Class type;
|
||||
private final Consumer method;
|
||||
private final int takeUntil;
|
||||
private final EventScheduler subscribe;
|
||||
private final EventScheduler observe;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void subscribe(EventBus eventBus, Object lifecycle)
|
||||
{
|
||||
eventBus.subscribe(type, lifecycle, method, takeUntil, subscribe, observe);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.game.AttackStyle;
|
||||
|
||||
/**
|
||||
* This will fire when {@link net.runelite.client.game.PlayerManager} detects
|
||||
* a change in the player appearance that resulted in the shifting of an attack style.
|
||||
* For example, ranged str went to 0, but melee str went to 108.
|
||||
*/
|
||||
@Value
|
||||
public class AttackStyleChanged implements Event
|
||||
{
|
||||
/**
|
||||
* The player that changed styles.
|
||||
*/
|
||||
Player player;
|
||||
|
||||
/**
|
||||
* Can be Unknown(nullable)
|
||||
*
|
||||
* @see net.runelite.client.game.AttackStyle
|
||||
*/
|
||||
AttackStyle oldStyle;
|
||||
|
||||
/**
|
||||
* Can be Unknown(nullable)
|
||||
*
|
||||
* @see net.runelite.client.game.AttackStyle
|
||||
*/
|
||||
AttackStyle newStyle;
|
||||
}
|
||||
@@ -24,18 +24,7 @@
|
||||
*/
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
public abstract class ChatInput implements Event
|
||||
public abstract class ChatInput
|
||||
{
|
||||
@Getter
|
||||
private boolean stop = false;
|
||||
|
||||
public void setStop()
|
||||
{
|
||||
this.stop = true;
|
||||
}
|
||||
|
||||
public abstract void resume();
|
||||
}
|
||||
|
||||
@@ -31,13 +31,12 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
@Value
|
||||
@Slf4j
|
||||
public class ClientShutdown implements Event
|
||||
public class ClientShutdown
|
||||
{
|
||||
Queue<Future<?>> tasks = new ConcurrentLinkedQueue<>();
|
||||
private Queue<Future<?>> tasks = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public void waitFor(Future<?> future)
|
||||
{
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
*/
|
||||
package net.runelite.client.events;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.config.RuneScapeProfile;
|
||||
|
||||
/**
|
||||
* An event where a configuration entry has been modified.
|
||||
*/
|
||||
@Data
|
||||
public class ConfigChanged implements Event, Serializable
|
||||
public class ConfigChanged
|
||||
{
|
||||
/**
|
||||
* The parent group for the key.
|
||||
@@ -41,6 +41,14 @@ public class ConfigChanged implements Event, Serializable
|
||||
* between other key values that may have the same name.
|
||||
*/
|
||||
private String group;
|
||||
|
||||
/**
|
||||
* The profile that has changed, if any
|
||||
*
|
||||
* @see RuneScapeProfile#getKey()
|
||||
*/
|
||||
@Nullable
|
||||
private String profile;
|
||||
/**
|
||||
* The configuration key that has been modified.
|
||||
*/
|
||||
@@ -53,12 +61,4 @@ public class ConfigChanged implements Event, Serializable
|
||||
* The new value of the entry, null if the entry has been unset.
|
||||
*/
|
||||
private String newValue;
|
||||
/**
|
||||
* The client where the config value was changed from
|
||||
*/
|
||||
private String origin;
|
||||
/**
|
||||
* Path of the current config file
|
||||
*/
|
||||
private String path;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* Copyright (c) 2019 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -24,14 +24,15 @@
|
||||
*/
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import java.util.List;
|
||||
import lombok.Value;
|
||||
import net.runelite.client.externalplugins.ExternalPluginManifest;
|
||||
|
||||
@Data
|
||||
public class ExternalPluginChanged implements Event
|
||||
/**
|
||||
* Posted when an external plugin has been added, removed, or updated
|
||||
*/
|
||||
@Value
|
||||
public class ExternalPluginsChanged
|
||||
{
|
||||
private final String pluginId;
|
||||
private final Plugin plugin;
|
||||
private final boolean added;
|
||||
private final List<ExternalPluginManifest> loadedManifest;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.events;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
@Data
|
||||
public class ExternalPluginsLoaded implements Event
|
||||
{}
|
||||
@@ -25,13 +25,12 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
|
||||
@Value
|
||||
public class InfoBoxMenuClicked implements Event
|
||||
public class InfoBoxMenuClicked
|
||||
{
|
||||
OverlayMenuEntry entry;
|
||||
InfoBox infoBox;
|
||||
private OverlayMenuEntry entry;
|
||||
private InfoBox infoBox;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,10 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
|
||||
@Value
|
||||
public class NavigationButtonAdded implements Event
|
||||
public class NavigationButtonAdded
|
||||
{
|
||||
NavigationButton button;
|
||||
private NavigationButton button;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,10 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
|
||||
@Value
|
||||
public class NavigationButtonRemoved implements Event
|
||||
public class NavigationButtonRemoved
|
||||
{
|
||||
NavigationButton button;
|
||||
private NavigationButton button;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,10 @@ package net.runelite.client.events;
|
||||
|
||||
import java.awt.TrayIcon;
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
@Value
|
||||
public class NotificationFired implements Event
|
||||
public class NotificationFired
|
||||
{
|
||||
String message;
|
||||
TrayIcon.MessageType type;
|
||||
final String message;
|
||||
final TrayIcon.MessageType type;
|
||||
}
|
||||
|
||||
@@ -27,12 +27,11 @@ package net.runelite.client.events;
|
||||
import java.util.Collection;
|
||||
import lombok.Value;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.game.ItemStack;
|
||||
|
||||
@Value
|
||||
public class NpcLootReceived implements Event
|
||||
public class NpcLootReceived
|
||||
{
|
||||
NPC npc;
|
||||
Collection<ItemStack> items;
|
||||
private final NPC npc;
|
||||
private final Collection<ItemStack> items;
|
||||
}
|
||||
|
||||
@@ -24,19 +24,16 @@
|
||||
*/
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
import lombok.Value;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
|
||||
/**
|
||||
* Event fired when an overlay menu entry is clicked.
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class OverlayMenuClicked implements Event
|
||||
@Value
|
||||
public class OverlayMenuClicked
|
||||
{
|
||||
private OverlayMenuEntry entry;
|
||||
private Overlay overlay;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,9 @@ package net.runelite.client.events;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
@Value
|
||||
public class PartyChanged implements Event
|
||||
public class PartyChanged
|
||||
{
|
||||
UUID partyId;
|
||||
private final UUID partyId;
|
||||
}
|
||||
|
||||
@@ -27,12 +27,11 @@ package net.runelite.client.events;
|
||||
import java.util.Collection;
|
||||
import lombok.Value;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.game.ItemStack;
|
||||
|
||||
@Value
|
||||
public class PlayerLootReceived implements Event
|
||||
public class PlayerLootReceived
|
||||
{
|
||||
Player player;
|
||||
Collection<ItemStack> items;
|
||||
private final Player player;
|
||||
private final Collection<ItemStack> items;
|
||||
}
|
||||
@@ -25,11 +25,10 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
|
||||
@Data
|
||||
public class PluginChanged implements Event
|
||||
public class PluginChanged
|
||||
{
|
||||
private final Plugin plugin;
|
||||
private final boolean loaded;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* Copyright (c) 2020 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -24,12 +24,11 @@
|
||||
*/
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
@Data
|
||||
public class ExternalRepositoryChanged implements Event
|
||||
/**
|
||||
* Posted when the user switches to a different RuneScape save profile
|
||||
* This might be because they logged into a different account, or hopped
|
||||
* to/from a Beta/Tournament/DMM/Leagues world
|
||||
*/
|
||||
public class RuneScapeProfileChanged
|
||||
{
|
||||
private final String owner;
|
||||
private final boolean added;
|
||||
}
|
||||
@@ -25,7 +25,6 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* An event where a new RuneLite account session has been closed,
|
||||
@@ -35,4 +34,7 @@ import net.runelite.api.events.Event;
|
||||
* it has nothing to do with whether an account is being logged out.
|
||||
*/
|
||||
@Data
|
||||
public class SessionClose implements Event {}
|
||||
public class SessionClose
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Data;
|
||||
import net.runelite.api.events.Event;
|
||||
|
||||
/**
|
||||
* An event where a new RuneLite account session has been opened
|
||||
@@ -35,4 +34,7 @@ import net.runelite.api.events.Event;
|
||||
* it has nothing to do with whether an account is being logged in.
|
||||
*/
|
||||
@Data
|
||||
public class SessionOpen implements Event {}
|
||||
public class SessionOpen
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -25,14 +25,13 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.api.events.Event;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
|
||||
/**
|
||||
* Fired when the @{link net.runelite.client.game.WorldService} refreshes the world list
|
||||
*/
|
||||
@Value
|
||||
public class WorldsFetch implements Event
|
||||
public class WorldsFetch
|
||||
{
|
||||
WorldResult worldResult;
|
||||
}
|
||||
private final WorldResult worldResult;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2019 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,17 +22,20 @@
|
||||
* (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;
|
||||
package net.runelite.client.externalplugins;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import javax.swing.JPanel;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import lombok.Getter;
|
||||
|
||||
class FixedWidthPanel extends JPanel
|
||||
class ExternalPluginClassLoader extends URLClassLoader
|
||||
{
|
||||
@Override
|
||||
public Dimension getPreferredSize()
|
||||
@Getter
|
||||
private final ExternalPluginManifest manifest;
|
||||
|
||||
ExternalPluginClassLoader(ExternalPluginManifest manifest, URL[] urls)
|
||||
{
|
||||
return new Dimension(PluginPanel.PANEL_WIDTH, super.getPreferredSize().height);
|
||||
super(urls, ExternalPluginClassLoader.class.getClassLoader());
|
||||
this.manifest = manifest;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.externalplugins;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.util.VerificationException;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okio.BufferedSource;
|
||||
|
||||
@Slf4j
|
||||
public class ExternalPluginClient
|
||||
{
|
||||
private final OkHttpClient okHttpClient;
|
||||
|
||||
@Inject
|
||||
private ExternalPluginClient(OkHttpClient okHttpClient)
|
||||
{
|
||||
this.okHttpClient = okHttpClient;
|
||||
}
|
||||
|
||||
public List<ExternalPluginManifest> downloadManifest() throws IOException, VerificationException
|
||||
{
|
||||
HttpUrl manifest = RuneLiteProperties.getPluginHubBase()
|
||||
.newBuilder()
|
||||
.addPathSegments("manifest.js")
|
||||
.build();
|
||||
try (Response res = okHttpClient.newCall(new Request.Builder().url(manifest).build()).execute())
|
||||
{
|
||||
if (res.code() != 200)
|
||||
{
|
||||
throw new IOException("Non-OK response code: " + res.code());
|
||||
}
|
||||
|
||||
BufferedSource src = res.body().source();
|
||||
|
||||
byte[] signature = new byte[src.readInt()];
|
||||
src.readFully(signature);
|
||||
|
||||
byte[] data = src.readByteArray();
|
||||
Signature s = Signature.getInstance("SHA256withRSA");
|
||||
s.initVerify(loadCertificate());
|
||||
s.update(data);
|
||||
|
||||
if (!s.verify(signature))
|
||||
{
|
||||
throw new VerificationException("Unable to verify external plugin manifest");
|
||||
}
|
||||
|
||||
return RuneLiteAPI.GSON.fromJson(new String(data, StandardCharsets.UTF_8),
|
||||
new TypeToken<List<ExternalPluginManifest>>()
|
||||
{
|
||||
}.getType());
|
||||
}
|
||||
catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public BufferedImage downloadIcon(ExternalPluginManifest plugin) throws IOException
|
||||
{
|
||||
if (!plugin.hasIcon())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
HttpUrl url = RuneLiteProperties.getPluginHubBase()
|
||||
.newBuilder()
|
||||
.addPathSegment(plugin.getInternalName())
|
||||
.addPathSegment(plugin.getCommit() + ".png")
|
||||
.build();
|
||||
|
||||
try (Response res = okHttpClient.newCall(new Request.Builder().url(url).build()).execute())
|
||||
{
|
||||
byte[] bytes = res.body().bytes();
|
||||
// We don't stream so the lock doesn't block the edt trying to load something at the same time
|
||||
synchronized (ImageIO.class)
|
||||
{
|
||||
return ImageIO.read(new ByteArrayInputStream(bytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Certificate loadCertificate()
|
||||
{
|
||||
try
|
||||
{
|
||||
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||
Certificate certificate = certFactory.generateCertificate(ExternalPluginClient.class.getResourceAsStream("externalplugins.crt"));
|
||||
return certificate;
|
||||
}
|
||||
catch (CertificateException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void submitPlugins(List<String> plugins)
|
||||
{
|
||||
if (plugins.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||
.addPathSegment("pluginhub")
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.post(RequestBody.create(RuneLiteAPI.JSON, RuneLiteAPI.GSON.toJson(plugins)))
|
||||
.build();
|
||||
|
||||
okHttpClient.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e)
|
||||
{
|
||||
log.debug("Error submitting plugins", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response)
|
||||
{
|
||||
log.debug("Submitted plugin list");
|
||||
response.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.externalplugins;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.hash.HashingInputStream;
|
||||
import com.google.common.io.Files;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.SwingUtilities;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ExternalPluginsChanged;
|
||||
import net.runelite.client.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginInstantiationException;
|
||||
import net.runelite.client.plugins.PluginManager;
|
||||
import net.runelite.client.ui.SplashScreen;
|
||||
import net.runelite.client.util.CountingInputStream;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.client.util.VerificationException;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ExternalPluginManager
|
||||
{
|
||||
private static final String PLUGIN_LIST_KEY = "externalPlugins";
|
||||
private static Class<? extends Plugin>[] builtinExternals = null;
|
||||
|
||||
@Inject
|
||||
@Named("safeMode")
|
||||
private boolean safeMode;
|
||||
|
||||
private final ConfigManager configManager;
|
||||
private final ExternalPluginClient externalPluginClient;
|
||||
private final ScheduledExecutorService executor;
|
||||
private final PluginManager pluginManager;
|
||||
private final EventBus eventBus;
|
||||
private final OkHttpClient okHttpClient;
|
||||
|
||||
@Inject
|
||||
private ExternalPluginManager(
|
||||
ConfigManager configManager,
|
||||
ExternalPluginClient externalPluginClient,
|
||||
ScheduledExecutorService executor,
|
||||
PluginManager pluginManager,
|
||||
EventBus eventBus,
|
||||
OkHttpClient okHttpClient
|
||||
)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.externalPluginClient = externalPluginClient;
|
||||
this.executor = executor;
|
||||
this.pluginManager = pluginManager;
|
||||
this.eventBus = eventBus;
|
||||
this.okHttpClient = okHttpClient;
|
||||
|
||||
executor.scheduleWithFixedDelay(() -> externalPluginClient.submitPlugins(getInstalledExternalPlugins()),
|
||||
new Random().nextInt(60), 180, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
public void loadExternalPlugins() throws PluginInstantiationException
|
||||
{
|
||||
refreshPlugins();
|
||||
|
||||
if (builtinExternals != null)
|
||||
{
|
||||
// builtin external's don't actually have a manifest or a separate classloader...
|
||||
pluginManager.loadPlugins(Lists.newArrayList(builtinExternals), null);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionOpen(SessionOpen event)
|
||||
{
|
||||
executor.submit(this::refreshPlugins);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionClose(SessionClose event)
|
||||
{
|
||||
executor.submit(this::refreshPlugins);
|
||||
}
|
||||
|
||||
private void refreshPlugins()
|
||||
{
|
||||
if (safeMode)
|
||||
{
|
||||
log.debug("External plugins are disabled in safe mode!");
|
||||
return;
|
||||
}
|
||||
|
||||
Multimap<ExternalPluginManifest, Plugin> loadedExternalPlugins = HashMultimap.create();
|
||||
for (Plugin p : pluginManager.getPlugins())
|
||||
{
|
||||
ExternalPluginManifest m = getExternalPluginManifest(p.getClass());
|
||||
if (m != null)
|
||||
{
|
||||
loadedExternalPlugins.put(m, p);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> installedIDs = getInstalledExternalPlugins();
|
||||
if (installedIDs.isEmpty() && loadedExternalPlugins.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boolean startup = SplashScreen.isOpen();
|
||||
try
|
||||
{
|
||||
double splashStart = startup ? .60 : 0;
|
||||
double splashLength = startup ? .10 : 1;
|
||||
if (!startup)
|
||||
{
|
||||
SplashScreen.init();
|
||||
}
|
||||
|
||||
SplashScreen.stage(splashStart, null, "Downloading external plugins");
|
||||
Set<ExternalPluginManifest> externalPlugins = new HashSet<>();
|
||||
|
||||
RuneLite.PLUGINS_DIR.mkdirs();
|
||||
|
||||
List<ExternalPluginManifest> manifestList;
|
||||
try
|
||||
{
|
||||
manifestList = externalPluginClient.downloadManifest();
|
||||
Map<String, ExternalPluginManifest> manifests = manifestList
|
||||
.stream().collect(ImmutableMap.toImmutableMap(ExternalPluginManifest::getInternalName, Function.identity()));
|
||||
|
||||
Set<ExternalPluginManifest> needsDownload = new HashSet<>();
|
||||
Set<File> keep = new HashSet<>();
|
||||
|
||||
for (String name : installedIDs)
|
||||
{
|
||||
ExternalPluginManifest manifest = manifests.get(name);
|
||||
if (manifest != null)
|
||||
{
|
||||
externalPlugins.add(manifest);
|
||||
|
||||
if (!manifest.isValid())
|
||||
{
|
||||
needsDownload.add(manifest);
|
||||
}
|
||||
else
|
||||
{
|
||||
keep.add(manifest.getJarFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete old plugins
|
||||
File[] files = RuneLite.PLUGINS_DIR.listFiles();
|
||||
if (files != null)
|
||||
{
|
||||
for (File fi : files)
|
||||
{
|
||||
if (!keep.contains(fi))
|
||||
{
|
||||
fi.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int toDownload = needsDownload.stream().mapToInt(ExternalPluginManifest::getSize).sum();
|
||||
int downloaded = 0;
|
||||
|
||||
for (ExternalPluginManifest manifest : needsDownload)
|
||||
{
|
||||
HttpUrl url = RuneLiteProperties.getPluginHubBase().newBuilder()
|
||||
.addPathSegment(manifest.getInternalName())
|
||||
.addPathSegment(manifest.getCommit() + ".jar")
|
||||
.build();
|
||||
|
||||
try (Response res = okHttpClient.newCall(new Request.Builder().url(url).build()).execute())
|
||||
{
|
||||
int fdownloaded = downloaded;
|
||||
downloaded += manifest.getSize();
|
||||
HashingInputStream his = new HashingInputStream(Hashing.sha256(),
|
||||
new CountingInputStream(res.body().byteStream(), i ->
|
||||
SplashScreen.stage(splashStart + (splashLength * .2), splashStart + (splashLength * .8),
|
||||
null, "Downloading " + manifest.getDisplayName(),
|
||||
i + fdownloaded, toDownload, true)));
|
||||
Files.asByteSink(manifest.getJarFile()).writeFrom(his);
|
||||
if (!his.hash().toString().equals(manifest.getHash()))
|
||||
{
|
||||
throw new VerificationException("Plugin " + manifest.getInternalName() + " didn't match its hash");
|
||||
}
|
||||
}
|
||||
catch (IOException | VerificationException e)
|
||||
{
|
||||
externalPlugins.remove(manifest);
|
||||
log.error("Unable to download external plugin \"{}\"", manifest.getInternalName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException | VerificationException e)
|
||||
{
|
||||
log.error("Unable to download external plugins", e);
|
||||
return;
|
||||
}
|
||||
|
||||
SplashScreen.stage(splashStart + (splashLength * .8), null, "Starting external plugins");
|
||||
|
||||
// TODO(abex): make sure the plugins get fully removed from the scheduler/eventbus/other managers (iterate and check classloader)
|
||||
Set<ExternalPluginManifest> add = new HashSet<>();
|
||||
for (ExternalPluginManifest ex : externalPlugins)
|
||||
{
|
||||
if (loadedExternalPlugins.removeAll(ex).size() <= 0)
|
||||
{
|
||||
add.add(ex);
|
||||
}
|
||||
}
|
||||
// list of loaded external plugins that aren't in the manifest
|
||||
Collection<Plugin> remove = loadedExternalPlugins.values();
|
||||
|
||||
for (Plugin p : remove)
|
||||
{
|
||||
log.info("Stopping external plugin \"{}\"", p.getClass());
|
||||
try
|
||||
{
|
||||
SwingUtilities.invokeAndWait(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
pluginManager.stopPlugin(p);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (InterruptedException | InvocationTargetException e)
|
||||
{
|
||||
log.warn("Unable to stop external plugin \"{}\"", p.getClass().getName(), e);
|
||||
}
|
||||
pluginManager.remove(p);
|
||||
}
|
||||
|
||||
for (ExternalPluginManifest manifest : add)
|
||||
{
|
||||
// I think this can't happen, but just in case
|
||||
if (!manifest.isValid())
|
||||
{
|
||||
log.warn("Invalid plugin for validated manifest: {}", manifest);
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("Loading external plugin \"{}\" version \"{}\" commit \"{}\"", manifest.getInternalName(), manifest.getVersion(), manifest.getCommit());
|
||||
|
||||
List<Plugin> newPlugins = null;
|
||||
try
|
||||
{
|
||||
ClassLoader cl = new ExternalPluginClassLoader(manifest, new URL[]{manifest.getJarFile().toURI().toURL()});
|
||||
List<Class<?>> clazzes = new ArrayList<>();
|
||||
for (String className : manifest.getPlugins())
|
||||
{
|
||||
clazzes.add(cl.loadClass(className));
|
||||
}
|
||||
|
||||
List<Plugin> newPlugins2 = newPlugins = pluginManager.loadPlugins(clazzes, null);
|
||||
if (!startup)
|
||||
{
|
||||
pluginManager.loadDefaultPluginConfiguration(newPlugins);
|
||||
|
||||
SwingUtilities.invokeAndWait(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
for (Plugin p : newPlugins2)
|
||||
{
|
||||
pluginManager.startPlugin(p);
|
||||
}
|
||||
}
|
||||
catch (PluginInstantiationException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (ThreadDeath e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
log.warn("Unable to start or load external plugin \"{}\"", manifest.getInternalName(), e);
|
||||
if (newPlugins != null)
|
||||
{
|
||||
for (Plugin p : newPlugins)
|
||||
{
|
||||
try
|
||||
{
|
||||
SwingUtilities.invokeAndWait(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
pluginManager.stopPlugin(p);
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (InterruptedException | InvocationTargetException e2)
|
||||
{
|
||||
log.info("Unable to fully stop plugin \"{}\"", manifest.getInternalName(), e2);
|
||||
}
|
||||
pluginManager.remove(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!startup)
|
||||
{
|
||||
eventBus.post(new ExternalPluginsChanged(manifestList));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!startup)
|
||||
{
|
||||
SplashScreen.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getInstalledExternalPlugins()
|
||||
{
|
||||
String externalPluginsStr = configManager.getConfiguration(RuneLiteConfig.GROUP_NAME, PLUGIN_LIST_KEY);
|
||||
return Text.fromCSV(externalPluginsStr == null ? "" : externalPluginsStr);
|
||||
}
|
||||
|
||||
public void install(String key)
|
||||
{
|
||||
Set<String> plugins = new HashSet<>(getInstalledExternalPlugins());
|
||||
if (plugins.add(key))
|
||||
{
|
||||
configManager.setConfiguration(RuneLiteConfig.GROUP_NAME, PLUGIN_LIST_KEY, Text.toCSV(plugins));
|
||||
executor.submit(this::refreshPlugins);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(String key)
|
||||
{
|
||||
Set<String> plugins = new HashSet<>(getInstalledExternalPlugins());
|
||||
if (plugins.remove(key))
|
||||
{
|
||||
configManager.setConfiguration(RuneLiteConfig.GROUP_NAME, PLUGIN_LIST_KEY, Text.toCSV(plugins));
|
||||
executor.submit(this::refreshPlugins);
|
||||
}
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
executor.submit(this::refreshPlugins);
|
||||
}
|
||||
|
||||
public static ExternalPluginManifest getExternalPluginManifest(Class<? extends Plugin> plugin)
|
||||
{
|
||||
ClassLoader cl = plugin.getClassLoader();
|
||||
if (cl instanceof ExternalPluginClassLoader)
|
||||
{
|
||||
ExternalPluginClassLoader ecl = (ExternalPluginClassLoader) cl;
|
||||
return ecl.getManifest();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void loadBuiltin(Class<? extends Plugin>... plugins)
|
||||
{
|
||||
builtinExternals = plugins;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, TheStonedTurtle <http://www.github.com/TheStonedTurtle>
|
||||
* Copyright (c) 2019 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,23 +22,68 @@
|
||||
* (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;
|
||||
package net.runelite.client.externalplugins;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.Files;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.Icon;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.runelite.client.RuneLite;
|
||||
|
||||
/**
|
||||
* Used with ComboBoxListRenderer to render an icon next to the text of the list entry.
|
||||
* Also supports adding a data object to be used for more complex selection logic
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class ComboBoxIconEntry
|
||||
@Data
|
||||
public class ExternalPluginManifest
|
||||
{
|
||||
private Icon icon;
|
||||
private String text;
|
||||
private String internalName;
|
||||
private String commit;
|
||||
private String hash;
|
||||
private int size;
|
||||
private String[] plugins;
|
||||
|
||||
private String displayName;
|
||||
private String version;
|
||||
private String author;
|
||||
@Nullable
|
||||
private Object data;
|
||||
}
|
||||
private String description;
|
||||
@Nullable
|
||||
private String warning;
|
||||
@Nullable
|
||||
private String[] tags;
|
||||
@EqualsAndHashCode.Exclude
|
||||
private URL support;
|
||||
private boolean hasIcon;
|
||||
|
||||
public boolean hasIcon()
|
||||
{
|
||||
return hasIcon;
|
||||
}
|
||||
|
||||
File getJarFile()
|
||||
{
|
||||
return new File(RuneLite.PLUGINS_DIR, internalName + commit + ".jar");
|
||||
}
|
||||
|
||||
boolean isValid()
|
||||
{
|
||||
File file = getJarFile();
|
||||
|
||||
try
|
||||
{
|
||||
if (file.exists())
|
||||
{
|
||||
String hash = Files.asByteSource(file).hash(Hashing.sha256()).toString();
|
||||
if (this.hash.equals(hash))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -28,56 +28,57 @@ package net.runelite.client.game;
|
||||
import lombok.Getter;
|
||||
import static net.runelite.api.NullObjectID.*;
|
||||
import static net.runelite.api.ObjectID.*;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@Getter
|
||||
public enum AgilityShortcut
|
||||
{
|
||||
GENERIC_SHORTCUT(1, "Shortcut", null,
|
||||
// Trollheim
|
||||
ROCKS_3790, ROCKS_3791,
|
||||
// Fremennik Slayer Cave
|
||||
STEPS_29993,
|
||||
// Fossil Island
|
||||
LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM,
|
||||
// Brimhaven dungeon
|
||||
CREVICE_30198,
|
||||
// Lumbridge
|
||||
STILE_12982,
|
||||
// Gu'Tanoth Bridge
|
||||
GAP, GAP_2831,
|
||||
// Lumbridge Swamp Caves
|
||||
STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673,
|
||||
// Morytania Pirate Ship
|
||||
ROCK_16115,
|
||||
// Lumber Yard
|
||||
BROKEN_FENCE_2618,
|
||||
// McGrubor's Wood
|
||||
LOOSE_RAILING,
|
||||
// Underwater Area Fossil Island
|
||||
TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962, PLANT_DOOR_30961,
|
||||
// Tree Gnome Village
|
||||
LOOSE_RAILING_2186,
|
||||
// Burgh de Rott
|
||||
LOW_FENCE,
|
||||
// Taverley
|
||||
STILE,
|
||||
// Asgarnian Ice Dungeon
|
||||
STEPS,
|
||||
// Fossil Island Wyvern Cave
|
||||
STAIRS_31485,
|
||||
// Trollweiss Mountain Cave
|
||||
ROCKY_HANDHOLDS, ROCKY_HANDHOLDS_19847,
|
||||
// Witchaven Dungeon
|
||||
SHORTCUT),
|
||||
// Trollheim
|
||||
ROCKS_3790, ROCKS_3791,
|
||||
// Fremennik Slayer Cave
|
||||
STEPS_29993,
|
||||
// Fossil Island
|
||||
LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM,
|
||||
// Brimhaven dungeon
|
||||
CREVICE_30198,
|
||||
// Lumbridge
|
||||
STILE_12982,
|
||||
// Gu'Tanoth Bridge
|
||||
GAP, GAP_2831,
|
||||
// Lumbridge Swamp Caves
|
||||
STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673,
|
||||
// Morytania Pirate Ship
|
||||
ROCK_16115,
|
||||
// Lumber Yard
|
||||
BROKEN_FENCE_2618,
|
||||
// McGrubor's Wood
|
||||
LOOSE_RAILING,
|
||||
// Underwater Area Fossil Island
|
||||
TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962, PLANT_DOOR_30961,
|
||||
// Tree Gnome Village
|
||||
LOOSE_RAILING_2186,
|
||||
// Burgh de Rott
|
||||
LOW_FENCE,
|
||||
// Taverley
|
||||
STILE,
|
||||
// Asgarnian Ice Dungeon
|
||||
STEPS,
|
||||
// Fossil Island Wyvern Cave
|
||||
STAIRS_31485,
|
||||
// Trollweiss Mountain Cave
|
||||
ROCKY_HANDHOLDS, ROCKY_HANDHOLDS_19847,
|
||||
// Witchaven Dungeon
|
||||
SHORTCUT),
|
||||
BRIMHAVEN_DUNGEON_MEDIUM_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2698, 9491, 0), PIPE_21727),
|
||||
BRIMHAVEN_DUNGEON_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2655, 9573, 0), PIPE_21728),
|
||||
BRIMHAVEN_DUNGEON_STEPPING_STONES_RETURN(1, "Pipe Squeeze", null, STEPPING_STONE_21739),
|
||||
BRIMHAVEN_DUNGEON_LOG_BALANCE_RETURN(1, "Log Balance", null, LOG_BALANCE_20884),
|
||||
AGILITY_PYRAMID_ROCKS_WEST(1, "Rocks", null, CLIMBING_ROCKS_11948),
|
||||
CAIRN_ISLE_CLIMBING_ROCKS(1, "Rocks", null, CLIMBING_ROCKS),
|
||||
KARAMJA_GLIDER_LOG(1, "Log Balance", new WorldPoint(2906, 3050, 0), A_WOODEN_LOG),
|
||||
FALADOR_CRUMBLING_WALL(5, "Crumbling Wall", new WorldPoint(2936, 3357, 0), CRUMBLING_WALL_24222),
|
||||
KARAMJA_GLIDER_LOG(1, "Log Balance", new WorldPoint(2906, 3050, 0), A_WOODEN_LOG ),
|
||||
FALADOR_CRUMBLING_WALL(5, "Crumbling Wall", new WorldPoint(2936, 3357, 0), CRUMBLING_WALL_24222 ),
|
||||
RIVER_LUM_GRAPPLE_WEST(8, "Grapple Broken Raft", new WorldPoint(3245, 3179, 0), BROKEN_RAFT),
|
||||
RIVER_LUM_GRAPPLE_EAST(8, "Grapple Broken Raft", new WorldPoint(3258, 3179, 0), BROKEN_RAFT),
|
||||
CORSAIR_COVE_ROCKS(10, "Rocks", new WorldPoint(2545, 2871, 0), ROCKS_31757),
|
||||
@@ -88,7 +89,7 @@ public enum AgilityShortcut
|
||||
GOBLIN_VILLAGE_WALL(14, "Wall", new WorldPoint(2925, 3523, 0), TIGHTGAP),
|
||||
CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809),
|
||||
EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566),
|
||||
TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15
|
||||
TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15
|
||||
YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, CASTLE_WALL),
|
||||
KOUREND_CATACOMBS_SOUTH_WEST_CREVICE_NORTH(17, "Crevice", new WorldPoint(1647, 10008, 0), CRACK_28892),
|
||||
KOUREND_CATACOMBS_SOUTH_WEST_CREVICE_SOUTH(17, "Crevice", new WorldPoint(1645, 10001, 0), CRACK_28892),
|
||||
@@ -151,7 +152,7 @@ public enum AgilityShortcut
|
||||
ISAFDAR_FOREST_OBSTACLES(56, "Trap", null, DENSE_FOREST_3938, DENSE_FOREST_3939, DENSE_FOREST_3998, DENSE_FOREST_3999, DENSE_FOREST, LEAVES, LEAVES_3924, LEAVES_3925, STICKS, TRIPWIRE, TRIPWIRE_3921),
|
||||
RELEKKA_EAST_FENCE(57, "Fence", new WorldPoint(2688, 3697, 0), BROKEN_FENCE),
|
||||
YANILLE_DUNGEON_MONKEY_BARS(57, "Monkey Bars", null, MONKEYBARS_23567),
|
||||
PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null, WEATHERED_WALL, WEATHERED_WALL_16526),
|
||||
PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null , WEATHERED_WALL, WEATHERED_WALL_16526),
|
||||
ELVEN_OVERPASS_CLIFF_SCRAMBLE(59, "Rocks", new WorldPoint(2345, 3300, 0), ROCKS_16514, ROCKS_16515),
|
||||
ELVEN_OVERPASS_CLIFF_SCRAMBLE_PRIFDDINAS(59, "Rocks", new WorldPoint(3369, 6052, 0), ROCKS_16514, ROCKS_16515),
|
||||
WILDERNESS_GWD_CLIMB_EAST(60, "Rocks", new WorldPoint(2943, 3770, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406),
|
||||
@@ -182,9 +183,17 @@ public enum AgilityShortcut
|
||||
TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON(70, "Pipe Squeeze", new WorldPoint(2886, 9798, 0), OBSTACLE_PIPE_16509),
|
||||
TAVERLEY_DUNGEON_ROCKS_NORTH(70, "Rocks", new WorldPoint(2887, 9823, 0), ROCKS, ROCKS_14106),
|
||||
TAVERLEY_DUNGEON_ROCKS_SOUTH(70, "Rocks", new WorldPoint(2887, 9631, 0), ROCKS, ROCKS_14106),
|
||||
FOSSIL_ISLAND_HARDWOOD_NORTH(70, "Hole", new WorldPoint(3712, 3828, 0), HOLE_31481, HOLE_31482),
|
||||
FOSSIL_ISLAND_HARDWOOD_SOUTH(70, "Hole", new WorldPoint(3714, 3816, 0), HOLE_31481, HOLE_31482),
|
||||
AL_KHARID_WINDOW(70, "Window", new WorldPoint(3293, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW),
|
||||
FOSSIL_ISLAND_HARDWOOD_NORTH(70, "Hole" , new WorldPoint(3712, 3828, 0), HOLE_31481, HOLE_31482),
|
||||
FOSSIL_ISLAND_HARDWOOD_SOUTH(70, "Hole" , new WorldPoint(3714, 3816, 0), HOLE_31481, HOLE_31482),
|
||||
AL_KHARID_WINDOW(70, "Window", new WorldPoint(3295, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW)
|
||||
{
|
||||
@Override
|
||||
public boolean matches(TileObject object)
|
||||
{
|
||||
// there are two BIG_WINDOW objects right next to each other here, but only this one is valid
|
||||
return object.getId() != BIG_WINDOW || object.getWorldLocation().equals(getWorldLocation());
|
||||
}
|
||||
},
|
||||
GWD_SARADOMIN_ROPE_NORTH(70, "Rope Descent", new WorldPoint(2912, 5300, 0), NULL_26371, NULL_26561),
|
||||
GWD_SARADOMIN_ROPE_SOUTH(70, "Rope Descent", new WorldPoint(2951, 5267, 0), NULL_26375, NULL_26562),
|
||||
GU_TANOTH_CRUMBLING_WALL(71, "Rocks", new WorldPoint(2545, 3032, 0), CRUMBLING_WALL_40355, ROCKS_40356),
|
||||
@@ -192,14 +201,14 @@ public enum AgilityShortcut
|
||||
SLAYER_TOWER_ADVANCED_CHAIN_SECOND(71, "Spiked Chain (Floor 3)", new WorldPoint(3446, 3576, 0), SPIKEY_CHAIN_16538),
|
||||
STRONGHOLD_SLAYER_CAVE_TUNNEL(72, "Tunnel", new WorldPoint(2431, 9806, 0), TUNNEL_30174, TUNNEL_30175),
|
||||
TROLL_STRONGHOLD_WALL_CLIMB(73, "Rocks", new WorldPoint(2841, 3694, 0), ROCKS_16464),
|
||||
ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985),
|
||||
ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985 ),
|
||||
LAVA_DRAGON_ISLE_JUMP(74, "Stepping Stone", new WorldPoint(3200, 3807, 0), STEPPING_STONE_14918),
|
||||
FORTHOS_DUNGEON_SPIKED_BLADES(75, "Spiked Blades", new WorldPoint(1819, 9946, 0), STRANGE_FLOOR_34834),
|
||||
REVENANT_CAVES_DEMONS_JUMP(75, "Jump", new WorldPoint(3199, 10135, 0), PILLAR_31561),
|
||||
REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561),
|
||||
REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561),
|
||||
ZUL_ANDRA_ISLAND_CROSSING(76, "Stepping Stone", new WorldPoint(2156, 3073, 0), STEPPING_STONE_10663),
|
||||
SHILO_VILLAGE_STEPPING_STONES(77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466),
|
||||
SHILO_VILLAGE_STEPPING_STONES( 77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466),
|
||||
IORWERTHS_DUNGEON_NORTHERN_SHORTCUT_EAST(78, "Tight Gap", new WorldPoint(3221, 12441, 0), TIGHT_GAP),
|
||||
IORWERTHS_DUNGEON_NORTHERN_SHORTCUT_WEST(78, "Tight Gap", new WorldPoint(3215, 12441, 0), TIGHT_GAP_36693),
|
||||
KHARAZI_JUNGLE_VINE_CLIMB(79, "Vine", new WorldPoint(2897, 2939, 0), NULL_26884, NULL_26886),
|
||||
@@ -265,4 +274,9 @@ public enum AgilityShortcut
|
||||
{
|
||||
return description + " - Level " + level;
|
||||
}
|
||||
|
||||
public boolean matches(TileObject object)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* 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.game;
|
||||
|
||||
import java.awt.Color;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Prayer;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum AttackStyle
|
||||
{
|
||||
MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES),
|
||||
MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE),
|
||||
UNKNOWN("Unknown", Color.WHITE, null);
|
||||
|
||||
private String name;
|
||||
private Color color;
|
||||
private Prayer prayer;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package net.runelite.client.game;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class CombatStats
|
||||
{
|
||||
private int magicAttack;
|
||||
private int magicDefence;
|
||||
private int magicStr;
|
||||
private int meleeAtkCrush;
|
||||
private int meleeAtkSlash;
|
||||
private int meleeAtkStab;
|
||||
private int meleeAttack;
|
||||
private int meleeDefCrush;
|
||||
private int meleeDefence;
|
||||
private int meleeDefSlash;
|
||||
private int meleeDefStab;
|
||||
private int meleeStr;
|
||||
private int rangeAttack;
|
||||
private int rangeDefence;
|
||||
private int rangeStr;
|
||||
private int speed;
|
||||
}
|
||||
@@ -36,18 +36,18 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.FriendsChatManager;
|
||||
import net.runelite.api.FriendsChatMember;
|
||||
import net.runelite.api.FriendsChatManager;
|
||||
import net.runelite.api.FriendsChatRank;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.events.FriendsChatChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Singleton
|
||||
public class FriendChatManager
|
||||
@@ -74,7 +74,7 @@ public class FriendChatManager
|
||||
private final LoadingCache<String, FriendsChatRank> ranksCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(100)
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<>()
|
||||
.build(new CacheLoader<String, FriendsChatRank>()
|
||||
{
|
||||
@Override
|
||||
public FriendsChatRank load(@Nonnull String key)
|
||||
@@ -93,15 +93,10 @@ public class FriendChatManager
|
||||
private int offset;
|
||||
|
||||
@Inject
|
||||
private FriendChatManager(final Client client,
|
||||
final SpriteManager spriteManager,
|
||||
final EventBus eventbus)
|
||||
private FriendChatManager(Client client, SpriteManager spriteManager)
|
||||
{
|
||||
this.client = client;
|
||||
this.spriteManager = spriteManager;
|
||||
|
||||
eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventbus.subscribe(FriendsChatChanged.class, this, this::onFriendsChatChanged);
|
||||
}
|
||||
|
||||
public boolean isMember(String name)
|
||||
@@ -131,14 +126,16 @@ public class FriendChatManager
|
||||
return offset + friendsChatRank.ordinal() - 1;
|
||||
}
|
||||
|
||||
private void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
if (gameStateChanged.getGameState() == GameState.LOGGED_IN && offset == 0)
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN && offset == 0)
|
||||
{
|
||||
loadRankIcons();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onFriendsChatChanged(FriendsChatChanged friendsChatChanged)
|
||||
{
|
||||
ranksCache.invalidateAll();
|
||||
|
||||
@@ -36,7 +36,6 @@ import static net.runelite.client.game.HiscoreManager.NONE;
|
||||
import net.runelite.http.api.hiscore.HiscoreClient;
|
||||
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
||||
import net.runelite.http.api.hiscore.HiscoreResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Slf4j
|
||||
class HiscoreLoader extends CacheLoader<HiscoreManager.HiscoreKey, HiscoreResult>
|
||||
@@ -51,7 +50,7 @@ class HiscoreLoader extends CacheLoader<HiscoreManager.HiscoreKey, HiscoreResult
|
||||
}
|
||||
|
||||
@Override
|
||||
public HiscoreResult load(@NotNull HiscoreManager.HiscoreKey hiscoreKey)
|
||||
public HiscoreResult load(HiscoreManager.HiscoreKey hiscoreKey) throws Exception
|
||||
{
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ 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.rxjava3.schedulers.Schedulers;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -49,19 +49,17 @@ import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import static net.runelite.api.Constants.CLIENT_DEFAULT_ZOOM;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import static net.runelite.api.ItemID.*;
|
||||
import net.runelite.api.Sprite;
|
||||
import net.runelite.api.SpritePixels;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.PostItemDefinition;
|
||||
import net.runelite.api.events.PostItemComposition;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.util.AsyncBufferedImage;
|
||||
import net.runelite.http.api.item.ItemClient;
|
||||
import net.runelite.http.api.item.ItemPrice;
|
||||
import net.runelite.http.api.item.ItemStats;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Singleton
|
||||
@@ -91,7 +89,7 @@ public class ItemManager
|
||||
private Map<Integer, ItemPrice> itemPrices = Collections.emptyMap();
|
||||
private Map<Integer, ItemStats> itemStats = Collections.emptyMap();
|
||||
private final LoadingCache<ImageKey, AsyncBufferedImage> itemImages;
|
||||
private final LoadingCache<Integer, ItemDefinition> itemDefinitions;
|
||||
private final LoadingCache<Integer, ItemComposition> itemCompositions;
|
||||
private final LoadingCache<OutlineKey, BufferedImage> itemOutlines;
|
||||
|
||||
// Worn items with weight reducing property have a different worn and inventory ItemID
|
||||
@@ -164,19 +162,15 @@ public class ItemManager
|
||||
build();
|
||||
|
||||
@Inject
|
||||
public ItemManager(
|
||||
Client client,
|
||||
ScheduledExecutorService executor,
|
||||
ClientThread clientThread,
|
||||
EventBus eventbus,
|
||||
public ItemManager(Client client, ScheduledExecutorService scheduledExecutorService, ClientThread clientThread,
|
||||
OkHttpClient okHttpClient)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
this.itemClient = new ItemClient(okHttpClient);
|
||||
|
||||
executor.scheduleWithFixedDelay(this::loadPrices, 0, 30, TimeUnit.MINUTES);
|
||||
executor.submit(this::loadStats);
|
||||
scheduledExecutorService.scheduleWithFixedDelay(this::loadPrices, 0, 30, TimeUnit.MINUTES);
|
||||
scheduledExecutorService.submit(this::loadStats);
|
||||
|
||||
itemImages = CacheBuilder.newBuilder()
|
||||
.maximumSize(128L)
|
||||
@@ -184,19 +178,19 @@ public class ItemManager
|
||||
.build(new CacheLoader<ImageKey, AsyncBufferedImage>()
|
||||
{
|
||||
@Override
|
||||
public AsyncBufferedImage load(@NotNull ImageKey key)
|
||||
public AsyncBufferedImage load(ImageKey key) throws Exception
|
||||
{
|
||||
return loadImage(key.itemId, key.itemQuantity, key.stackable);
|
||||
}
|
||||
});
|
||||
|
||||
itemDefinitions = CacheBuilder.newBuilder()
|
||||
itemCompositions = CacheBuilder.newBuilder()
|
||||
.maximumSize(1024L)
|
||||
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||
.build(new CacheLoader<Integer, ItemDefinition>()
|
||||
.build(new CacheLoader<Integer, ItemComposition>()
|
||||
{
|
||||
@Override
|
||||
public ItemDefinition load(@NotNull Integer key)
|
||||
public ItemComposition load(Integer key) throws Exception
|
||||
{
|
||||
return client.getItemDefinition(key);
|
||||
}
|
||||
@@ -208,59 +202,77 @@ public class ItemManager
|
||||
.build(new CacheLoader<OutlineKey, BufferedImage>()
|
||||
{
|
||||
@Override
|
||||
public BufferedImage load(@NotNull OutlineKey key)
|
||||
public BufferedImage load(OutlineKey key) throws Exception
|
||||
{
|
||||
return loadItemOutline(key.itemId, key.itemQuantity, key.outlineColor);
|
||||
}
|
||||
});
|
||||
|
||||
eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventbus.subscribe(PostItemDefinition.class, this, this::onPostItemDefinition);
|
||||
}
|
||||
|
||||
private void loadPrices()
|
||||
{
|
||||
itemClient.getPrices()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
m -> itemPrices = m,
|
||||
e -> log.warn("Error loading prices", e),
|
||||
() -> log.debug("Loaded {} prices", itemPrices.size())
|
||||
);
|
||||
try
|
||||
{
|
||||
ItemPrice[] prices = itemClient.getPrices();
|
||||
if (prices != null)
|
||||
{
|
||||
ImmutableMap.Builder<Integer, ItemPrice> map = ImmutableMap.builderWithExpectedSize(prices.length);
|
||||
for (ItemPrice price : prices)
|
||||
{
|
||||
map.put(price.getId(), price);
|
||||
}
|
||||
itemPrices = map.build();
|
||||
}
|
||||
|
||||
log.debug("Loaded {} prices", itemPrices.size());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("error loading prices!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadStats()
|
||||
{
|
||||
itemClient.getStats()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
m -> itemStats = m,
|
||||
e -> log.warn("Error fetching stats", e),
|
||||
() -> log.debug("Loaded {} stats", itemStats.size())
|
||||
);
|
||||
}
|
||||
|
||||
private void onGameStateChanged(final GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.HOPPING || event.getGameState() == GameState.LOGIN_SCREEN)
|
||||
try
|
||||
{
|
||||
itemDefinitions.invalidateAll();
|
||||
final Map<Integer, ItemStats> stats = itemClient.getStats();
|
||||
if (stats != null)
|
||||
{
|
||||
itemStats = ImmutableMap.copyOf(stats);
|
||||
}
|
||||
|
||||
log.debug("Loaded {} stats", itemStats.size());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("error loading stats!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void onPostItemDefinition(PostItemDefinition event)
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(final GameStateChanged event)
|
||||
{
|
||||
itemDefinitions.put(event.getItemDefinition().getId(), event.getItemDefinition());
|
||||
if (event.getGameState() == GameState.HOPPING || event.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
itemCompositions.invalidateAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPostItemComposition(PostItemComposition event)
|
||||
{
|
||||
itemCompositions.put(event.getItemComposition().getId(), event.getItemComposition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates internal item manager item composition cache (but not client item composition cache)
|
||||
*
|
||||
* @see Client#getItemDefinitionCache()
|
||||
* @see Client#getItemCompositionCache()
|
||||
*/
|
||||
public void invalidateItemDefinitionCache()
|
||||
public void invalidateItemCompositionCache()
|
||||
{
|
||||
itemDefinitions.invalidateAll();
|
||||
itemCompositions.invalidateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,7 +292,7 @@ public class ItemManager
|
||||
* @param itemID item id
|
||||
* @param ignoreUntradeableMap should the price returned ignore items that are not tradeable for coins in regular way
|
||||
* @return item price
|
||||
* */
|
||||
*/
|
||||
public int getItemPrice(int itemID, boolean ignoreUntradeableMap)
|
||||
{
|
||||
if (itemID == COINS_995)
|
||||
@@ -292,10 +304,10 @@ public class ItemManager
|
||||
return 1000;
|
||||
}
|
||||
|
||||
ItemDefinition itemDefinition = getItemDefinition(itemID);
|
||||
if (itemDefinition.getNote() != -1)
|
||||
ItemComposition itemComposition = getItemComposition(itemID);
|
||||
if (itemComposition.getNote() != -1)
|
||||
{
|
||||
itemID = itemDefinition.getLinkedNoteId();
|
||||
itemID = itemComposition.getLinkedNoteId();
|
||||
}
|
||||
itemID = WORN_ITEMS.getOrDefault(itemID, itemID);
|
||||
|
||||
@@ -328,67 +340,17 @@ public class ItemManager
|
||||
return price;
|
||||
}
|
||||
|
||||
public int getAlchValue(ItemDefinition composition)
|
||||
{
|
||||
if (composition.getId() == ItemID.COINS_995)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (composition.getId() == ItemID.PLATINUM_TOKEN)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return Math.max(1, composition.getHaPrice());
|
||||
}
|
||||
|
||||
public int getAlchValue(int itemID)
|
||||
{
|
||||
if (itemID == ItemID.COINS_995)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (itemID == ItemID.PLATINUM_TOKEN)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return Math.max(1, getItemDefinition(itemID).getHaPrice());
|
||||
}
|
||||
|
||||
public int getRepairValue(int itemId)
|
||||
{
|
||||
return getRepairValue(itemId, false);
|
||||
}
|
||||
|
||||
private int getRepairValue(int itemId, boolean fullValue)
|
||||
{
|
||||
final ItemReclaimCost b = ItemReclaimCost.of(itemId);
|
||||
|
||||
if (b != null)
|
||||
{
|
||||
if (fullValue || b.getItemID() == GRANITE_MAUL_24225 || b.getItemID() == GRANITE_MAUL_24227)
|
||||
{
|
||||
return b.getValue();
|
||||
}
|
||||
return (int) (b.getValue() * (75.0f / 100.0f));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an item's stats
|
||||
*
|
||||
* @param itemId item id
|
||||
* @return item stats
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStats getItemStats(int itemId, boolean allowNote)
|
||||
{
|
||||
ItemDefinition itemDefinition = getItemDefinition(itemId);
|
||||
ItemComposition itemComposition = getItemComposition(itemId);
|
||||
|
||||
if (!allowNote && itemDefinition.getNote() != -1)
|
||||
if (itemComposition == null || itemComposition.getName() == null || (!allowNote && itemComposition.getNote() != -1))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -425,10 +387,10 @@ public class ItemManager
|
||||
* @return item composition
|
||||
*/
|
||||
@Nonnull
|
||||
public ItemDefinition getItemDefinition(int itemId)
|
||||
public ItemComposition getItemComposition(int itemId)
|
||||
{
|
||||
assert client.isClientThread() : "getItemDefinition must be called on client thread";
|
||||
return itemDefinitions.getUnchecked(itemId);
|
||||
assert client.isClientThread() : "getItemComposition must be called on client thread";
|
||||
return itemCompositions.getUnchecked(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,16 +398,16 @@ public class ItemManager
|
||||
*/
|
||||
public int canonicalize(int itemID)
|
||||
{
|
||||
ItemDefinition itemDefinition = getItemDefinition(itemID);
|
||||
ItemComposition itemComposition = getItemComposition(itemID);
|
||||
|
||||
if (itemDefinition.getNote() != -1)
|
||||
if (itemComposition.getNote() != -1)
|
||||
{
|
||||
return itemDefinition.getLinkedNoteId();
|
||||
return itemComposition.getLinkedNoteId();
|
||||
}
|
||||
|
||||
if (itemDefinition.getPlaceholderTemplateId() != -1)
|
||||
if (itemComposition.getPlaceholderTemplateId() != -1)
|
||||
{
|
||||
return itemDefinition.getPlaceholderId();
|
||||
return itemComposition.getPlaceholderId();
|
||||
}
|
||||
|
||||
return WORN_ITEMS.getOrDefault(itemID, itemID);
|
||||
@@ -466,7 +428,7 @@ public class ItemManager
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Sprite sprite = client.createItemSprite(itemId, quantity, 1, Sprite.DEFAULT_SHADOW_COLOR,
|
||||
SpritePixels sprite = client.createItemSprite(itemId, quantity, 1, SpritePixels.DEFAULT_SHADOW_COLOR,
|
||||
stackable ? 1 : 0, false, CLIENT_DEFAULT_ZOOM);
|
||||
if (sprite == null)
|
||||
{
|
||||
@@ -520,21 +482,21 @@ public class ItemManager
|
||||
/**
|
||||
* Create item sprite and applies an outline.
|
||||
*
|
||||
* @param itemId item id
|
||||
* @param itemId item id
|
||||
* @param itemQuantity item quantity
|
||||
* @param outlineColor outline color
|
||||
* @return image
|
||||
*/
|
||||
private BufferedImage loadItemOutline(final int itemId, final int itemQuantity, final Color outlineColor)
|
||||
{
|
||||
final Sprite itemSprite = client.createItemSprite(itemId, itemQuantity, 1, 0, 0, false, CLIENT_DEFAULT_ZOOM);
|
||||
final SpritePixels itemSprite = client.createItemSprite(itemId, itemQuantity, 1, 0, 0, false, CLIENT_DEFAULT_ZOOM);
|
||||
return itemSprite.toBufferedOutline(outlineColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item outline with a specific color.
|
||||
*
|
||||
* @param itemId item id
|
||||
* @param itemId item id
|
||||
* @param itemQuantity item quantity
|
||||
* @param outlineColor outline color
|
||||
* @return image
|
||||
|
||||
@@ -352,9 +352,4 @@ public enum ItemMapping
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public static boolean isMapped(int itemId)
|
||||
{
|
||||
return MAPPINGS.containsValue(itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* 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.game;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ItemID;
|
||||
|
||||
/**
|
||||
* Some non tradeable items are kept on death inside low level wilderness (1-20) but are turned into a broken variant.
|
||||
* <p>
|
||||
* The non-broken variant will be shown inside the interface.
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum ItemReclaimCost
|
||||
{
|
||||
// Capes
|
||||
FIRE_CAPE(ItemID.FIRE_CAPE, 50000),
|
||||
FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE, 99000),
|
||||
INFERNAL_CAPE(ItemID.INFERNAL_CAPE, 50000),
|
||||
INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE, 99000),
|
||||
AVAS_ASSEMBLER(ItemID.AVAS_ASSEMBLER, 75000),
|
||||
ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE, 99000),
|
||||
IMBUED_GUTHIX_CAPE(ItemID.IMBUED_GUTHIX_CAPE, 75000),
|
||||
IMBUED_GUTHIX_MAX_CAPE(ItemID.GUTHIX_MAX_CAPE, 99000),
|
||||
IMBUED_SARADOMIN_CAPE(ItemID.IMBUED_SARADOMIN_CAPE, 75000),
|
||||
IMBUED_SARADOMIN_MAX_CAPE(ItemID.SARADOMIN_MAX_CAPE, 99000),
|
||||
IMBUED_ZAMORAK_CAPE(ItemID.IMBUED_ZAMORAK_CAPE, 75000),
|
||||
IMBUED_ZAMORAK_MAX_CAPE(ItemID.ZAMORAK_MAX_CAPE, 99000),
|
||||
|
||||
// Defenders
|
||||
BRONZE_DEFENDER(ItemID.BRONZE_DEFENDER, 1000),
|
||||
IRON_DEFENDER(ItemID.IRON_DEFENDER, 2000),
|
||||
STEEL_DEFENDER(ItemID.STEEL_DEFENDER, 2500),
|
||||
BLACK_DEFENDER(ItemID.BLACK_DEFENDER, 5000),
|
||||
MITHRIL_DEFENDER(ItemID.MITHRIL_DEFENDER, 15000),
|
||||
ADAMANT_DEFENDER(ItemID.ADAMANT_DEFENDER, 25000),
|
||||
RUNE_DEFENDER(ItemID.RUNE_DEFENDER, 35000),
|
||||
DRAGON_DEFENDER(ItemID.DRAGON_DEFENDER, 40000),
|
||||
AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER, 1000000),
|
||||
|
||||
// Void
|
||||
VOID_MAGE_HELM(ItemID.VOID_MAGE_HELM, 40000),
|
||||
VOID_RANGER_HELM(ItemID.VOID_RANGER_HELM, 40000),
|
||||
VOID_MELEE_HELM(ItemID.VOID_MELEE_HELM, 40000),
|
||||
VOID_KNIGHT_TOP(ItemID.VOID_KNIGHT_TOP, 45000),
|
||||
VOID_KNIGHT_ROBE(ItemID.VOID_KNIGHT_ROBE, 45000),
|
||||
VOID_KNIGHT_GLOVES(ItemID.VOID_KNIGHT_GLOVES, 30000),
|
||||
ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP, 50000),
|
||||
ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE, 50000),
|
||||
|
||||
// Barb Assault
|
||||
FIGHTER_HAT(ItemID.FIGHTER_HAT, 45000),
|
||||
RANGER_HAT(ItemID.RANGER_HAT, 45000),
|
||||
HEALER_HAT(ItemID.HEALER_HAT, 45000),
|
||||
FIGHTER_TORSO(ItemID.FIGHTER_TORSO, 50000),
|
||||
PENANCE_SKIRT(ItemID.PENANCE_SKIRT, 20000),
|
||||
|
||||
// Castle Wars
|
||||
SARADOMIN_HALO(ItemID.SARADOMIN_HALO, 25000),
|
||||
ZAMORAK_HALO(ItemID.ZAMORAK_HALO, 25000),
|
||||
GUTHIX_HALO(ItemID.GUTHIX_HALO, 25000),
|
||||
DECORATIVE_MAGIC_HAT(ItemID.DECORATIVE_ARMOUR_11898, 5000),
|
||||
DECORATIVE_MAGIC_ROBE_TOP(ItemID.DECORATIVE_ARMOUR_11896, 5000),
|
||||
DECORATIVE_MAGIC_ROBE_LEGS(ItemID.DECORATIVE_ARMOUR_11897, 5000),
|
||||
DECORATIVE_RANGE_TOP(ItemID.DECORATIVE_ARMOUR_11899, 5000),
|
||||
DECORATIVE_RANGE_BOTTOM(ItemID.DECORATIVE_ARMOUR_11900, 5000),
|
||||
DECORATIVE_RANGE_QUIVER(ItemID.DECORATIVE_ARMOUR_11901, 5000),
|
||||
GOLD_DECORATIVE_HELM(ItemID.DECORATIVE_HELM_4511, 5000),
|
||||
GOLD_DECORATIVE_BODY(ItemID.DECORATIVE_ARMOUR_4509, 5000),
|
||||
GOLD_DECORATIVE_LEGS(ItemID.DECORATIVE_ARMOUR_4510, 5000),
|
||||
GOLD_DECORATIVE_SKIRT(ItemID.DECORATIVE_ARMOUR_11895, 5000),
|
||||
GOLD_DECORATIVE_SHIELD(ItemID.DECORATIVE_SHIELD_4512, 5000),
|
||||
GOLD_DECORATIVE_SWORD(ItemID.DECORATIVE_SWORD_4508, 5000),
|
||||
|
||||
// Granite Maul
|
||||
GRANITE_MAUL(ItemID.GRANITE_MAUL_24225, 375000),
|
||||
GRANITE_MAUL_OR(ItemID.GRANITE_MAUL_24227, 375000);
|
||||
|
||||
private static final ImmutableMap<Integer, ItemReclaimCost> idMap;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Integer, ItemReclaimCost> builder = ImmutableMap.builder();
|
||||
|
||||
for (ItemReclaimCost items : values())
|
||||
{
|
||||
builder.put(items.itemID, items);
|
||||
}
|
||||
|
||||
idMap = builder.build();
|
||||
}
|
||||
|
||||
private final int itemID;
|
||||
private final int value;
|
||||
|
||||
@Nullable
|
||||
public static ItemReclaimCost of(int itemId)
|
||||
{
|
||||
return idMap.get(itemId);
|
||||
}
|
||||
|
||||
public static boolean breaksOnDeath(int itemId)
|
||||
{
|
||||
return idMap.containsKey(itemId);
|
||||
}
|
||||
}
|
||||
@@ -98,9 +98,4 @@ public class ItemVariationMapping
|
||||
{
|
||||
return INVERTED_MAPPINGS.asMap().getOrDefault(itemId, Collections.singletonList(itemId));
|
||||
}
|
||||
|
||||
static int getSize()
|
||||
{
|
||||
return MAPPINGS.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,449 +1,428 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.TileItem;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemQuantityChanged;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.PlayerDespawned;
|
||||
import net.runelite.api.events.NpcDefinitionChanged;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.events.NpcLootReceived;
|
||||
import net.runelite.client.events.PlayerLootReceived;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class LootManager
|
||||
{
|
||||
private static final Map<Integer, Integer> NPC_DEATH_ANIMATIONS = ImmutableMap.<Integer, Integer>builder()
|
||||
.put(NpcID.CAVE_KRAKEN, AnimationID.CAVE_KRAKEN_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_BAT, AnimationID.CRYSTALLINE_BAT_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_RAT, AnimationID.CRYSTALLINE_RAT_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_SPIDER, AnimationID.CRYSTALLINE_SPIDER_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_WOLF, AnimationID.CRYSTALLINE_WOLF_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_UNICORN, AnimationID.CRYSTALLINE_UNICORN_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_SCORPION, AnimationID.CORRUPTED_SCORPION_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_DRAGON, AnimationID.CRYSTALLINE_DRAGON_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_DARK_BEAST, AnimationID.CRYSTALLINE_DARK_BEAST_DEATH)
|
||||
.put(NpcID.CRYSTALLINE_BEAR, AnimationID.CRYSTALLINE_BEAR_DEATH)
|
||||
.put(NpcID.CORRUPTED_BAT, AnimationID.CRYSTALLINE_BAT_DEATH)
|
||||
.put(NpcID.CORRUPTED_RAT, AnimationID.CRYSTALLINE_RAT_DEATH)
|
||||
.put(NpcID.CORRUPTED_SPIDER, AnimationID.CRYSTALLINE_SPIDER_DEATH)
|
||||
.put(NpcID.CORRUPTED_WOLF, AnimationID.CRYSTALLINE_WOLF_DEATH)
|
||||
.put(NpcID.CORRUPTED_UNICORN, AnimationID.CRYSTALLINE_UNICORN_DEATH)
|
||||
.put(NpcID.CORRUPTED_SCORPION, AnimationID.CORRUPTED_SCORPION_DEATH)
|
||||
.put(NpcID.CORRUPTED_DRAGON, AnimationID.CRYSTALLINE_DRAGON_DEATH)
|
||||
.put(NpcID.CORRUPTED_DARK_BEAST, AnimationID.CRYSTALLINE_DARK_BEAST_DEATH)
|
||||
.put(NpcID.CORRUPTED_BEAR, AnimationID.CRYSTALLINE_BEAR_DEATH)
|
||||
.put(NpcID.THE_NIGHTMARE_9433, AnimationID.NIGHTMARE_DEATH)
|
||||
.build();
|
||||
|
||||
private final EventBus eventBus;
|
||||
private final Client client;
|
||||
private final ListMultimap<Integer, ItemStack> itemSpawns = ArrayListMultimap.create();
|
||||
private final Set<LocalPoint> killPoints = new HashSet<>();
|
||||
private WorldPoint playerLocationLastTick;
|
||||
private WorldPoint krakenPlayerLocation;
|
||||
|
||||
private NPC delayedLootNpc;
|
||||
private int delayedLootTickLimit;
|
||||
|
||||
@Inject
|
||||
private LootManager(
|
||||
final EventBus eventBus,
|
||||
final Client client
|
||||
)
|
||||
{
|
||||
this.eventBus = eventBus;
|
||||
this.client = client;
|
||||
|
||||
eventBus.subscribe(GameTick.class, this, this::onGameTick);
|
||||
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
|
||||
eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned);
|
||||
eventBus.subscribe(ItemSpawned.class, this, this::onItemSpawned);
|
||||
eventBus.subscribe(ItemDespawned.class, this, this::onItemDespawned);
|
||||
eventBus.subscribe(ItemQuantityChanged.class, this, this::onItemQuantityChanged);
|
||||
eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged);
|
||||
eventBus.subscribe(NpcDefinitionChanged.class, this, this::onNpcDefinitionChanged);
|
||||
}
|
||||
|
||||
private void onNpcDespawned(NpcDespawned npcDespawned)
|
||||
{
|
||||
final NPC npc = npcDespawned.getNpc();
|
||||
|
||||
if (npc == delayedLootNpc)
|
||||
{
|
||||
delayedLootNpc = null;
|
||||
delayedLootTickLimit = 0;
|
||||
}
|
||||
|
||||
if (!npc.isDead())
|
||||
{
|
||||
int id = npc.getId();
|
||||
switch (id)
|
||||
{
|
||||
case NpcID.GARGOYLE:
|
||||
case NpcID.GARGOYLE_413:
|
||||
case NpcID.GARGOYLE_1543:
|
||||
case NpcID.MARBLE_GARGOYLE:
|
||||
case NpcID.MARBLE_GARGOYLE_7408:
|
||||
case NpcID.DUSK_7888:
|
||||
case NpcID.DUSK_7889:
|
||||
|
||||
case NpcID.ROCKSLUG:
|
||||
case NpcID.ROCKSLUG_422:
|
||||
case NpcID.GIANT_ROCKSLUG:
|
||||
|
||||
case NpcID.SMALL_LIZARD:
|
||||
case NpcID.SMALL_LIZARD_463:
|
||||
case NpcID.DESERT_LIZARD:
|
||||
case NpcID.DESERT_LIZARD_460:
|
||||
case NpcID.DESERT_LIZARD_461:
|
||||
case NpcID.LIZARD:
|
||||
|
||||
case NpcID.ZYGOMITE:
|
||||
case NpcID.ZYGOMITE_1024:
|
||||
case NpcID.ANCIENT_ZYGOMITE:
|
||||
|
||||
// these monsters die with >0 hp, so we just look for coincident
|
||||
// item spawn with despawn
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
processNpcLoot(npc);
|
||||
}
|
||||
|
||||
private void onPlayerDespawned(PlayerDespawned playerDespawned)
|
||||
{
|
||||
final Player player = playerDespawned.getPlayer();
|
||||
// Only care about dead Players
|
||||
if (player.getHealthRatio() != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final LocalPoint location = LocalPoint.fromWorld(client, player.getWorldLocation());
|
||||
if (location == null || killPoints.contains(location))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int x = location.getSceneX();
|
||||
final int y = location.getSceneY();
|
||||
final int packed = x << 8 | y;
|
||||
final Collection<ItemStack> items = itemSpawns.get(packed);
|
||||
|
||||
if (items.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
killPoints.add(location);
|
||||
eventBus.post(PlayerLootReceived.class, new PlayerLootReceived(player, items));
|
||||
}
|
||||
|
||||
private void onItemSpawned(ItemSpawned itemSpawned)
|
||||
{
|
||||
final TileItem item = itemSpawned.getItem();
|
||||
final Tile tile = itemSpawned.getTile();
|
||||
final LocalPoint location = tile.getLocalLocation();
|
||||
final int packed = location.getSceneX() << 8 | location.getSceneY();
|
||||
itemSpawns.put(packed, new ItemStack(item.getId(), item.getQuantity(), location));
|
||||
log.debug("Item spawn {} ({}) location {}", item.getId(), item.getQuantity(), location);
|
||||
}
|
||||
|
||||
private void onItemDespawned(ItemDespawned itemDespawned)
|
||||
{
|
||||
final TileItem item = itemDespawned.getItem();
|
||||
final LocalPoint location = itemDespawned.getTile().getLocalLocation();
|
||||
log.debug("Item despawn {} ({}) location {}", item.getId(), item.getQuantity(), location);
|
||||
}
|
||||
|
||||
private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged)
|
||||
{
|
||||
final TileItem item = itemQuantityChanged.getItem();
|
||||
final Tile tile = itemQuantityChanged.getTile();
|
||||
final LocalPoint location = tile.getLocalLocation();
|
||||
final int packed = location.getSceneX() << 8 | location.getSceneY();
|
||||
final int diff = itemQuantityChanged.getNewQuantity() - itemQuantityChanged.getOldQuantity();
|
||||
|
||||
if (diff <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
itemSpawns.put(packed, new ItemStack(item.getId(), diff, location));
|
||||
}
|
||||
|
||||
private void onAnimationChanged(AnimationChanged e)
|
||||
{
|
||||
if (!(e.getActor() instanceof NPC))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NPC npc = (NPC) e.getActor();
|
||||
int id = npc.getId();
|
||||
|
||||
// We only care about certain NPCs
|
||||
final Integer deathAnim = NPC_DEATH_ANIMATIONS.get(id);
|
||||
|
||||
// Current animation is death animation?
|
||||
if (deathAnim != null && deathAnim == npc.getAnimation())
|
||||
{
|
||||
if (id == NpcID.CAVE_KRAKEN)
|
||||
{
|
||||
// Big Kraken drops loot wherever player is standing when animation starts.
|
||||
krakenPlayerLocation = client.getLocalPlayer().getWorldLocation();
|
||||
}
|
||||
else
|
||||
{
|
||||
// These NPCs drop loot on death animation, which is right now.
|
||||
processNpcLoot(npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onNpcDefinitionChanged(NpcDefinitionChanged npcChanged)
|
||||
{
|
||||
final NPC npc = npcChanged.getNpc();
|
||||
if (npc.getId() == NpcID.THE_NIGHTMARE_9433)
|
||||
{
|
||||
delayedLootNpc = npc;
|
||||
delayedLootTickLimit = 15;
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameTick(GameTick gameTick)
|
||||
{
|
||||
if (delayedLootNpc != null && delayedLootTickLimit-- > 0)
|
||||
{
|
||||
processDelayedLoot();
|
||||
}
|
||||
|
||||
playerLocationLastTick = client.getLocalPlayer().getWorldLocation();
|
||||
itemSpawns.clear();
|
||||
killPoints.clear();
|
||||
}
|
||||
|
||||
private void processDelayedLoot()
|
||||
{
|
||||
final WorldPoint adjacentLootTile = getAdjacentSquareLootTile(delayedLootNpc);
|
||||
final LocalPoint localPoint = LocalPoint.fromWorld(client, adjacentLootTile);
|
||||
|
||||
if (localPoint == null)
|
||||
{
|
||||
log.debug("Scene changed away from delayed loot location");
|
||||
delayedLootNpc = null;
|
||||
delayedLootTickLimit = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
final int sceneX = localPoint.getSceneX();
|
||||
final int sceneY = localPoint.getSceneY();
|
||||
final int packed = sceneX << 8 | sceneY;
|
||||
final List<ItemStack> itemStacks = itemSpawns.get(packed);
|
||||
if (itemStacks.isEmpty())
|
||||
{
|
||||
// no loot yet
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Got delayed loot stack from {}: {}", delayedLootNpc.getName(), itemStacks);
|
||||
eventBus.post(NpcLootReceived.class, new NpcLootReceived(delayedLootNpc, itemStacks));
|
||||
|
||||
delayedLootNpc = null;
|
||||
delayedLootTickLimit = 0;
|
||||
}
|
||||
|
||||
private void processNpcLoot(NPC npc)
|
||||
{
|
||||
final LocalPoint location = LocalPoint.fromWorld(client, getDropLocation(npc, npc.getWorldLocation()));
|
||||
if (location == null || killPoints.contains(location))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int x = location.getSceneX();
|
||||
final int y = location.getSceneY();
|
||||
final int size = npc.getDefinition().getSize();
|
||||
|
||||
// Some NPCs drop items onto multiple tiles
|
||||
final List<ItemStack> allItems = new ArrayList<>();
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
for (int j = 0; j < size; ++j)
|
||||
{
|
||||
final int packed = (x + i) << 8 | (y + j);
|
||||
final Collection<ItemStack> items = itemSpawns.get(packed);
|
||||
allItems.addAll(items);
|
||||
}
|
||||
}
|
||||
|
||||
if (allItems.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
killPoints.add(location);
|
||||
eventBus.post(NpcLootReceived.class, new NpcLootReceived(npc, allItems));
|
||||
}
|
||||
|
||||
private WorldPoint getDropLocation(NPC npc, WorldPoint worldLocation)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.KRAKEN:
|
||||
case NpcID.KRAKEN_6640:
|
||||
case NpcID.KRAKEN_6656:
|
||||
worldLocation = playerLocationLastTick;
|
||||
break;
|
||||
case NpcID.CAVE_KRAKEN:
|
||||
worldLocation = krakenPlayerLocation;
|
||||
break;
|
||||
case NpcID.ZULRAH: // Green
|
||||
case NpcID.ZULRAH_2043: // Red
|
||||
case NpcID.ZULRAH_2044: // Blue
|
||||
for (Map.Entry<Integer, ItemStack> entry : itemSpawns.entries())
|
||||
{
|
||||
if (entry.getValue().getId() == ItemID.ZULRAHS_SCALES)
|
||||
{
|
||||
int packed = entry.getKey();
|
||||
int unpackedX = packed >> 8;
|
||||
int unpackedY = packed & 0xFF;
|
||||
worldLocation = WorldPoint.fromScene(client, unpackedX, unpackedY, worldLocation.getPlane());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NpcID.VORKATH:
|
||||
case NpcID.VORKATH_8058:
|
||||
case NpcID.VORKATH_8059:
|
||||
case NpcID.VORKATH_8060:
|
||||
case NpcID.VORKATH_8061:
|
||||
int x = worldLocation.getX() + 3;
|
||||
int y = worldLocation.getY() + 3;
|
||||
if (playerLocationLastTick.getX() < x)
|
||||
{
|
||||
x -= 4;
|
||||
}
|
||||
else if (playerLocationLastTick.getX() > x)
|
||||
{
|
||||
x += 4;
|
||||
}
|
||||
if (playerLocationLastTick.getY() < y)
|
||||
{
|
||||
y -= 4;
|
||||
}
|
||||
else if (playerLocationLastTick.getY() > y)
|
||||
{
|
||||
y += 4;
|
||||
}
|
||||
worldLocation = new WorldPoint(x, y, worldLocation.getPlane());
|
||||
break;
|
||||
}
|
||||
|
||||
return worldLocation;
|
||||
}
|
||||
|
||||
private WorldPoint getAdjacentSquareLootTile(NPC npc)
|
||||
{
|
||||
final NPCDefinition composition = npc.getDefinition();
|
||||
final WorldPoint worldLocation = npc.getWorldLocation();
|
||||
int x = worldLocation.getX();
|
||||
int y = worldLocation.getY();
|
||||
|
||||
if (playerLocationLastTick.getX() < x)
|
||||
{
|
||||
x -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += Math.min(playerLocationLastTick.getX() - x, composition.getSize());
|
||||
}
|
||||
|
||||
if (playerLocationLastTick.getY() < y)
|
||||
{
|
||||
y -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y += Math.min(playerLocationLastTick.getY() - y, composition.getSize());
|
||||
}
|
||||
|
||||
return new WorldPoint(x, y, worldLocation.getPlane());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of items present at the provided WorldPoint that spawned this tick.
|
||||
*
|
||||
* @param worldPoint the location in question
|
||||
* @return the list of item stacks
|
||||
*/
|
||||
public Collection<ItemStack> getItemSpawns(WorldPoint worldPoint)
|
||||
{
|
||||
LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||
if (localPoint == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final int sceneX = localPoint.getSceneX();
|
||||
final int sceneY = localPoint.getSceneY();
|
||||
final int packed = sceneX << 8 | sceneY;
|
||||
final List<ItemStack> itemStacks = itemSpawns.get(packed);
|
||||
return Collections.unmodifiableList(itemStacks);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.TileItem;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemQuantityChanged;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.NpcChanged;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.PlayerDespawned;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.NpcLootReceived;
|
||||
import net.runelite.client.events.PlayerLootReceived;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class LootManager
|
||||
{
|
||||
private static final Map<Integer, Integer> NPC_DEATH_ANIMATIONS = ImmutableMap.of(
|
||||
NpcID.CAVE_KRAKEN, AnimationID.CAVE_KRAKEN_DEATH
|
||||
);
|
||||
|
||||
private final EventBus eventBus;
|
||||
private final Client client;
|
||||
private final ListMultimap<Integer, ItemStack> itemSpawns = ArrayListMultimap.create();
|
||||
private final Set<LocalPoint> killPoints = new HashSet<>();
|
||||
private WorldPoint playerLocationLastTick;
|
||||
private WorldPoint krakenPlayerLocation;
|
||||
|
||||
private NPC delayedLootNpc;
|
||||
private int delayedLootTickLimit;
|
||||
|
||||
@Inject
|
||||
private LootManager(EventBus eventBus, Client client)
|
||||
{
|
||||
this.eventBus = eventBus;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned npcDespawned)
|
||||
{
|
||||
final NPC npc = npcDespawned.getNpc();
|
||||
|
||||
if (npc == delayedLootNpc)
|
||||
{
|
||||
delayedLootNpc = null;
|
||||
delayedLootTickLimit = 0;
|
||||
}
|
||||
|
||||
if (!npc.isDead())
|
||||
{
|
||||
int id = npc.getId();
|
||||
switch (id)
|
||||
{
|
||||
case NpcID.GARGOYLE:
|
||||
case NpcID.GARGOYLE_413:
|
||||
case NpcID.GARGOYLE_1543:
|
||||
case NpcID.MARBLE_GARGOYLE:
|
||||
case NpcID.MARBLE_GARGOYLE_7408:
|
||||
case NpcID.DUSK_7888:
|
||||
case NpcID.DUSK_7889:
|
||||
|
||||
case NpcID.ROCKSLUG:
|
||||
case NpcID.ROCKSLUG_422:
|
||||
case NpcID.GIANT_ROCKSLUG:
|
||||
|
||||
case NpcID.SMALL_LIZARD:
|
||||
case NpcID.SMALL_LIZARD_463:
|
||||
case NpcID.DESERT_LIZARD:
|
||||
case NpcID.DESERT_LIZARD_460:
|
||||
case NpcID.DESERT_LIZARD_461:
|
||||
case NpcID.LIZARD:
|
||||
|
||||
case NpcID.ZYGOMITE:
|
||||
case NpcID.ZYGOMITE_1024:
|
||||
case NpcID.ANCIENT_ZYGOMITE:
|
||||
|
||||
// these monsters die with >0 hp, so we just look for coincident
|
||||
// item spawn with despawn
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
processNpcLoot(npc);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPlayerDespawned(PlayerDespawned playerDespawned)
|
||||
{
|
||||
final Player player = playerDespawned.getPlayer();
|
||||
// Only care about dead Players
|
||||
if (player.getHealthRatio() != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final LocalPoint location = LocalPoint.fromWorld(client, player.getWorldLocation());
|
||||
if (location == null || killPoints.contains(location))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int x = location.getSceneX();
|
||||
final int y = location.getSceneY();
|
||||
final int packed = x << 8 | y;
|
||||
final Collection<ItemStack> items = itemSpawns.get(packed);
|
||||
|
||||
if (items.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
killPoints.add(location);
|
||||
eventBus.post(new PlayerLootReceived(player, items));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemSpawned(ItemSpawned itemSpawned)
|
||||
{
|
||||
final TileItem item = itemSpawned.getItem();
|
||||
final Tile tile = itemSpawned.getTile();
|
||||
final LocalPoint location = tile.getLocalLocation();
|
||||
final int packed = location.getSceneX() << 8 | location.getSceneY();
|
||||
itemSpawns.put(packed, new ItemStack(item.getId(), item.getQuantity(), location));
|
||||
log.debug("Item spawn {} ({}) location {}", item.getId(), item.getQuantity(), location);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemDespawned(ItemDespawned itemDespawned)
|
||||
{
|
||||
final TileItem item = itemDespawned.getItem();
|
||||
final LocalPoint location = itemDespawned.getTile().getLocalLocation();
|
||||
log.debug("Item despawn {} ({}) location {}", item.getId(), item.getQuantity(), location);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged)
|
||||
{
|
||||
final TileItem item = itemQuantityChanged.getItem();
|
||||
final Tile tile = itemQuantityChanged.getTile();
|
||||
final LocalPoint location = tile.getLocalLocation();
|
||||
final int packed = location.getSceneX() << 8 | location.getSceneY();
|
||||
final int diff = itemQuantityChanged.getNewQuantity() - itemQuantityChanged.getOldQuantity();
|
||||
|
||||
if (diff <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
itemSpawns.put(packed, new ItemStack(item.getId(), diff, location));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(AnimationChanged e)
|
||||
{
|
||||
if (!(e.getActor() instanceof NPC))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NPC npc = (NPC) e.getActor();
|
||||
int id = npc.getId();
|
||||
|
||||
// We only care about certain NPCs
|
||||
final Integer deathAnim = NPC_DEATH_ANIMATIONS.get(id);
|
||||
|
||||
// Current animation is death animation?
|
||||
if (deathAnim != null && deathAnim == npc.getAnimation())
|
||||
{
|
||||
if (id == NpcID.CAVE_KRAKEN)
|
||||
{
|
||||
// Big Kraken drops loot wherever player is standing when animation starts.
|
||||
krakenPlayerLocation = client.getLocalPlayer().getWorldLocation();
|
||||
}
|
||||
else
|
||||
{
|
||||
// These NPCs drop loot on death animation, which is right now.
|
||||
processNpcLoot(npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcChanged(NpcChanged npcChanged)
|
||||
{
|
||||
final NPC npc = npcChanged.getNpc();
|
||||
if (npc.getId() == NpcID.THE_NIGHTMARE_9433)
|
||||
{
|
||||
delayedLootNpc = npc;
|
||||
delayedLootTickLimit = 15;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick gameTick)
|
||||
{
|
||||
if (delayedLootNpc != null && delayedLootTickLimit-- > 0)
|
||||
{
|
||||
processDelayedLoot();
|
||||
}
|
||||
|
||||
playerLocationLastTick = client.getLocalPlayer().getWorldLocation();
|
||||
|
||||
itemSpawns.clear();
|
||||
killPoints.clear();
|
||||
}
|
||||
|
||||
private void processDelayedLoot()
|
||||
{
|
||||
final WorldPoint adjacentLootTile = getAdjacentSquareLootTile(delayedLootNpc);
|
||||
final LocalPoint localPoint = LocalPoint.fromWorld(client, adjacentLootTile);
|
||||
|
||||
if (localPoint == null)
|
||||
{
|
||||
log.debug("Scene changed away from delayed loot location");
|
||||
delayedLootNpc = null;
|
||||
delayedLootTickLimit = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
final int sceneX = localPoint.getSceneX();
|
||||
final int sceneY = localPoint.getSceneY();
|
||||
final int packed = sceneX << 8 | sceneY;
|
||||
final List<ItemStack> itemStacks = itemSpawns.get(packed);
|
||||
if (itemStacks.isEmpty())
|
||||
{
|
||||
// no loot yet
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Got delayed loot stack from {}: {}", delayedLootNpc.getName(), itemStacks);
|
||||
eventBus.post(new NpcLootReceived(delayedLootNpc, itemStacks));
|
||||
|
||||
delayedLootNpc = null;
|
||||
delayedLootTickLimit = 0;
|
||||
}
|
||||
|
||||
private void processNpcLoot(NPC npc)
|
||||
{
|
||||
final LocalPoint location = LocalPoint.fromWorld(client, getDropLocation(npc, npc.getWorldLocation()));
|
||||
if (location == null || killPoints.contains(location))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int x = location.getSceneX();
|
||||
final int y = location.getSceneY();
|
||||
final int size = npc.getComposition().getSize();
|
||||
|
||||
// Some NPCs drop items onto multiple tiles
|
||||
final List<ItemStack> allItems = new ArrayList<>();
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
for (int j = 0; j < size; ++j)
|
||||
{
|
||||
final int packed = (x + i) << 8 | (y + j);
|
||||
final Collection<ItemStack> items = itemSpawns.get(packed);
|
||||
allItems.addAll(items);
|
||||
}
|
||||
}
|
||||
|
||||
if (allItems.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
killPoints.add(location);
|
||||
eventBus.post(new NpcLootReceived(npc, allItems));
|
||||
}
|
||||
|
||||
private WorldPoint getDropLocation(NPC npc, WorldPoint worldLocation)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.KRAKEN:
|
||||
case NpcID.KRAKEN_6640:
|
||||
case NpcID.KRAKEN_6656:
|
||||
worldLocation = playerLocationLastTick;
|
||||
break;
|
||||
case NpcID.CAVE_KRAKEN:
|
||||
worldLocation = krakenPlayerLocation;
|
||||
break;
|
||||
case NpcID.ZULRAH: // Green
|
||||
case NpcID.ZULRAH_2043: // Red
|
||||
case NpcID.ZULRAH_2044: // Blue
|
||||
for (Map.Entry<Integer, ItemStack> entry : itemSpawns.entries())
|
||||
{
|
||||
if (entry.getValue().getId() == ItemID.ZULRAHS_SCALES)
|
||||
{
|
||||
int packed = entry.getKey();
|
||||
int unpackedX = packed >> 8;
|
||||
int unpackedY = packed & 0xFF;
|
||||
worldLocation = WorldPoint.fromScene(client, unpackedX, unpackedY, worldLocation.getPlane());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NpcID.VORKATH:
|
||||
case NpcID.VORKATH_8058:
|
||||
case NpcID.VORKATH_8059:
|
||||
case NpcID.VORKATH_8060:
|
||||
case NpcID.VORKATH_8061:
|
||||
int x = worldLocation.getX() + 3;
|
||||
int y = worldLocation.getY() + 3;
|
||||
if (playerLocationLastTick.getX() < x)
|
||||
{
|
||||
x -= 4;
|
||||
}
|
||||
else if (playerLocationLastTick.getX() > x)
|
||||
{
|
||||
x += 4;
|
||||
}
|
||||
if (playerLocationLastTick.getY() < y)
|
||||
{
|
||||
y -= 4;
|
||||
}
|
||||
else if (playerLocationLastTick.getY() > y)
|
||||
{
|
||||
y += 4;
|
||||
}
|
||||
worldLocation = new WorldPoint(x, y, worldLocation.getPlane());
|
||||
break;
|
||||
}
|
||||
|
||||
return worldLocation;
|
||||
}
|
||||
|
||||
private WorldPoint getAdjacentSquareLootTile(NPC npc)
|
||||
{
|
||||
final NPCComposition composition = npc.getComposition();
|
||||
final WorldPoint worldLocation = npc.getWorldLocation();
|
||||
int x = worldLocation.getX();
|
||||
int y = worldLocation.getY();
|
||||
|
||||
if (playerLocationLastTick.getX() < x)
|
||||
{
|
||||
x -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += Math.min(playerLocationLastTick.getX() - x, composition.getSize());
|
||||
}
|
||||
|
||||
if (playerLocationLastTick.getY() < y)
|
||||
{
|
||||
y -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y += Math.min(playerLocationLastTick.getY() - y, composition.getSize());
|
||||
}
|
||||
|
||||
return new WorldPoint(x, y, worldLocation.getPlane());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of items present at the provided WorldPoint that spawned this tick.
|
||||
*
|
||||
* @param worldPoint the location in question
|
||||
* @return the list of item stacks
|
||||
*/
|
||||
public Collection<ItemStack> getItemSpawns(WorldPoint worldPoint)
|
||||
{
|
||||
LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||
if (localPoint == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final int sceneX = localPoint.getSceneX();
|
||||
final int sceneY = localPoint.getSceneY();
|
||||
final int packed = sceneX << 8 | sceneY;
|
||||
final List<ItemStack> itemStacks = itemSpawns.get(packed);
|
||||
return Collections.unmodifiableList(itemStacks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -25,136 +24,54 @@
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
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;
|
||||
import java.util.Set;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.http.api.npc.NpcInfo;
|
||||
import net.runelite.http.api.npc.NpcInfoClient;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class NPCManager
|
||||
{
|
||||
private static final Set<Integer> blacklistXpMultiplier = Set.of(
|
||||
// Vorkath
|
||||
NpcID.VORKATH, NpcID.VORKATH_8058, NpcID.VORKATH_8059, NpcID.VORKATH_8060, NpcID.VORKATH_8061,
|
||||
|
||||
// Grotesque Guardians
|
||||
NpcID.DAWN, NpcID.DAWN_7852, NpcID.DAWN_7853, NpcID.DAWN_7884, NpcID.DAWN_7885,
|
||||
NpcID.DUSK, NpcID.DUSK_7851, NpcID.DUSK_7854, NpcID.DUSK_7855, NpcID.DUSK_7882, NpcID.DUSK_7883, NpcID.DUSK_7886, NpcID.DUSK_7887, NpcID.DUSK_7888, NpcID.DUSK_7889,
|
||||
|
||||
// Kraken
|
||||
NpcID.KRAKEN, NpcID.KRAKEN_6640, NpcID.KRAKEN_6656,
|
||||
|
||||
// Zulrah
|
||||
NpcID.ZULRAH, NpcID.ZULRAH_2043, NpcID.ZULRAH_2044
|
||||
);
|
||||
private ImmutableMap<Integer, NPCStats> statsMap;
|
||||
private final OkHttpClient okHttpClient;
|
||||
private Map<Integer, NpcInfo> npcMap = Collections.emptyMap();
|
||||
|
||||
@Inject
|
||||
private NPCManager()
|
||||
private NPCManager(OkHttpClient okHttpClient, ScheduledExecutorService scheduledExecutorService)
|
||||
{
|
||||
Completable.fromAction(this::loadStats)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.subscribe(
|
||||
() -> log.debug("Loaded {} NPC stats", statsMap.size()),
|
||||
ex -> log.warn("Error loading NPC stats", ex)
|
||||
);
|
||||
this.okHttpClient = okHttpClient;
|
||||
scheduledExecutorService.execute(this::loadNpcs);
|
||||
}
|
||||
|
||||
private void loadStats() throws IOException
|
||||
{
|
||||
try (JsonReader reader = new JsonReader(new InputStreamReader(NPCManager.class.getResourceAsStream("/npc_stats.json"), StandardCharsets.UTF_8)))
|
||||
{
|
||||
ImmutableMap.Builder<Integer, NPCStats> builder = ImmutableMap.builderWithExpectedSize(2821);
|
||||
reader.beginObject();
|
||||
|
||||
while (reader.hasNext())
|
||||
{
|
||||
builder.put(
|
||||
Integer.parseInt(reader.nextName()),
|
||||
NPCStats.NPC_STATS_TYPE_ADAPTER.read(reader)
|
||||
);
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
statsMap = builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link NPCStats} for target NPC id
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return the {@link NPCStats} or null if unknown
|
||||
*/
|
||||
@Nullable
|
||||
public NPCStats getStats(final int npcId)
|
||||
public NpcInfo getNpcInfo(int npcId)
|
||||
{
|
||||
return statsMap.get(npcId);
|
||||
return npcMap.get(npcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns health for target NPC ID
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return health or null if unknown
|
||||
*/
|
||||
public int getHealth(final int npcId)
|
||||
@Nullable
|
||||
public Integer getHealth(int npcId)
|
||||
{
|
||||
final NPCStats s = statsMap.get(npcId);
|
||||
if (s == null || s.getHitpoints() == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s.getHitpoints();
|
||||
NpcInfo npcInfo = npcMap.get(npcId);
|
||||
return npcInfo == null ? null : npcInfo.getHitpoints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attack speed for target NPC ID.
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return attack speed in game ticks for NPC ID.
|
||||
*/
|
||||
public int getAttackSpeed(final int npcId)
|
||||
private void loadNpcs()
|
||||
{
|
||||
final NPCStats s = statsMap.get(npcId);
|
||||
if (s == null || s.getAttackSpeed() == -1)
|
||||
try
|
||||
{
|
||||
return -1;
|
||||
npcMap = new NpcInfoClient(okHttpClient).getNpcs();
|
||||
}
|
||||
|
||||
return s.getAttackSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exp modifier for target NPC ID based on its stats.
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return npcs exp modifier. Assumes default xp rate if npc stats are unknown (returns 1)
|
||||
*/
|
||||
public double getXpModifier(final int npcId)
|
||||
{
|
||||
if (blacklistXpMultiplier.contains(npcId))
|
||||
catch (IOException e)
|
||||
{
|
||||
return 1;
|
||||
log.warn("error loading npc stats", e);
|
||||
}
|
||||
|
||||
final NPCStats s = statsMap.get(npcId);
|
||||
if (s == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return s.calculateXpModifier();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user