Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-12-22 15:08:16 +01:00
9 changed files with 74 additions and 454 deletions

View File

@@ -1,104 +0,0 @@
/*
* Copyright (c) 2017, 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.http.api.cache;
import java.time.Instant;
import java.util.Objects;
public class Cache
{
private final int id;
private final int revision;
private final Instant date;
public Cache(int id, int revision, Instant date)
{
this.id = id;
this.revision = revision;
this.date = date;
}
@Override
public String toString()
{
return "Cache{" + "id=" + id + ", revision=" + revision + ", date=" + date + '}';
}
@Override
public int hashCode()
{
int hash = 5;
hash = 29 * hash + this.id;
hash = 29 * hash + this.revision;
hash = 29 * hash + Objects.hashCode(this.date);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Cache other = (Cache) obj;
if (this.id != other.id)
{
return false;
}
if (this.revision != other.revision)
{
return false;
}
if (!Objects.equals(this.date, other.date))
{
return false;
}
return true;
}
public int getId()
{
return id;
}
public int getRevision()
{
return revision;
}
public Instant getDate()
{
return date;
}
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright (c) 2017, 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.http.api.cache;
public class CacheArchive
{
private final int archiveId;
private final int nameHash;
private final int revision;
public CacheArchive(int archiveId, int nameHash, int revision)
{
this.archiveId = archiveId;
this.nameHash = nameHash;
this.revision = revision;
}
@Override
public String toString()
{
return "CacheArchive{" + "archiveId=" + archiveId + ", nameHash=" + nameHash + ", revision=" + revision + '}';
}
@Override
public int hashCode()
{
int hash = 5;
hash = 71 * hash + this.archiveId;
hash = 71 * hash + this.nameHash;
hash = 71 * hash + this.revision;
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final CacheArchive other = (CacheArchive) obj;
if (this.archiveId != other.archiveId)
{
return false;
}
if (this.nameHash != other.nameHash)
{
return false;
}
if (this.revision != other.revision)
{
return false;
}
return true;
}
public int getArchiveId()
{
return archiveId;
}
public int getNameHash()
{
return nameHash;
}
public int getRevision()
{
return revision;
}
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright (c) 2017, 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.http.api.cache;
public class CacheIndex
{
private final int indexId;
private final int revision;
public CacheIndex(int indexId, int revision)
{
this.indexId = indexId;
this.revision = revision;
}
@Override
public String toString()
{
return "CacheIndex{" + "indexId=" + indexId + ", revision=" + revision + '}';
}
@Override
public int hashCode()
{
int hash = 5;
hash = 61 * hash + this.indexId;
hash = 61 * hash + this.revision;
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final CacheIndex other = (CacheIndex) obj;
if (this.indexId != other.indexId)
{
return false;
}
if (this.revision != other.revision)
{
return false;
}
return true;
}
public int getIndexId()
{
return indexId;
}
public int getRevision()
{
return revision;
}
}

View File

@@ -965,20 +965,6 @@ public interface Client extends GameEngine
*/
long getOverallExperience();
/**
* Gets the game drawing mode.
*
* @return the game drawing mode
*/
int getGameDrawingMode();
/**
* Sets the games drawing mode.
*
* @param gameDrawingMode the new drawing mode
*/
void setGameDrawingMode(int gameDrawingMode);
/**
* Refreshes the chat.
*/

View File

