client: Async-ify or improve data loading methods (#1782)
client: Async-ify or improve data loading methods
This commit is contained in:
@@ -24,77 +24,78 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.task.Schedule;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ClientSessionManager
|
||||
{
|
||||
private final SessionClient sessionClient = new SessionClient(this);
|
||||
private final ScheduledExecutorService executorService;
|
||||
|
||||
private ScheduledFuture<?> scheduledFuture;
|
||||
private final SessionClient sessionClient;
|
||||
private final ClientThread clientThread;
|
||||
private UUID sessionId;
|
||||
|
||||
|
||||
@Inject
|
||||
ClientSessionManager(ScheduledExecutorService executorService)
|
||||
ClientSessionManager(ClientThread clientThread)
|
||||
{
|
||||
this.executorService = executorService;
|
||||
this.sessionClient = new SessionClient();
|
||||
this.clientThread = clientThread;
|
||||
}
|
||||
|
||||
public void start()
|
||||
void start()
|
||||
{
|
||||
sessionClient.open();
|
||||
|
||||
scheduledFuture = executorService.scheduleWithFixedDelay(this::ping, 1, 10, TimeUnit.MINUTES);
|
||||
sessionClient.openSession()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.from(clientThread))
|
||||
.subscribe(this::setUuid, this::error);
|
||||
}
|
||||
|
||||
void setUuid(UUID uuid)
|
||||
@Schedule(period = 10, unit = ChronoUnit.MINUTES, asynchronous = true)
|
||||
private void ping()
|
||||
{
|
||||
this.sessionId = uuid;
|
||||
log.debug("Opened session {}", sessionId);
|
||||
}
|
||||
if (sessionId == null)
|
||||
{
|
||||
start();
|
||||
return;
|
||||
}
|
||||
|
||||
void error(IOException e)
|
||||
{
|
||||
log.warn("Client session error, resetting UUID", e.getCause());
|
||||
sessionId = null;
|
||||
sessionClient.pingSession(sessionId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.from(clientThread))
|
||||
.doOnError(e -> this.error((Throwable) e))
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
public void shutdown()
|
||||
{
|
||||
if (sessionId != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
sessionClient.delete(sessionId);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn(null, ex);
|
||||
}
|
||||
sessionClient.delete(sessionId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.from(clientThread))
|
||||
.doOnError(e -> this.error((Throwable) e))
|
||||
.subscribe();
|
||||
|
||||
sessionId = null;
|
||||
}
|
||||
|
||||
scheduledFuture.cancel(true);
|
||||
}
|
||||
|
||||
private void ping()
|
||||
private void setUuid(UUID uuid)
|
||||
{
|
||||
if (sessionId == null)
|
||||
{
|
||||
sessionClient.open();
|
||||
return;
|
||||
}
|
||||
this.sessionId = uuid;
|
||||
log.debug("Opened session {}.", sessionId);
|
||||
}
|
||||
|
||||
sessionClient.ping(sessionId);
|
||||
private void error(Throwable error)
|
||||
{
|
||||
log.debug("Error in client session.");
|
||||
log.trace(null, error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,6 +375,7 @@ public class RuneLite
|
||||
if (this.client != null)
|
||||
{
|
||||
scheduler.registerObject(modelOutlineRenderer.get());
|
||||
scheduler.registerObject(clientSessionManager);
|
||||
}
|
||||
|
||||
// Close the splash screen
|
||||
|
||||
@@ -24,106 +24,68 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import io.reactivex.Observable;
|
||||
import java.util.UUID;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class SessionClient
|
||||
{
|
||||
private final ClientSessionManager manager;
|
||||
|
||||
SessionClient(ClientSessionManager manager)
|
||||
Observable<UUID> openSession()
|
||||
{
|
||||
this.manager = manager;
|
||||
}
|
||||
final HttpUrl url = RuneLiteAPI.getSessionBase();
|
||||
|
||||
void open()
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getopenosrsSessionBase().newBuilder()
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
|
||||
return Observable.fromCallable(() ->
|
||||
{
|
||||
@Override
|
||||
public void onFailure(@NotNull Call call, @NotNull IOException e)
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
manager.error(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call call, @NotNull Response response)
|
||||
{
|
||||
try
|
||||
{
|
||||
ResponseBody body = response.body();
|
||||
|
||||
InputStream in = body.byteStream();
|
||||
|
||||
manager.setUuid(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), UUID.class));
|
||||
}
|
||||
catch (JsonParseException | IllegalArgumentException ex) // UUID.fromString can throw IllegalArgumentException
|
||||
{
|
||||
manager.error(new IOException(ex));
|
||||
}
|
||||
return RuneLiteAPI.GSON.fromJson(response.body().string(), UUID.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ping(UUID uuid)
|
||||
Observable pingSession(UUID uuid)
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getopenosrsSessionBase().newBuilder()
|
||||
final HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
.addPathSegment("ping")
|
||||
.addQueryParameter("session", uuid.toString())
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
|
||||
return Observable.defer(() ->
|
||||
{
|
||||
@Override
|
||||
public void onFailure(@NotNull Call call, @NotNull IOException e)
|
||||
{
|
||||
manager.error(e);
|
||||
}
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call call, @NotNull Response response)
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
manager.error(new IOException("Failed ping"));
|
||||
}
|
||||
return Observable.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void delete(UUID uuid) throws IOException
|
||||
Observable delete(UUID uuid)
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getopenosrsSessionBase().newBuilder()
|
||||
final HttpUrl url = RuneLiteAPI.getSessionBase().newBuilder()
|
||||
.addQueryParameter("session", uuid.toString())
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.delete()
|
||||
.url(url)
|
||||
.build();
|
||||
return Observable.defer(() ->
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.delete()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
RuneLiteAPI.CLIENT.newCall(request).execute().close();
|
||||
RuneLiteAPI.CLIENT.newCall(request).execute().close();
|
||||
return Observable.empty();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
package net.runelite.client.account;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
@@ -37,7 +38,6 @@ 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.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
@@ -57,13 +57,11 @@ public class SessionManager
|
||||
private AccountSession accountSession;
|
||||
|
||||
private final EventBus eventBus;
|
||||
private final ConfigManager configManager;
|
||||
private final WSClient wsClient;
|
||||
|
||||
@Inject
|
||||
private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient)
|
||||
private SessionManager(EventBus eventBus, WSClient wsClient)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.eventBus = eventBus;
|
||||
this.wsClient = wsClient;
|
||||
|
||||
@@ -94,13 +92,26 @@ public class SessionManager
|
||||
|
||||
// Check if session is still valid
|
||||
AccountClient accountClient = new AccountClient(session.getUuid());
|
||||
if (!accountClient.sessionCheck())
|
||||
{
|
||||
log.debug("Loaded session {} is invalid", session.getUuid());
|
||||
return;
|
||||
}
|
||||
|
||||
openSession(session, false);
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void saveSession()
|
||||
@@ -143,13 +154,6 @@ public class SessionManager
|
||||
|
||||
accountSession = session;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
eventBus.post(SessionOpen.class, new SessionOpen());
|
||||
}
|
||||
|
||||
@@ -176,9 +180,6 @@ public class SessionManager
|
||||
|
||||
accountSession = null; // No more account
|
||||
|
||||
// Restore config
|
||||
configManager.switchSession();
|
||||
|
||||
eventBus.post(SessionClose.class, new SessionClose());
|
||||
}
|
||||
|
||||
|
||||
@@ -28,14 +28,10 @@ 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 com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -137,12 +133,11 @@ public class ItemManager
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
private final ItemClient itemClient;
|
||||
private final ImmutableMap<Integer, ItemStats> itemStatMap;
|
||||
private final LoadingCache<ImageKey, AsyncBufferedImage> itemImages;
|
||||
private final LoadingCache<Integer, ItemDefinition> itemDefinitions;
|
||||
private final LoadingCache<OutlineKey, BufferedImage> itemOutlines;
|
||||
private Map<Integer, ItemPrice> itemPrices = Collections.emptyMap();
|
||||
private Map<Integer, ItemStats> itemStats = Collections.emptyMap();
|
||||
private ImmutableMap<Integer, ItemStats> itemStats = ImmutableMap.of();
|
||||
|
||||
@Inject
|
||||
public ItemManager(
|
||||
@@ -166,7 +161,7 @@ public class ItemManager
|
||||
.build(new CacheLoader<ImageKey, AsyncBufferedImage>()
|
||||
{
|
||||
@Override
|
||||
public AsyncBufferedImage load(@NotNull ImageKey key) throws Exception
|
||||
public AsyncBufferedImage load(@NotNull ImageKey key)
|
||||
{
|
||||
return loadImage(key.itemId, key.itemQuantity, key.stackable);
|
||||
}
|
||||
@@ -178,7 +173,7 @@ public class ItemManager
|
||||
.build(new CacheLoader<Integer, ItemDefinition>()
|
||||
{
|
||||
@Override
|
||||
public ItemDefinition load(@NotNull Integer key) throws Exception
|
||||
public ItemDefinition load(@NotNull Integer key)
|
||||
{
|
||||
return client.getItemDefinition(key);
|
||||
}
|
||||
@@ -190,24 +185,21 @@ public class ItemManager
|
||||
.build(new CacheLoader<OutlineKey, BufferedImage>()
|
||||
{
|
||||
@Override
|
||||
public BufferedImage load(@NotNull OutlineKey key) throws Exception
|
||||
public BufferedImage load(@NotNull OutlineKey key)
|
||||
{
|
||||
return loadItemOutline(key.itemId, key.itemQuantity, key.outlineColor);
|
||||
}
|
||||
});
|
||||
|
||||
final Gson gson = new Gson();
|
||||
|
||||
final Type typeToken = new TypeToken<Map<Integer, ItemStats>>()
|
||||
{
|
||||
}.getType();
|
||||
|
||||
final InputStream statsFile = getClass().getResourceAsStream("/item_stats.json");
|
||||
final Map<Integer, ItemStats> stats = gson.fromJson(new InputStreamReader(statsFile), typeToken);
|
||||
itemStatMap = ImmutableMap.copyOf(stats);
|
||||
|
||||
eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventbus.subscribe(PostItemDefinition.class, this, this::onPostItemDefinition);
|
||||
|
||||
Completable.fromAction(ItemVariationMapping::load)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.subscribe(
|
||||
() -> log.debug("Loaded {} item variations", ItemVariationMapping.getSize()),
|
||||
ex -> log.warn("Error loading item variations", ex)
|
||||
);
|
||||
}
|
||||
|
||||
private void loadPrices()
|
||||
@@ -215,21 +207,9 @@ public class ItemManager
|
||||
itemClient.getPrices()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
(prices) ->
|
||||
{
|
||||
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());
|
||||
},
|
||||
(e) -> log.warn("error loading prices!", e)
|
||||
m -> itemPrices = m,
|
||||
e -> log.warn("Error loading prices", e),
|
||||
() -> log.debug("Loaded {} prices", itemPrices.size())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -238,16 +218,9 @@ public class ItemManager
|
||||
itemClient.getStats()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
(stats) ->
|
||||
{
|
||||
if (stats != null)
|
||||
{
|
||||
itemStats = ImmutableMap.copyOf(stats);
|
||||
}
|
||||
|
||||
log.debug("Loaded {} stats", itemStats.size());
|
||||
},
|
||||
(e) -> log.warn("error loading stats!", e)
|
||||
m -> itemStats = m,
|
||||
e -> log.warn("Error fetching stats", e),
|
||||
() -> log.debug("Loaded {} stats", itemStats.size())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -376,12 +349,12 @@ public class ItemManager
|
||||
{
|
||||
ItemDefinition itemDefinition = getItemDefinition(itemId);
|
||||
|
||||
if (itemDefinition.getName() == null || !allowNote && itemDefinition.getNote() != -1)
|
||||
if (!allowNote && itemDefinition.getNote() != -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return itemStatMap.get(canonicalize(itemId));
|
||||
return itemStats.get(canonicalize(itemId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package net.runelite.client.game;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class ItemStat
|
||||
{
|
||||
private int slot;
|
||||
|
||||
private int astab;
|
||||
private int aslash;
|
||||
private int acrush;
|
||||
private int amagic;
|
||||
private int arange;
|
||||
|
||||
private int dstab;
|
||||
private int dslash;
|
||||
private int dcrush;
|
||||
private int dmagic;
|
||||
private int drange;
|
||||
|
||||
private int str;
|
||||
private int rstr;
|
||||
private int mdmg;
|
||||
private int prayer;
|
||||
private int aspeed;
|
||||
}
|
||||
@@ -26,44 +26,20 @@
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.InputStream;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Converts variation items to it's base item counterparts
|
||||
*/
|
||||
@Slf4j
|
||||
public class ItemVariationMapping
|
||||
{
|
||||
private static final Map<Integer, Integer> MAPPINGS;
|
||||
|
||||
static
|
||||
{
|
||||
final Gson gson = new Gson();
|
||||
final TypeToken<Map<String, Collection<Integer>>> typeToken = new TypeToken<Map<String, Collection<Integer>>>()
|
||||
{
|
||||
};
|
||||
|
||||
final InputStream geLimitData = ItemVariationMapping.class.getResourceAsStream("/item_variations.json");
|
||||
final Map<String, Collection<Integer>> itemVariations = gson.fromJson(new InputStreamReader(geLimitData), typeToken.getType());
|
||||
|
||||
ImmutableMap.Builder<Integer, Integer> builder = new ImmutableMap.Builder<>();
|
||||
for (Collection<Integer> value : itemVariations.values())
|
||||
{
|
||||
final Iterator<Integer> iterator = value.iterator();
|
||||
final int base = iterator.next();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
builder.put(iterator.next(), base);
|
||||
}
|
||||
}
|
||||
MAPPINGS = builder.build();
|
||||
}
|
||||
private static Map<Integer, Integer> MAPPINGS;
|
||||
|
||||
/**
|
||||
* Get base item id for provided variation item id.
|
||||
@@ -75,4 +51,39 @@ public class ItemVariationMapping
|
||||
{
|
||||
return MAPPINGS.getOrDefault(itemId, itemId);
|
||||
}
|
||||
|
||||
static void load() throws IOException
|
||||
{
|
||||
try (JsonReader reader = new JsonReader(new InputStreamReader(ItemVariationMapping.class.getResourceAsStream("/item_variations.json"), StandardCharsets.UTF_8)))
|
||||
{
|
||||
ImmutableMap.Builder<Integer, Integer> builder = ImmutableMap.builderWithExpectedSize(5039);
|
||||
reader.beginObject();
|
||||
|
||||
while (reader.hasNext())
|
||||
{
|
||||
// Names are useless
|
||||
reader.skipValue();
|
||||
reader.beginArray();
|
||||
|
||||
int base = reader.nextInt();
|
||||
while (reader.hasNext())
|
||||
{
|
||||
builder.put(
|
||||
reader.nextInt(),
|
||||
base
|
||||
);
|
||||
}
|
||||
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
MAPPINGS = builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
static int getSize()
|
||||
{
|
||||
return MAPPINGS.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.InputStream;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -41,20 +41,37 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Singleton
|
||||
public class NPCManager
|
||||
{
|
||||
private final ImmutableMap<Integer, NPCStats> statsMap;
|
||||
private ImmutableMap<Integer, NPCStats> statsMap;
|
||||
|
||||
@Inject
|
||||
private NPCManager()
|
||||
{
|
||||
final Gson gson = new Gson();
|
||||
Completable.fromAction(this::loadStats)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.subscribe(
|
||||
() -> log.debug("Loaded {} NPC stats", statsMap.size()),
|
||||
ex -> log.warn("Error loading NPC stats", ex)
|
||||
);
|
||||
}
|
||||
|
||||
final Type typeToken = new TypeToken<Map<Integer, NPCStats>>()
|
||||
private void loadStats() throws IOException
|
||||
{
|
||||
try (JsonReader reader = new JsonReader(new InputStreamReader(NPCManager.class.getResourceAsStream("/npc_stats.json"), StandardCharsets.UTF_8)))
|
||||
{
|
||||
}.getType();
|
||||
ImmutableMap.Builder<Integer, NPCStats> builder = ImmutableMap.builderWithExpectedSize(2821);
|
||||
reader.beginObject();
|
||||
|
||||
final InputStream statsFile = getClass().getResourceAsStream("/npc_stats.json");
|
||||
final Map<Integer, NPCStats> stats = gson.fromJson(new InputStreamReader(statsFile), typeToken);
|
||||
statsMap = ImmutableMap.copyOf(stats);
|
||||
while (reader.hasNext())
|
||||
{
|
||||
builder.put(
|
||||
Integer.parseInt(reader.nextName()),
|
||||
NPCStats.NPC_STATS_TYPE_ADAPTER.read(reader)
|
||||
);
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
statsMap = builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,9 +24,15 @@
|
||||
*/
|
||||
package net.runelite.client.game;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@Builder(builderClassName = "Builder")
|
||||
public class NPCStats
|
||||
{
|
||||
private final String name;
|
||||
@@ -77,4 +83,120 @@ public class NPCStats
|
||||
|
||||
return (1 + Math.floor(averageLevel * (averageDefBonus + bonusStrength + bonusAttack) / 5120) / 40);
|
||||
}
|
||||
|
||||
// Because this class is here we can't add the TypeAdapter to gson (easily)
|
||||
// doesn't mean we can't use one to do it a bit quicker
|
||||
public static final TypeAdapter<NPCStats> NPC_STATS_TYPE_ADAPTER = new TypeAdapter<NPCStats>()
|
||||
{
|
||||
@Override
|
||||
public void write(JsonWriter out, NPCStats value)
|
||||
{
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPCStats read(JsonReader in) throws IOException
|
||||
{
|
||||
in.beginObject();
|
||||
NPCStats.Builder builder = NPCStats.builder();
|
||||
|
||||
// Name is the only one that's guaranteed
|
||||
in.skipValue();
|
||||
builder.name(in.nextString());
|
||||
|
||||
while (in.hasNext())
|
||||
{
|
||||
switch (in.nextName())
|
||||
{
|
||||
case "hitpoints":
|
||||
builder.hitpoints(in.nextInt());
|
||||
break;
|
||||
case "combatLevel":
|
||||
builder.combatLevel(in.nextInt());
|
||||
break;
|
||||
case "slayerLevel":
|
||||
builder.slayerLevel(in.nextInt());
|
||||
break;
|
||||
case "attackSpeed":
|
||||
builder.attackSpeed(in.nextInt());
|
||||
break;
|
||||
case "attackLevel":
|
||||
builder.attackLevel(in.nextInt());
|
||||
break;
|
||||
case "strengthLevel":
|
||||
builder.strengthLevel(in.nextInt());
|
||||
break;
|
||||
case "defenceLevel":
|
||||
builder.defenceLevel(in.nextInt());
|
||||
break;
|
||||
case "rangeLevel":
|
||||
builder.rangeLevel(in.nextInt());
|
||||
break;
|
||||
case "magicLevel":
|
||||
builder.magicLevel(in.nextInt());
|
||||
break;
|
||||
case "stab":
|
||||
builder.stab(in.nextInt());
|
||||
break;
|
||||
case "slash":
|
||||
builder.slash(in.nextInt());
|
||||
break;
|
||||
case "crush":
|
||||
builder.crush(in.nextInt());
|
||||
break;
|
||||
case "range":
|
||||
builder.range(in.nextInt());
|
||||
break;
|
||||
case "magic":
|
||||
builder.magic(in.nextInt());
|
||||
break;
|
||||
case "stabDef":
|
||||
builder.stabDef(in.nextInt());
|
||||
break;
|
||||
case "slashDef":
|
||||
builder.slashDef(in.nextInt());
|
||||
break;
|
||||
case "crushDef":
|
||||
builder.crushDef(in.nextInt());
|
||||
break;
|
||||
case "rangeDef":
|
||||
builder.rangeDef(in.nextInt());
|
||||
break;
|
||||
case "magicDef":
|
||||
builder.magicDef(in.nextInt());
|
||||
break;
|
||||
case "bonusAttack":
|
||||
builder.bonusAttack(in.nextInt());
|
||||
break;
|
||||
case "bonusStrength":
|
||||
builder.bonusStrength(in.nextInt());
|
||||
break;
|
||||
case "bonusRangeStrength":
|
||||
builder.bonusRangeStrength(in.nextInt());
|
||||
break;
|
||||
case "bonusMagicDamage":
|
||||
builder.bonusMagicDamage(in.nextInt());
|
||||
break;
|
||||
case "poisonImmune":
|
||||
builder.poisonImmune(in.nextBoolean());
|
||||
break;
|
||||
case "venomImmune":
|
||||
builder.venomImmune(in.nextBoolean());
|
||||
break;
|
||||
case "dragon":
|
||||
builder.dragon(in.nextBoolean());
|
||||
break;
|
||||
case "demon":
|
||||
builder.demon(in.nextBoolean());
|
||||
break;
|
||||
case "undead":
|
||||
builder.undead(in.nextBoolean());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in.endObject();
|
||||
return builder.build();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -56,9 +56,9 @@ public class HighAlchemyOverlay extends WidgetItemOverlay
|
||||
this.itemManager = itemManager;
|
||||
this.plugin = plugin;
|
||||
|
||||
int natPrice = itemManager.getItemPrice(ItemID.NATURE_RUNE);
|
||||
int natPrice = itemManager.getItemPrice(ItemID.NATURE_RUNE, true);
|
||||
this.alchPrice = natPrice;
|
||||
this.alchPriceNoStaff = natPrice + 5 * itemManager.getItemPrice(ItemID.FIRE_RUNE);
|
||||
this.alchPriceNoStaff = natPrice + 5 * itemManager.getItemPrice(ItemID.FIRE_RUNE, true);
|
||||
|
||||
showOnBank();
|
||||
showOnInventory();
|
||||
|
||||
@@ -48,7 +48,7 @@ import net.runelite.http.api.item.ItemStats;
|
||||
public class ItemStatOverlay extends Overlay
|
||||
{
|
||||
// Unarmed attack speed is 6
|
||||
private static final ItemStats UNARMED = new ItemStats("", false, true, 0,
|
||||
private static final ItemStats UNARMED = new ItemStats(false, true, 0,
|
||||
ItemEquipmentStats.builder()
|
||||
.aspeed(6)
|
||||
.build());
|
||||
|
||||
@@ -551,6 +551,7 @@ public class PlayerScouter extends Plugin
|
||||
}
|
||||
|
||||
ItemStats item = itemManager.getItemStats(gear, false);
|
||||
String name = itemManager.getItemDefinition(gear).getName();
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
@@ -559,7 +560,7 @@ public class PlayerScouter extends Plugin
|
||||
}
|
||||
|
||||
fieldList.add(FieldEmbed.builder()
|
||||
.name(item.getName())
|
||||
.name(name)
|
||||
.value("Value: " + StackFormatter.quantityToRSDecimalStack(value))
|
||||
.inline(true)
|
||||
.build());
|
||||
|
||||
@@ -77,10 +77,13 @@ public class StonedTrackerPlugin extends Plugin
|
||||
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
|
||||
@Inject
|
||||
public StonedTrackerConfig config;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.timetracking.farming;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -42,7 +43,7 @@ import net.runelite.client.plugins.timetracking.Tab;
|
||||
class FarmingWorld
|
||||
{
|
||||
@Getter
|
||||
private Map<Integer, FarmingRegion> regions = new HashMap<>();
|
||||
private final ImmutableMap<Integer, FarmingRegion> regions;
|
||||
|
||||
@Getter
|
||||
private Map<Tab, Set<FarmingPatch>> tabs = new HashMap<>();
|
||||
@@ -54,58 +55,60 @@ class FarmingWorld
|
||||
|
||||
FarmingWorld()
|
||||
{
|
||||
ImmutableMap.Builder<Integer, FarmingRegion> regionBuilder = ImmutableMap.builderWithExpectedSize(40);
|
||||
|
||||
// Some of these patches get updated in multiple regions.
|
||||
// It may be worth it to add a specialization for these patches
|
||||
add(new FarmingRegion("Al Kharid", 13106,
|
||||
add(regionBuilder, new FarmingRegion("Al Kharid", 13106,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.CACTUS)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Ardougne", 10290,
|
||||
add(regionBuilder, new FarmingRegion("Ardougne", 10290,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH)
|
||||
));
|
||||
add(new FarmingRegion("Ardougne", 10548,
|
||||
add(regionBuilder, new FarmingRegion("Ardougne", 10548,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
new FarmingPatch("", Varbits.FARMING_4774, PatchImplementation.HERB)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Brimhaven", 11058,
|
||||
add(regionBuilder, new FarmingRegion("Brimhaven", 11058,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.SPIRIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Catherby", 11062,
|
||||
add(regionBuilder, new FarmingRegion("Catherby", 11062,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
new FarmingPatch("", Varbits.FARMING_4774, PatchImplementation.HERB)
|
||||
));
|
||||
add(new FarmingRegion("Catherby", 11317,
|
||||
add(regionBuilder, new FarmingRegion("Catherby", 11317,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Champions' Guild", 12596,
|
||||
add(regionBuilder, new FarmingRegion("Champions' Guild", 12596,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Draynor Manor", 12340,
|
||||
add(regionBuilder, new FarmingRegion("Draynor Manor", 12340,
|
||||
new FarmingPatch("Belladonna", Varbits.FARMING_4771, PatchImplementation.BELLADONNA)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Entrana", 11060,
|
||||
add(regionBuilder, new FarmingRegion("Entrana", 11060,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Etceteria", 10300,
|
||||
add(regionBuilder, new FarmingRegion("Etceteria", 10300,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.SPIRIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Falador", 11828,
|
||||
add(regionBuilder, new FarmingRegion("Falador", 11828,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
));
|
||||
add(new FarmingRegion("Falador", 12083,
|
||||
add(regionBuilder, new FarmingRegion("Falador", 12083,
|
||||
new FarmingPatch("North West", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South East", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -119,36 +122,36 @@ class FarmingWorld
|
||||
}
|
||||
});
|
||||
|
||||
add(new FarmingRegion("Fossil Island", 14651,
|
||||
add(regionBuilder, new FarmingRegion("Fossil Island", 14651,
|
||||
new FarmingPatch("East", Varbits.FARMING_4771, PatchImplementation.HARDWOOD_TREE),
|
||||
new FarmingPatch("Middle", Varbits.FARMING_4772, PatchImplementation.HARDWOOD_TREE),
|
||||
new FarmingPatch("West", Varbits.FARMING_4773, PatchImplementation.HARDWOOD_TREE)
|
||||
), 14907);
|
||||
add(new FarmingRegion("Seaweed", 15008,
|
||||
add(regionBuilder, new FarmingRegion("Seaweed", 15008,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.SEAWEED),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.SEAWEED)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Gnome Stronghold", 9781,
|
||||
add(regionBuilder, new FarmingRegion("Gnome Stronghold", 9781,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.FRUIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Harmony", 15148,
|
||||
add(regionBuilder, new FarmingRegion("Harmony", 15148,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.HERB)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Kourend", 6967,
|
||||
add(regionBuilder, new FarmingRegion("Kourend", 6967,
|
||||
new FarmingPatch("North East", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South West", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
new FarmingPatch("", Varbits.FARMING_4774, PatchImplementation.HERB)
|
||||
));
|
||||
add(new FarmingRegion("Kourend", 6711,
|
||||
add(regionBuilder, new FarmingRegion("Kourend", 6711,
|
||||
new FarmingPatch("", Varbits.FARMING_7904, PatchImplementation.SPIRIT_TREE)
|
||||
));
|
||||
add(new FarmingRegion("Kourend", 7223,
|
||||
add(regionBuilder, new FarmingRegion("Kourend", 7223,
|
||||
new FarmingPatch("East 1", Varbits.GRAPES_4953, PatchImplementation.GRAPES),
|
||||
new FarmingPatch("East 2", Varbits.GRAPES_4954, PatchImplementation.GRAPES),
|
||||
new FarmingPatch("East 3", Varbits.GRAPES_4955, PatchImplementation.GRAPES),
|
||||
@@ -163,21 +166,21 @@ class FarmingWorld
|
||||
new FarmingPatch("West 6", Varbits.GRAPES_4964, PatchImplementation.GRAPES)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Lletya", 9265,
|
||||
add(regionBuilder, new FarmingRegion("Lletya", 9265,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Lumbridge", 12851,
|
||||
add(regionBuilder, new FarmingRegion("Lumbridge", 12851,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
));
|
||||
add(new FarmingRegion("Lumbridge", 12594,
|
||||
add(regionBuilder, new FarmingRegion("Lumbridge", 12594,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Morytania", 13622,
|
||||
add(regionBuilder, new FarmingRegion("Morytania", 13622,
|
||||
new FarmingPatch("Mushroom", Varbits.FARMING_4771, PatchImplementation.MUSHROOM)
|
||||
));
|
||||
add(new FarmingRegion("Morytania", 14391,
|
||||
add(regionBuilder, new FarmingRegion("Morytania", 14391,
|
||||
new FarmingPatch("North West", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South East", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -185,51 +188,51 @@ class FarmingWorld
|
||||
));
|
||||
|
||||
|
||||
add(new FarmingRegion("Port Sarim", 12082,
|
||||
add(regionBuilder, new FarmingRegion("Port Sarim", 12082,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.SPIRIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Rimmington", 11570,
|
||||
add(regionBuilder, new FarmingRegion("Rimmington", 11570,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.BUSH)
|
||||
), 11826);
|
||||
|
||||
add(new FarmingRegion("Seers' Village", 10551,
|
||||
add(regionBuilder, new FarmingRegion("Seers' Village", 10551,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Tai Bwo Wannai", 11056,
|
||||
add(regionBuilder, new FarmingRegion("Tai Bwo Wannai", 11056,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.CALQUAT)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Taverley", 11573,
|
||||
add(regionBuilder, new FarmingRegion("Taverley", 11573,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Tree Gnome Village", 9777,
|
||||
add(regionBuilder, new FarmingRegion("Tree Gnome Village", 9777,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.FRUIT_TREE)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Troll Stronghold", 11321,
|
||||
add(regionBuilder, new FarmingRegion("Troll Stronghold", 11321,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HERB)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Varrock", 12854,
|
||||
add(regionBuilder, new FarmingRegion("Varrock", 12854,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.TREE)
|
||||
), 12853);
|
||||
|
||||
add(new FarmingRegion("Yanille", 10288,
|
||||
add(regionBuilder, new FarmingRegion("Yanille", 10288,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HOPS)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Weiss", 11325,
|
||||
add(regionBuilder, new FarmingRegion("Weiss", 11325,
|
||||
new FarmingPatch("", Varbits.FARMING_4771, PatchImplementation.HERB)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Farming Guild", 5021,
|
||||
add(regionBuilder, new FarmingRegion("Farming Guild", 5021,
|
||||
new FarmingPatch("Hespori", Varbits.FARMING_7908, PatchImplementation.HESPORI)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Farming Guild", 4922,
|
||||
add(regionBuilder, new FarmingRegion("Farming Guild", 4922,
|
||||
new FarmingPatch("", Varbits.FARMING_7905, PatchImplementation.TREE),
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.HERB),
|
||||
new FarmingPatch("", Varbits.FARMING_4772, PatchImplementation.BUSH),
|
||||
@@ -244,7 +247,7 @@ class FarmingWorld
|
||||
new FarmingPatch("", Varbits.FARMING_7907, PatchImplementation.REDWOOD)
|
||||
));
|
||||
|
||||
add(new FarmingRegion("Prifddinas", 13151,
|
||||
add(regionBuilder, new FarmingRegion("Prifddinas", 13151,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
@@ -252,7 +255,8 @@ class FarmingWorld
|
||||
));
|
||||
|
||||
// Finalize
|
||||
this.regions = Collections.unmodifiableMap(regions);
|
||||
this.regions = regionBuilder.build();
|
||||
|
||||
Map<Tab, Set<FarmingPatch>> umtabs = new TreeMap<>();
|
||||
for (Map.Entry<Tab, Set<FarmingPatch>> e : tabs.entrySet())
|
||||
{
|
||||
@@ -261,12 +265,12 @@ class FarmingWorld
|
||||
this.tabs = Collections.unmodifiableMap(umtabs);
|
||||
}
|
||||
|
||||
private void add(FarmingRegion r, int... extraRegions)
|
||||
private void add(ImmutableMap.Builder<Integer, FarmingRegion> builder, FarmingRegion r, int... extraRegions)
|
||||
{
|
||||
regions.put(r.getRegionID(), r);
|
||||
builder.put(r.getRegionID(), r);
|
||||
for (int er : extraRegions)
|
||||
{
|
||||
regions.put(er, r);
|
||||
builder.put(er, r);
|
||||
}
|
||||
for (FarmingPatch p : r.getPatches())
|
||||
{
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.worldmap;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Getter
|
||||
enum TeleportLocationData
|
||||
@@ -188,6 +190,24 @@ enum TeleportLocationData
|
||||
private final String tooltip;
|
||||
private final WorldPoint location;
|
||||
private final String iconPath;
|
||||
private BufferedImage image;
|
||||
|
||||
BufferedImage getImage()
|
||||
{
|
||||
if (image == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
image = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, this.getIconPath());
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
return WorldMapPlugin.BLANK_ICON;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
TeleportLocationData(TeleportType type, String destination, int magicLevel, WorldPoint location, String iconPath)
|
||||
{
|
||||
|
||||
@@ -26,14 +26,12 @@
|
||||
package net.runelite.client.plugins.worldmap;
|
||||
|
||||
import net.runelite.client.ui.overlay.worldmap.WorldMapPoint;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
class TeleportPoint extends WorldMapPoint
|
||||
{
|
||||
TeleportPoint(TeleportLocationData data)
|
||||
{
|
||||
super(data.getLocation(), WorldMapPlugin.BLANK_ICON);
|
||||
super(data.getLocation(), data.getImage());
|
||||
setTooltip(data.getTooltip());
|
||||
setImage(ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, data.getIconPath()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.GameState;
|
||||
@@ -127,6 +128,9 @@ public class WorldMapPlugin extends Plugin
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
|
||||
@Inject
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
private int agilityLevel = 0;
|
||||
private int woodcuttingLevel = 0;
|
||||
|
||||
@@ -308,30 +312,33 @@ public class WorldMapPlugin extends Plugin
|
||||
}
|
||||
|
||||
worldMapPointManager.removeIf(TeleportPoint.class::isInstance);
|
||||
Arrays.stream(TeleportLocationData.values())
|
||||
.filter(data ->
|
||||
{
|
||||
switch (data.getType())
|
||||
// This next part gets 142 icons from disk, and does so on the EDT (at first run)
|
||||
executor.submit(() ->
|
||||
Arrays.stream(TeleportLocationData.values())
|
||||
.filter(data ->
|
||||
{
|
||||
case NORMAL_MAGIC:
|
||||
return this.normalTeleportIcon;
|
||||
case ANCIENT_MAGICKS:
|
||||
return this.ancientTeleportIcon;
|
||||
case LUNAR_MAGIC:
|
||||
return this.lunarTeleportIcon;
|
||||
case ARCEUUS_MAGIC:
|
||||
return this.arceuusTeleportIcon;
|
||||
case JEWELLERY:
|
||||
return this.jewelleryTeleportIcon;
|
||||
case SCROLL:
|
||||
return this.scrollTeleportIcon;
|
||||
case OTHER:
|
||||
return this.miscellaneousTeleportIcon;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}).map(TeleportPoint::new)
|
||||
.forEach(worldMapPointManager::add);
|
||||
switch (data.getType())
|
||||
{
|
||||
case NORMAL_MAGIC:
|
||||
return this.normalTeleportIcon;
|
||||
case ANCIENT_MAGICKS:
|
||||
return this.ancientTeleportIcon;
|
||||
case LUNAR_MAGIC:
|
||||
return this.lunarTeleportIcon;
|
||||
case ARCEUUS_MAGIC:
|
||||
return this.arceuusTeleportIcon;
|
||||
case JEWELLERY:
|
||||
return this.jewelleryTeleportIcon;
|
||||
case SCROLL:
|
||||
return this.scrollTeleportIcon;
|
||||
case OTHER:
|
||||
return this.miscellaneousTeleportIcon;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}).map(TeleportPoint::new)
|
||||
.forEach(worldMapPointManager::add)
|
||||
);
|
||||
}
|
||||
|
||||
private void updateQuestStartPointIcons()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -340,8 +340,10 @@ public class ItemVariationMappingTest
|
||||
}};
|
||||
|
||||
@Test
|
||||
public void testMappedNames()
|
||||
public void testMappedNames() throws Exception
|
||||
{
|
||||
ItemVariationMapping.load();
|
||||
|
||||
ITEMS_MAP.forEach((key, value) ->
|
||||
{
|
||||
assertEquals(value, (Integer) ItemVariationMapping.map(key));
|
||||
|
||||
Reference in New Issue
Block a user