@@ -30,19 +30,27 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.openosrs.client.OpenOSRS;
import com.openosrs.client.game.PlayerManager;
import com.openosrs.client.ui.OpenOSRSSplashScreen;
import java.applet.Applet;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import javax.inject.Provider;
import javax.inject.Singleton;
@@ -50,8 +58,6 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.swing.SwingUtilities;
import com.openosrs.client.OpenOSRS;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
@@ -61,6 +67,7 @@ import joptsimple.util.EnumConverter;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.client.account.SessionManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.discord.DiscordService;
@@ -73,7 +80,6 @@ import net.runelite.client.rs.ClientLoader;
import net.runelite.client.rs.ClientUpdateCheckMode;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.FatalErrorDialog;
import com.openosrs.client.ui.OpenOSRSSplashScreen;
import net.runelite.client.ui.SplashScreen;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.WidgetOverlay;
@@ -92,7 +98,8 @@ import org.slf4j.LoggerFactory;
@Slf4j
public class RuneLite
{
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".openosrs");
public static final String OPENOSRS = ".openosrs";
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), OPENOSRS);
public static final File CACHE_DIR = new File(RUNELITE_DIR, "cache");
public static final File PLUGINS_DIR = new File(RUNELITE_DIR, "plugin-hub");
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
@@ -151,6 +158,10 @@ public class RuneLite
@Inject
private WorldService worldService;
@Inject
@Nullable
private Applet applet;
@Inject
@Nullable
private Client client;
@@ -336,6 +347,28 @@ public class RuneLite
injector.injectMembers(client);
}
// Start the applet
if (applet != null)
{
copyJagexCache();
// Client size must be set prior to init
applet.setSize(Constants.GAME_FIXED_SIZE);
// Change user.home so the client places jagexcache in the .runelite directory
String oldHome = System.setProperty("user.home", RUNELITE_DIR.getAbsolutePath());
try
{
applet.init();
}
finally
{
System.setProperty("user.home", oldHome);
}
applet.start();
}
SplashScreen.stage(.57, null, "Loading configuration");
// Load user configuration
@@ -558,4 +591,36 @@ public class RuneLite
String launcherVersion = System.getProperty("launcher.version");
System.setProperty("runelite.launcher.version", launcherVersion == null ? "unknown" : launcherVersion);
}
}
private static void copyJagexCache()
{
Path from = Paths.get(System.getProperty("user.home"), "jagexcache");
Path to = Paths.get(System.getProperty("user.home"), OPENOSRS, "jagexcache");
if (Files.exists(to) || !Files.exists(from))
{
return;
}
log.info("Copying jagexcache from {} to {}", from, to);
// Recursively copy path https://stackoverflow.com/a/50418060
try (Stream<Path> stream = Files.walk(from))
{
stream.forEach(source ->
{
try
{
Files.copy(source, to.resolve(from.relativize(source)), COPY_ATTRIBUTES);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
});
}
catch (Exception e)
{
log.warn("unable to copy jagexcache", e);
}
}
}

View File

@@ -166,7 +166,7 @@ public class ConfigManager
this.propertiesFile = getPropertiesFile();
this.gson = gson;
scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 5 * 60, TimeUnit.SECONDS);
}
public String getRSProfileKey()
@@ -268,8 +268,6 @@ public class ConfigManager
}
}
}
migrateConfig();
}
private void syncPropertiesFromFile(File propertiesFile)
@@ -1254,116 +1252,6 @@ public class ConfigManager
return new String[]{group, profile, key};
}
private synchronized void migrateConfig()
{
String migrationKey = "profileMigrationDone";
if (getConfiguration("runelite", migrationKey) != null)
{
return;
}
Map<String, String> profiles = new HashMap<>();
AtomicInteger changes = new AtomicInteger();
List<Predicate<String>> migrators = new ArrayList<>();
for (String[] tpl : new String[][]
{
{"(grandexchange)\\.buylimit_(%)\\.(#)", "$1.buylimit.$3"},
{"(timetracking)\\.(%)\\.(autoweed|contract)", "$1.$3"},
{"(timetracking)\\.(%)\\.(#\\.#)", "$1.$3"},
{"(timetracking)\\.(%)\\.(birdhouse)\\.(#)", "$1.$3.$4"},
{"(killcount|personalbest)\\.(%)\\.([^.]+)", "$1.$3"},
{"(geoffer)\\.(%)\\.(#)", "$1.$3"},
})
{
String replace = tpl[1];
String pat = ("^" + tpl[0] + "$")
.replace("#", "-?[0-9]+")
.replace("(%)", "(?<login>.*)");
Pattern p = Pattern.compile(pat);
migrators.add(oldkey ->
{
Matcher m = p.matcher(oldkey);
if (!m.find())
{
return false;
}
String newKey = m.replaceFirst(replace);
String username = m.group("login").toLowerCase(Locale.US);
if (username.startsWith(RSPROFILE_GROUP + "."))
{
return false;
}
String profKey = profiles.computeIfAbsent(username, u ->
findRSProfile(getRSProfiles(), u, RuneScapeProfileType.STANDARD, u, true).getKey());
String[] oldKeySplit = splitKey(oldkey);
if (oldKeySplit == null)
{
log.warn("skipping migration of invalid key \"{}\"", oldkey);
return false;
}
if (oldKeySplit[KEY_SPLITTER_PROFILE] != null)
{
log.debug("skipping migrated key \"{}\"", oldkey);
return false;
}
String[] newKeySplit = splitKey(newKey);
if (newKeySplit == null || newKeySplit[KEY_SPLITTER_PROFILE] != null)
{
log.warn("migration produced a bad key: \"{}\" -> \"{}\"", oldkey, newKey);
return false;
}
if (changes.getAndAdd(1) <= 0)
{
File file = new File(propertiesFile.getParent(), propertiesFile.getName() + "." + TIME_FORMAT.format(new Date()));
log.info("backing up pre-migration config to {}", file);
try
{
saveToFile(file);
}
catch (IOException e)
{
log.error("Backup failed", e);
throw new RuntimeException(e);
}
}
String oldGroup = oldKeySplit[KEY_SPLITTER_GROUP];
String oldKeyPart = oldKeySplit[KEY_SPLITTER_KEY];
String value = getConfiguration(oldGroup, oldKeyPart);
setConfiguration(newKeySplit[KEY_SPLITTER_GROUP], profKey, newKeySplit[KEY_SPLITTER_KEY], value);
unsetConfiguration(oldGroup, oldKeyPart);
return true;
});
}
Set<String> keys = (Set<String>) ImmutableSet.copyOf((Set) properties.keySet());
keys:
for (String key : keys)
{
for (Predicate<String> mig : migrators)
{
if (mig.test(key))
{
continue keys;
}
}
}
if (changes.get() > 0)
{
log.info("migrated {} config keys", changes);
}
setConfiguration("runelite", migrationKey, 1);
}
/**
* Retrieves a consumer from config group and key name
*/

View File

@@ -66,10 +66,6 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat
"Jorral",
"Speak to Jorral to receive a strange device.",
new WorldPoint(2436, 3347, 0));
private static final HotColdClue MASTER_CLUE_LEAGUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Watson may have a clue.",
"Watson",
"Speak to Watson to receive a strange device.",
new WorldPoint(1645, 3572, 0));
private final String text;
private final String npc;
@@ -91,11 +87,6 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat
MASTER_CLUE.reset();
return MASTER_CLUE;
}
else if (MASTER_CLUE_LEAGUE.text.equalsIgnoreCase(text))
{
MASTER_CLUE_LEAGUE.reset();
return MASTER_CLUE_LEAGUE;
}
return null;
}
@@ -290,7 +281,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat
{
temperatureSet = HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES;
}
else if (this == MASTER_CLUE || this == MASTER_CLUE_LEAGUE)
else if (this == MASTER_CLUE)
{
temperatureSet = HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES;
}
@@ -314,9 +305,8 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat
return false;
}
boolean master = this == MASTER_CLUE || this == MASTER_CLUE_LEAGUE;
if ((this == BEGINNER_CLUE && temperature == HotColdTemperature.BEGINNER_VISIBLY_SHAKING)
|| (master && temperature == HotColdTemperature.MASTER_VISIBLY_SHAKING))
|| (this == MASTER_CLUE && temperature == HotColdTemperature.MASTER_VISIBLY_SHAKING))
{
markFinalSpot(localWorld);
}
@@ -346,7 +336,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat
{
isBeginner = true;
}
else if (this == MASTER_CLUE || this == MASTER_CLUE_LEAGUE)
else if (this == MASTER_CLUE)
{
isBeginner = false;
}

View File

@@ -29,7 +29,6 @@ import java.awt.BorderLayout;
import java.awt.Color;
import javax.annotation.Nullable;
import javax.swing.JPanel;
import net.runelite.api.Client;
import net.runelite.api.Constants;
final class ClientPanel extends JPanel
@@ -47,20 +46,6 @@ final class ClientPanel extends JPanel
return;
}
client.setLayout(null);
client.setSize(Constants.GAME_FIXED_SIZE);
client.init();
client.start();
add(client, BorderLayout.CENTER);
// This causes the whole game frame to be redrawn each frame instead
// of only the viewport, so we can hook to MainBufferProvider#draw
// and draw anywhere without it leaving artifacts
if (client instanceof Client)
{
((Client)client).setGameDrawingMode(2);
}
}
}

View File

@@ -538,14 +538,6 @@ public interface RSClient extends RSGameEngine, Client
@Override
int[][] getXteaKeys();
@Import("gameDrawingMode")
@Override
int getGameDrawingMode();
@Import("gameDrawingMode")
@Override
void setGameDrawingMode(int gameDrawingMode);
@Import("cycleCntr")
int getCycleCntr();