Merge pull request #2086 from Owain94/selective-upstream-merge

project: Selective upstream merge
This commit is contained in:
Owain van Brakel
2019-11-28 21:41:45 +01:00
committed by GitHub
63 changed files with 1570 additions and 777 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
- name: Assembling - name: Assembling
run: ./gradlew assemble --console=plain run: ./gradlew assemble --console=plain
- name: Building - name: Building
run: ./gradlew build --stacktrace -x test -x checkstyleMain --console=plain run: ./gradlew build --stacktrace -x test -x checkstyleMain -x checkstyleTest --console=plain
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -26,7 +26,7 @@
package net.runelite.http.api.worlds; package net.runelite.http.api.worlds;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import io.reactivex.Observable; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import javax.inject.Inject; import javax.inject.Inject;
@@ -50,7 +50,7 @@ public class WorldClient
this.client = client; this.client = client;
} }
public Observable<WorldResult> lookupWorlds() public WorldResult lookupWorlds() throws IOException
{ {
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
.addPathSegment("worlds.js") .addPathSegment("worlds.js")
@@ -58,8 +58,6 @@ public class WorldClient
logger.debug("Built URI: {}", url); logger.debug("Built URI: {}", url);
return Observable.defer(() ->
{
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.build(); .build();
@@ -69,16 +67,15 @@ public class WorldClient
if (!response.isSuccessful()) if (!response.isSuccessful())
{ {
logger.debug("Error looking up worlds: {}", response); logger.debug("Error looking up worlds: {}", response);
return Observable.just(null); throw new IOException("unsuccessful response looking up worlds");
} }
InputStream in = response.body().byteStream(); InputStream in = response.body().byteStream();
return Observable.just(RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class)); return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), WorldResult.class);
} }
catch (JsonParseException ex) catch (JsonParseException ex)
{ {
return Observable.error(ex); throw new IOException(ex);
} }
});
} }
} }
@@ -47,6 +47,7 @@ public class ChatController
{ {
private static final Pattern STRING_VALIDATION = Pattern.compile("[^a-zA-Z0-9' -]"); private static final Pattern STRING_VALIDATION = Pattern.compile("[^a-zA-Z0-9' -]");
private static final int STRING_MAX_LENGTH = 50; private static final int STRING_MAX_LENGTH = 50;
private static final int MAX_LAYOUT_ROOMS = 16;
private final Cache<KillCountKey, Integer> killCountCache = CacheBuilder.newBuilder() private final Cache<KillCountKey, Integer> killCountCache = CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES) .expireAfterWrite(2, TimeUnit.MINUTES)
@@ -214,6 +215,11 @@ public class ChatController
@PostMapping("/layout") @PostMapping("/layout")
public void submitLayout(@RequestParam String name, @RequestBody LayoutRoom[] rooms) public void submitLayout(@RequestParam String name, @RequestBody LayoutRoom[] rooms)
{ {
if (rooms.length > MAX_LAYOUT_ROOMS)
{
return;
}
chatService.setLayout(name, rooms); chatService.setLayout(name, rooms);
} }
@@ -148,6 +148,10 @@ public enum ChatMessageType
* A message that times out after 10 seconds. * A message that times out after 10 seconds.
*/ */
TENSECTIMEOUT(107), TENSECTIMEOUT(107),
/**
* The "Welcome to RuneScape" message
*/
WELCOME(108),
/** /**
* An unknown message type. * An unknown message type.
*/ */
@@ -11357,5 +11357,14 @@ public final class ItemID
public static final int TWISTED_BOOTS_T1 = 24411; public static final int TWISTED_BOOTS_T1 = 24411;
public static final int TWISTED_LEAGUE_BANNER = 24413; public static final int TWISTED_LEAGUE_BANNER = 24413;
public static final int RUNE_POUCH_L = 24416; public static final int RUNE_POUCH_L = 24416;
public static final int INQUISITORS_MACE = 24417;
public static final int SIRENS_TOME = 24418;
public static final int INQUISITORS_GREAT_HELM = 24419;
public static final int INQUISITORS_HAUBERK = 24420;
public static final int INQUISITORS_PLATESKIRT = 24421;
public static final int NIGHTMARE_STAFF = 24422;
public static final int HARMONISED_NIGHTMARE_STAFF = 24423;
public static final int VOLATILE_NIGHTMARE_STAFF = 24424;
public static final int ELDRITCH_NIGHTMARE_STAFF = 24425;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -12850,5 +12850,6 @@ public final class NullItemID
public static final int NULL_24410 = 24410; public static final int NULL_24410 = 24410;
public static final int NULL_24412 = 24412; public static final int NULL_24412 = 24412;
public static final int NULL_24414 = 24414; public static final int NULL_24414 = 24414;
public static final int NULL_24415 = 24415;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -18070,5 +18070,6 @@ public final class NullObjectID
public static final int NULL_37480 = 37480; public static final int NULL_37480 = 37480;
public static final int NULL_37481 = 37481; public static final int NULL_37481 = 37481;
public static final int NULL_37490 = 37490; public static final int NULL_37490 = 37490;
public static final int NULL_37491 = 37491;
/* This file is automatically generated. Do not edit. */ /* This file is automatically generated. Do not edit. */
} }
@@ -33,6 +33,7 @@ import javax.annotation.Nullable;
import lombok.Value; import lombok.Value;
import net.runelite.api.Client; import net.runelite.api.Client;
import static net.runelite.api.Constants.CHUNK_SIZE; import static net.runelite.api.Constants.CHUNK_SIZE;
import static net.runelite.api.Constants.REGION_SIZE;
import net.runelite.api.Perspective; import net.runelite.api.Perspective;
/** /**
@@ -416,6 +417,6 @@ public class WorldPoint
private static int getRegionOffset(final int position) private static int getRegionOffset(final int position)
{ {
return position & 0x3f; return position & (REGION_SIZE - 1);
} }
} }
@@ -986,6 +986,7 @@ public class WidgetID
static class StandardSpellBook static class StandardSpellBook
{ {
static final int LUMBRIDGE_HOME_TELEPORT = 5; static final int LUMBRIDGE_HOME_TELEPORT = 5;
static final int KOUREND_HOME_TELEPORT = 4;
} }
static class AncientSpellBook static class AncientSpellBook
@@ -512,6 +512,7 @@ public enum WidgetInfo
PVP_FOG_OVERLAY(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.FOG_OVERLAY), PVP_FOG_OVERLAY(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.FOG_OVERLAY),
PVP_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.PVP_WIDGET_CONTAINER), PVP_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.PVP_WIDGET_CONTAINER),
PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER), PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER),
PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL), PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL),
PVP_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), PVP_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE),
@@ -676,6 +677,7 @@ public enum WidgetInfo
/* END OF LUNAR SPELL BOOK WIDGETS*/ /* END OF LUNAR SPELL BOOK WIDGETS*/
SPELL_TOOLTIP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TOOLTIP), SPELL_TOOLTIP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TOOLTIP),
/* ARCEUUS SPELL BOOK WIDGETS*/ /* ARCEUUS SPELL BOOK WIDGETS*/
SPELL_KOUREND_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.KOUREND_HOME_TELEPORT),
SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARCEUUS_HOME_TELEPORT), SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARCEUUS_HOME_TELEPORT),
SPELL_BATTLEFRONT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BATTLEFRONT_TELEPORT), SPELL_BATTLEFRONT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BATTLEFRONT_TELEPORT),
/* END OF ARCEUUS SPELL BOOK WIDGETS*/ /* END OF ARCEUUS SPELL BOOK WIDGETS*/
@@ -29,6 +29,7 @@ import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import javax.annotation.Nullable;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -41,6 +42,7 @@ public class ClientThread implements Executor
private final ConcurrentLinkedQueue<BooleanSupplier> invokes = new ConcurrentLinkedQueue<>(); private final ConcurrentLinkedQueue<BooleanSupplier> invokes = new ConcurrentLinkedQueue<>();
@Inject @Inject
@Nullable
private Client client; private Client client;
public void invoke(Runnable r) public void invoke(Runnable r)
@@ -26,12 +26,11 @@ package net.runelite.client.config;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Objects; import java.util.Objects;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.util.ReflectUtil;
@Slf4j @Slf4j
class ConfigInvocationHandler implements InvocationHandler class ConfigInvocationHandler implements InvocationHandler
@@ -169,12 +168,8 @@ class ConfigInvocationHandler implements InvocationHandler
static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable
{ {
// Call the default method implementation - https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/
Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
Class<?> declaringClass = method.getDeclaringClass(); Class<?> declaringClass = method.getDeclaringClass();
return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE) return ReflectUtil.privateLookupIn(declaringClass)
.unreflectSpecial(method, declaringClass) .unreflectSpecial(method, declaringClass)
.bindTo(proxy) .bindTo(proxy)
.invokeWithArguments(args); .invokeWithArguments(args);
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019, 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.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
{
private final WorldResult worldResult;
}
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2019, 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 java.io.IOException;
import java.util.Comparator;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.WorldsFetch;
import net.runelite.client.util.RunnableExceptionLogger;
import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient;
import net.runelite.http.api.worlds.WorldResult;
@Singleton
@Slf4j
public class WorldService
{
private static final int WORLD_FETCH_TIMER = 10; // minutes
private final Client client;
private final ScheduledExecutorService scheduledExecutorService;
private final WorldClient worldClient;
private final EventBus eventBus;
private final CompletableFuture<WorldResult> firstRunFuture = new CompletableFuture<>();
private WorldResult worlds;
@Inject
private WorldService(Client client, ScheduledExecutorService scheduledExecutorService, WorldClient worldClient,
EventBus eventBus)
{
this.client = client;
this.scheduledExecutorService = scheduledExecutorService;
this.worldClient = worldClient;
this.eventBus = eventBus;
scheduledExecutorService.scheduleWithFixedDelay(RunnableExceptionLogger.wrap(this::tick), 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES);
}
private void tick()
{
try
{
if (worlds == null || client.getGameState() == GameState.LOGGED_IN)
{
fetch();
}
}
finally
{
firstRunFuture.complete(worlds);
}
}
private void fetch()
{
log.debug("Fetching worlds");
try
{
WorldResult worldResult = worldClient.lookupWorlds();
worldResult.getWorlds().sort(Comparator.comparingInt(World::getId));
worlds = worldResult;
eventBus.post(WorldsFetch.class, new WorldsFetch(worldResult));
}
catch (IOException ex)
{
log.warn("Error looking up worlds", ex);
}
}
public void refresh()
{
scheduledExecutorService.execute(this::fetch);
}
@Nullable
public WorldResult getWorlds()
{
if (!firstRunFuture.isDone())
{
try
{
return firstRunFuture.get(10, TimeUnit.SECONDS);
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
log.warn("Failed to retrieve worlds on first run", e);
}
}
return worlds;
}
}
@@ -52,6 +52,7 @@ import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import org.apache.commons.lang3.StringUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Chat History", name = "Chat History",
@@ -61,7 +62,7 @@ import net.runelite.client.plugins.PluginDescriptor;
@Singleton @Singleton
public class ChatHistoryPlugin extends Plugin implements KeyListener public class ChatHistoryPlugin extends Plugin implements KeyListener
{ {
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape."; private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape";
private static final String CLEAR_HISTORY = "Clear history"; private static final String CLEAR_HISTORY = "Clear history";
private static final String CLEAR_PRIVATE = "<col=ffff00>Private:"; private static final String CLEAR_PRIVATE = "<col=ffff00>Private:";
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB; private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
@@ -137,7 +138,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
{ {
// Start sending old messages right after the welcome message, as that is most reliable source // Start sending old messages right after the welcome message, as that is most reliable source
// of information that chat history was reset // of information that chat history was reset
if (chatMessage.getMessage().equals(WELCOME_MESSAGE)) ChatMessageType chatMessageType = chatMessage.getType();
if (chatMessageType == ChatMessageType.WELCOME && StringUtils.startsWithIgnoreCase(chatMessage.getMessage(), WELCOME_MESSAGE))
{ {
if (!this.retainChatHistory) if (!this.retainChatHistory)
{ {
@@ -154,7 +156,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
return; return;
} }
switch (chatMessage.getType()) switch (chatMessageType)
{ {
case PRIVATECHATOUT: case PRIVATECHATOUT:
case PRIVATECHAT: case PRIVATECHAT:
@@ -174,7 +176,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
case FRIENDSCHAT: case FRIENDSCHAT:
case CONSOLE: case CONSOLE:
final QueuedMessage queuedMessage = QueuedMessage.builder() final QueuedMessage queuedMessage = QueuedMessage.builder()
.type(chatMessage.getType()) .type(chatMessageType)
.name(chatMessage.getName()) .name(chatMessage.getName())
.sender(chatMessage.getSender()) .sender(chatMessage.getSender())
.value(tweakSpaces(chatMessage.getMessage())) .value(tweakSpaces(chatMessage.getMessage()))
@@ -25,22 +25,21 @@
package net.runelite.client.plugins.defaultworld; package net.runelite.client.plugins.defaultworld;
import com.google.inject.Provides; import com.google.inject.Provides;
import io.reactivex.schedulers.Schedulers;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.SessionOpen; import net.runelite.client.events.SessionOpen;
import net.runelite.client.game.WorldService;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.WorldUtil; import net.runelite.client.util.WorldUtil;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient; import net.runelite.http.api.worlds.WorldResult;
@PluginDescriptor( @PluginDescriptor(
name = "Default World", name = "Default World",
@@ -58,10 +57,7 @@ public class DefaultWorldPlugin extends Plugin
private DefaultWorldConfig config; private DefaultWorldConfig config;
@Inject @Inject
private ClientThread clientThread; private WorldService worldService;
@Inject
private WorldClient worldClient;
private int worldCache; private int worldCache;
private boolean worldChangeRequired; private boolean worldChangeRequired;
@@ -122,14 +118,11 @@ public class DefaultWorldPlugin extends Plugin
return; return;
} }
worldClient.lookupWorlds() final WorldResult worldResult = worldService.getWorlds();
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.from(clientThread))
.subscribe(
(worldResult) ->
{
if (worldResult == null) if (worldResult == null)
{ {
log.warn("Failed to lookup worlds.");
return; return;
} }
@@ -152,9 +145,6 @@ public class DefaultWorldPlugin extends Plugin
{ {
log.warn("World {} not found.", correctedWorld); log.warn("World {} not found.", correctedWorld);
} }
},
(e) -> log.warn("Error looking up world {}. Error: {}", correctedWorld, e)
);
} }
private void applyWorld() private void applyWorld()
@@ -84,7 +84,9 @@ enum Emoji
ALIEN("(@.@)"), ALIEN("(@.@)"),
EGGPLANT("8=D"), EGGPLANT("8=D"),
WAVE("(^_^)/"), WAVE("(^_^)/"),
HEART_EYES("(*.*)"); HEART_EYES("(*.*)"),
FACEPALM("M-)"),
;
private static final Map<String, Emoji> emojiMap; private static final Map<String, Emoji> emojiMap;
@@ -33,14 +33,15 @@ import net.runelite.client.config.Range;
public interface FpsConfig extends Config public interface FpsConfig extends Config
{ {
@ConfigItem( @ConfigItem(
keyName = "limitMode", keyName = "limitFps",
name = "Limit Mode", name = "Limit Global FPS",
description = "Stay at or under the target frames per second even when in this mode", description = "Global FPS limit in effect regardless of<br>" +
"whether window is in focus or not",
position = 1 position = 1
) )
default FpsLimitMode limitMode() default boolean limitFps()
{ {
return FpsLimitMode.NEVER; return false;
} }
@Range( @Range(
@@ -49,8 +50,8 @@ public interface FpsConfig extends Config
) )
@ConfigItem( @ConfigItem(
keyName = "maxFps", keyName = "maxFps",
name = "FPS target", name = "Global FPS target",
description = "Desired max frames per second", description = "Desired max global frames per second",
position = 2 position = 2
) )
default int maxFps() default int maxFps()
@@ -58,11 +59,33 @@ public interface FpsConfig extends Config
return 50; return 50;
} }
@ConfigItem(
keyName = "limitFpsUnfocused",
name = "Limit FPS unfocused",
description = "FPS limit while window is out of focus",
position = 3
)
default boolean limitFpsUnfocused()
{
return false;
}
@ConfigItem(
keyName = "maxFpsUnfocused",
name = "Unfocused FPS target",
description = "Desired max frames per second for unfocused",
position = 4
)
default int maxFpsUnfocused()
{
return 50;
}
@ConfigItem( @ConfigItem(
keyName = "drawFps", keyName = "drawFps",
name = "Draw FPS indicator", name = "Draw FPS indicator",
description = "Show a number in the corner for the current FPS", description = "Show a number in the corner for the current FPS",
position = 3 position = 5
) )
default boolean drawFps() default boolean drawFps()
{ {
@@ -69,7 +69,13 @@ public class FpsDrawListener implements Runnable
void reloadConfig() void reloadConfig()
{ {
lastMillis = System.currentTimeMillis(); lastMillis = System.currentTimeMillis();
targetDelay = 1000 / Math.max(1, config.maxFps());
int fps = config.limitFpsUnfocused() && !isFocused
? config.maxFpsUnfocused()
: config.maxFps();
targetDelay = 1000 / Math.max(1, fps);
sleepDelay = targetDelay; sleepDelay = targetDelay;
for (int i = 0; i < SAMPLE_SIZE; i++) for (int i = 0; i < SAMPLE_SIZE; i++)
@@ -81,18 +87,18 @@ public class FpsDrawListener implements Runnable
void onFocusChanged(FocusChanged event) void onFocusChanged(FocusChanged event)
{ {
this.isFocused = event.isFocused(); this.isFocused = event.isFocused();
reloadConfig(); // load new delay
} }
private boolean isEnforced() private boolean isEnforced()
{ {
return FpsLimitMode.ALWAYS == plugin.getLimitMode() return config.limitFps()
|| (FpsLimitMode.UNFOCUSED == plugin.getLimitMode() && !isFocused); || (config.limitFpsUnfocused() && !isFocused);
} }
@Override @Override
public void run() public void run()
{ {
if (!isEnforced()) if (!isEnforced())
{ {
return; return;
@@ -57,16 +57,16 @@ public class FpsOverlay extends Overlay
// Local dependencies // Local dependencies
private final Client client; private final Client client;
private final FpsPlugin plugin; private final FpsConfig config;
// Often changing values // Often changing values
private boolean isFocused = true; private boolean isFocused = true;
@Inject @Inject
private FpsOverlay(final FpsPlugin plugin, final Client client) private FpsOverlay(final FpsConfig config, final Client client)
{ {
this.client = client; this.client = client;
this.plugin = plugin; this.config = config;
setLayer(OverlayLayer.ABOVE_WIDGETS); setLayer(OverlayLayer.ABOVE_WIDGETS);
setPriority(OverlayPriority.HIGH); setPriority(OverlayPriority.HIGH);
setPosition(OverlayPosition.DYNAMIC); setPosition(OverlayPosition.DYNAMIC);
@@ -79,8 +79,8 @@ public class FpsOverlay extends Overlay
private boolean isEnforced() private boolean isEnforced()
{ {
return FpsLimitMode.ALWAYS == plugin.getLimitMode() return config.limitFps()
|| (FpsLimitMode.UNFOCUSED == plugin.getLimitMode() && !isFocused); || (config.limitFpsUnfocused() && !isFocused);
} }
private Color getFpsValueColor() private Color getFpsValueColor()
@@ -91,7 +91,7 @@ public class FpsOverlay extends Overlay
@Override @Override
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
if (!plugin.isDrawFps()) if (!config.drawFps())
{ {
return null; return null;
} }
@@ -27,8 +27,6 @@ package net.runelite.client.plugins.fps;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
@@ -71,15 +69,6 @@ public class FpsPlugin extends Plugin
@Inject @Inject
private DrawManager drawManager; private DrawManager drawManager;
@Inject
private FpsConfig fpsConfig;
@Getter(AccessLevel.PACKAGE)
private FpsLimitMode limitMode;
@Getter(AccessLevel.PACKAGE)
private boolean drawFps;
@Provides @Provides
FpsConfig provideConfig(ConfigManager configManager) FpsConfig provideConfig(ConfigManager configManager)
{ {
@@ -92,9 +81,6 @@ public class FpsPlugin extends Plugin
if (event.getGroup().equals(CONFIG_GROUP_KEY)) if (event.getGroup().equals(CONFIG_GROUP_KEY))
{ {
drawListener.reloadConfig(); drawListener.reloadConfig();
limitMode = fpsConfig.limitMode();
drawFps = fpsConfig.drawFps();
} }
} }
@@ -108,9 +94,6 @@ public class FpsPlugin extends Plugin
@Override @Override
protected void startUp() protected void startUp()
{ {
limitMode = fpsConfig.limitMode();
drawFps = fpsConfig.drawFps();
overlayManager.add(overlay); overlayManager.add(overlay);
drawManager.registerEveryFrameListener(drawListener); drawManager.registerEveryFrameListener(drawListener);
drawListener.reloadConfig(); drawListener.reloadConfig();
@@ -84,7 +84,6 @@ class InventoryGridOverlay extends Overlay
final Point mousePoint = new Point(mouse.getX(), mouse.getY()); final Point mousePoint = new Point(mouse.getX(), mouse.getY());
final int if1DraggedItemIndex = client.getIf1DraggedItemIndex(); final int if1DraggedItemIndex = client.getIf1DraggedItemIndex();
final WidgetItem draggedItem = inventoryWidget.getWidgetItem(if1DraggedItemIndex); final WidgetItem draggedItem = inventoryWidget.getWidgetItem(if1DraggedItemIndex);
final int itemId = draggedItem.getId();
final Rectangle initialBounds = draggedItem.getCanvasBounds(); final Rectangle initialBounds = draggedItem.getCanvasBounds();
if (initialMousePoint == null) if (initialMousePoint == null)
@@ -92,7 +91,7 @@ class InventoryGridOverlay extends Overlay
initialMousePoint = mousePoint; initialMousePoint = mousePoint;
} }
if (itemId == -1 || !hoverActive && initialMousePoint.distance(mousePoint) < DISTANCE_TO_ACTIVATE_HOVER) if (draggedItem.getId() == -1 || !hoverActive && initialMousePoint.distance(mousePoint) < DISTANCE_TO_ACTIVATE_HOVER)
{ {
return null; return null;
} }
@@ -101,16 +100,15 @@ class InventoryGridOverlay extends Overlay
for (int i = 0; i < INVENTORY_SIZE; ++i) for (int i = 0; i < INVENTORY_SIZE; ++i)
{ {
WidgetItem widgetItem = inventoryWidget.getWidgetItem(i); WidgetItem targetWidgetItem = inventoryWidget.getWidgetItem(i);
final int targetItemId = widgetItem.getId();
final Rectangle bounds = widgetItem.getCanvasBounds(); final Rectangle bounds = targetWidgetItem.getCanvasBounds();
boolean inBounds = bounds.contains(mousePoint); boolean inBounds = bounds.contains(mousePoint);
if (plugin.isShowItem() && inBounds) if (plugin.isShowItem() && inBounds)
{ {
drawItem(graphics, bounds, itemId); drawItem(graphics, bounds, draggedItem);
drawItem(graphics, initialBounds, targetItemId); drawItem(graphics, initialBounds, targetWidgetItem);
} }
if (plugin.isShowHighlight() && inBounds) if (plugin.isShowHighlight() && inBounds)
@@ -128,14 +126,14 @@ class InventoryGridOverlay extends Overlay
return null; return null;
} }
private void drawItem(Graphics2D graphics, Rectangle bounds, int itemId) private void drawItem(Graphics2D graphics, Rectangle bounds, WidgetItem item)
{ {
if (itemId == -1) if (item.getId() == -1)
{ {
return; return;
} }
final BufferedImage draggedItemImage = itemManager.getImage(itemId); final BufferedImage draggedItemImage = itemManager.getImage(item.getId(), item.getQuantity(), false);
final int x = (int) bounds.getX(); final int x = (int) bounds.getX();
final int y = (int) bounds.getY(); final int y = (int) bounds.getY();
@@ -34,7 +34,6 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.IconID;
import net.runelite.api.VarClientInt; import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr; import net.runelite.api.VarClientStr;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
@@ -212,7 +211,7 @@ public class KeyRemappingPlugin extends Plugin
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null && chatboxInput.getText().endsWith(PRESS_ENTER_TO_CHAT)) if (chatboxInput != null && chatboxInput.getText().endsWith(PRESS_ENTER_TO_CHAT))
{ {
chatboxInput.setText(getWaitingText()); setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT);
} }
} }
); );
@@ -227,7 +226,7 @@ public class KeyRemappingPlugin extends Plugin
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null && chatboxFocused() && !typing) if (chatboxInput != null && chatboxFocused() && !typing)
{ {
chatboxInput.setText(getWaitingText()); setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT);
} }
break; break;
case SCRIPT_EVENT_BLOCK_CHAT_INPUT: case SCRIPT_EVENT_BLOCK_CHAT_INPUT:
@@ -246,7 +245,7 @@ public class KeyRemappingPlugin extends Plugin
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null) if (chatboxInput != null)
{ {
chatboxInput.setText(getWaitingText()); setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT);
} }
} }
@@ -257,39 +256,24 @@ public class KeyRemappingPlugin extends Plugin
{ {
final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1; final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1;
final Color textColor = isChatboxTransparent ? JagexColors.CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND : JagexColors.CHAT_TYPED_TEXT_OPAQUE_BACKGROUND; final Color textColor = isChatboxTransparent ? JagexColors.CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND : JagexColors.CHAT_TYPED_TEXT_OPAQUE_BACKGROUND;
chatboxInput.setText(getPlayerNameWithIcon() + ": " + ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor)); setChatboxWidgetInput(chatboxInput, ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor));
} }
} }
private String getPlayerNameWithIcon() private void setChatboxWidgetInput(Widget widget, String input)
{
IconID icon;
switch (client.getAccountType())
{
case IRONMAN:
icon = IconID.IRONMAN;
break;
case ULTIMATE_IRONMAN:
icon = IconID.ULTIMATE_IRONMAN;
break;
case HARDCORE_IRONMAN:
icon = IconID.HARDCORE_IRONMAN;
break;
default:
return client.getLocalPlayer().getName();
}
return icon + client.getLocalPlayer().getName();
}
private String getWaitingText()
{ {
if (this.hideDisplayName) if (this.hideDisplayName)
{ {
return PRESS_ENTER_TO_CHAT; widget.setText(input);
return;
} }
else
String text = widget.getText();
int idx = text.indexOf(':');
if (idx != -1)
{ {
return getPlayerNameWithIcon() + ": " + PRESS_ENTER_TO_CHAT; String newText = text.substring(0, idx) + ": " + input;
widget.setText(newText);
} }
} }
@@ -0,0 +1,349 @@
/*
* Copyright (c) 2019, hsamoht <https://github.com/hsamoht>
* Copyright (c) 2019, 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.plugins.leaguechaticons;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatPlayer;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.IconID;
import net.runelite.api.IndexedSprite;
import net.runelite.api.MessageNode;
import net.runelite.api.Player;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.util.Text;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.WorldService;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.ImageUtil;
import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldResult;
import net.runelite.http.api.worlds.WorldType;
@PluginDescriptor(
name = "Chat League Icons",
description = "Changes the chat icon for players on league worlds",
enabledByDefault = false
)
@Slf4j
public class LeagueChatIconsPlugin extends Plugin
{
private static final String SCRIPT_EVENT_SET_CHATBOX_INPUT = "setChatboxInput";
private static final String IRONMAN_PREFIX = "<img=" + IconID.IRONMAN.getIndex() + ">";
@Inject
private Client client;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private WorldService worldService;
@Inject
private ClientThread clientThread;
private int leagueIconOffset = -1; // offset for league icon
private boolean onLeagueWorld;
@Override
protected void startUp()
{
onLeagueWorld = false;
clientThread.invoke(() ->
{
if (client.getGameState() == GameState.LOGGED_IN)
{
loadLeagueIcon();
onLeagueWorld = isLeagueWorld(client.getWorld());
if (onLeagueWorld)
{
setChatboxName(getNameChatbox());
}
}
});
}
@Override
protected void shutDown()
{
clientThread.invoke(() ->
{
if (client.getGameState() == GameState.LOGGED_IN && onLeagueWorld)
{
setChatboxName(getNameDefault());
}
});
}
@Subscribe
private void onGameStateChanged(GameStateChanged gameStateChanged)
{
if (gameStateChanged.getGameState() == GameState.LOGGED_IN)
{
loadLeagueIcon();
onLeagueWorld = isLeagueWorld(client.getWorld());
}
}
@Subscribe
private void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
{
if (scriptCallbackEvent.getEventName().equals(SCRIPT_EVENT_SET_CHATBOX_INPUT) && onLeagueWorld)
{
setChatboxName(getNameChatbox());
}
}
@Subscribe
private void onChatMessage(ChatMessage chatMessage)
{
if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN)
{
return;
}
switch (chatMessage.getType())
{
case PRIVATECHAT:
case MODPRIVATECHAT:
// Note this is unable to change icon on PMs if they are not a friend or in clan chat
case FRIENDSCHAT:
String name = Text.removeTags(chatMessage.getName());
if (isChatPlayerOnLeague(name))
{
addLeagueIconToMessage(chatMessage);
}
break;
case PUBLICCHAT:
case MODCHAT:
if (onLeagueWorld)
{
addLeagueIconToMessage(chatMessage);
}
break;
}
}
/**
* Adds the League Icon in front of player names chatting from a league world.
*
* @param chatMessage chat message to edit sender name on
*/
private void addLeagueIconToMessage(ChatMessage chatMessage)
{
String name = chatMessage.getName();
if (!name.startsWith(IRONMAN_PREFIX))
{
// don't replace non-ironman icons, like mods
return;
}
name = Text.removeTags(name);
final MessageNode messageNode = chatMessage.getMessageNode();
messageNode.setName(getNameWithIcon(leagueIconOffset, name));
chatMessageManager.update(messageNode);
client.refreshChat();
}
/**
* Update the player name in the chatbox input
*/
private void setChatboxName(String name)
{
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null)
{
String text = chatboxInput.getText();
int idx = text.indexOf(':');
if (idx != -1)
{
String newText = name + text.substring(idx);
chatboxInput.setText(newText);
}
}
}
/**
* Gets the league name, including possible icon, of the local player.
*
* @return String of icon + name
*/
private String getNameChatbox()
{
Player player = client.getLocalPlayer();
if (player != null)
{
return getNameWithIcon(leagueIconOffset, player.getName());
}
return null;
}
/**
* Gets the default name, including possible icon, of the local player.
*
* @return String of icon + name
*/
private String getNameDefault()
{
Player player = client.getLocalPlayer();
if (player == null)
{
return null;
}
int iconIndex;
switch (client.getAccountType())
{
case IRONMAN:
iconIndex = IconID.IRONMAN.getIndex();
break;
case HARDCORE_IRONMAN:
iconIndex = IconID.HARDCORE_IRONMAN.getIndex();
break;
case ULTIMATE_IRONMAN:
iconIndex = IconID.ULTIMATE_IRONMAN.getIndex();
break;
default:
return player.getName();
}
return getNameWithIcon(iconIndex, player.getName());
}
/**
* Get a name formatted with icon
*
* @param iconIndex index of the icon
* @param name name of the player
* @return String of icon + name
*/
private static String getNameWithIcon(int iconIndex, String name)
{
String icon = "<img=" + iconIndex + ">";
return icon + name;
}
/**
* Checks if a player name is a friend or clan member on a league world.
*
* @param name name of player to check.
* @return boolean true/false.
*/
private boolean isChatPlayerOnLeague(String name)
{
ChatPlayer player = getChatPlayerFromName(name);
if (player == null)
{
return false;
}
int world = player.getWorld();
return isLeagueWorld(world);
}
/**
* Checks if the world is a League world.
*
* @param worldNumber number of the world to check.
* @return boolean true/false if it is a league world or not.
*/
private boolean isLeagueWorld(int worldNumber)
{
WorldResult worlds = worldService.getWorlds();
if (worlds == null)
{
return false;
}
World world = worlds.findWorld(worldNumber);
return world != null && world.getTypes().contains(WorldType.LEAGUE);
}
/**
* Loads the league icon into the client.
*/
private void loadLeagueIcon()
{
final IndexedSprite[] modIcons = client.getModIcons();
if (leagueIconOffset != -1 || modIcons == null)
{
return;
}
BufferedImage image = ImageUtil.getResourceStreamFromClass(getClass(), "league_icon.png");
IndexedSprite indexedSprite = ImageUtil.getImageIndexedSprite(image, client);
leagueIconOffset = modIcons.length;
final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + 1);
newModIcons[newModIcons.length - 1] = indexedSprite;
client.setModIcons(newModIcons);
}
/**
* Gets a ChatPlayer object from a clean name by searching clan and friends list.
*
* @param name name of player to find.
* @return ChatPlayer if found, else null.
*/
private ChatPlayer getChatPlayerFromName(String name)
{
if (client.isClanMember(name))
{
return Arrays.stream(client.getClanMembers())
.filter(clanMember -> Text.removeTags(clanMember.getUsername()).equals(name))
.findFirst()
.orElse(null);
}
if (client.isFriended(name, true))
{
return Arrays.stream(client.getFriends())
.filter(friend -> Text.removeTags(friend.getName()).equals(name))
.findFirst()
.orElse(null);
}
return null;
}
}
@@ -105,7 +105,7 @@ public interface LootTrackerConfig extends Config
@ConfigItem( @ConfigItem(
keyName = "syncPanel", keyName = "syncPanel",
name = "Synchronize panel contents", name = "Synchronize panel contents",
description = "Synchronize you local loot tracker with your online (requires being logged in). This means" + description = "Synchronize your local loot tracker with your online (requires being logged in). This means" +
" that panel is filled with portion of your remote data on startup and deleting data in panel deletes them" + " that panel is filled with portion of your remote data on startup and deleting data in panel deletes them" +
" also on server." " also on server."
) )
@@ -25,10 +25,12 @@
*/ */
package net.runelite.client.plugins.music; package net.runelite.client.plugins.music;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.ToIntFunction; import java.util.function.ToIntFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -76,6 +78,10 @@ import net.runelite.client.plugins.PluginDescriptor;
) )
public class MusicPlugin extends Plugin public class MusicPlugin extends Plugin
{ {
private static final Set<Integer> SOURCELESS_PLAYER_SOUNDS = ImmutableSet.of(
SoundEffectID.TELEPORT_VWOOP
);
@Inject @Inject
private Client client; private Client client;
@@ -559,13 +565,14 @@ public class MusicPlugin extends Plugin
private void onAreaSoundEffectPlayed(AreaSoundEffectPlayed areaSoundEffectPlayed) private void onAreaSoundEffectPlayed(AreaSoundEffectPlayed areaSoundEffectPlayed)
{ {
Actor source = areaSoundEffectPlayed.getSource(); Actor source = areaSoundEffectPlayed.getSource();
int soundId = areaSoundEffectPlayed.getSoundId();
if (source == client.getLocalPlayer() if (source == client.getLocalPlayer()
&& musicConfig.muteOwnAreaSounds()) && musicConfig.muteOwnAreaSounds())
{ {
areaSoundEffectPlayed.consume(); areaSoundEffectPlayed.consume();
} }
else if (source != client.getLocalPlayer() else if (source != client.getLocalPlayer()
&& source instanceof Player && (source instanceof Player || (source == null && SOURCELESS_PLAYER_SOUNDS.contains(soundId)))
&& musicConfig.muteOtherAreaSounds()) && musicConfig.muteOtherAreaSounds())
{ {
areaSoundEffectPlayed.consume(); areaSoundEffectPlayed.consume();
@@ -576,6 +583,7 @@ public class MusicPlugin extends Plugin
areaSoundEffectPlayed.consume(); areaSoundEffectPlayed.consume();
} }
else if (source == null else if (source == null
&& !SOURCELESS_PLAYER_SOUNDS.contains(soundId)
&& musicConfig.muteEnvironmentAreaSounds()) && musicConfig.muteEnvironmentAreaSounds())
{ {
areaSoundEffectPlayed.consume(); areaSoundEffectPlayed.consume();
@@ -45,7 +45,6 @@ import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import static net.runelite.api.Constants.REGION_SIZE;
import net.runelite.api.DecorativeObject; import net.runelite.api.DecorativeObject;
import net.runelite.api.GameObject; import net.runelite.api.GameObject;
import net.runelite.api.GameState; import net.runelite.api.GameState;
@@ -350,8 +349,8 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
for (ObjectPoint objectPoint : objectPoints) for (ObjectPoint objectPoint : objectPoints)
{ {
if ((worldPoint.getX() & (REGION_SIZE - 1)) == objectPoint.getRegionX() if (worldPoint.getRegionX() == objectPoint.getRegionX()
&& (worldPoint.getY() & (REGION_SIZE - 1)) == objectPoint.getRegionY()) && worldPoint.getRegionY() == objectPoint.getRegionY())
{ {
// Transform object to get the name which matches against what we've stored // Transform object to get the name which matches against what we've stored
if (objectPoint.getName().equals(getObjectDefinition(object.getId()).getName())) if (objectPoint.getName().equals(getObjectDefinition(object.getId()).getName()))
@@ -446,18 +445,27 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
} }
final int regionId = worldPoint.getRegionID(); final int regionId = worldPoint.getRegionID();
final ObjectPoint point = new ObjectPoint( final ObjectPoint point = new ObjectPoint(
object.getId(),
name, name,
regionId, regionId,
worldPoint.getX() & (REGION_SIZE - 1), worldPoint.getRegionX(),
worldPoint.getY() & (REGION_SIZE - 1), worldPoint.getRegionY(),
client.getPlane()); client.getPlane());
Set<ObjectPoint> objectPoints = points.computeIfAbsent(regionId, k -> new HashSet<>()); Set<ObjectPoint> objectPoints = points.computeIfAbsent(regionId, k -> new HashSet<>());
if (objectPoints.contains(point)) if (objects.remove(object))
{ {
objectPoints.remove(point); // Use object id instead of name to match the object point with this object due to the object name being
objects.remove(object); // able to change because of multilocs.
if (!objectPoints.removeIf(op -> (op.getId() == -1 || op.getId() == object.getId())
&& op.getRegionX() == worldPoint.getRegionX()
&& op.getRegionY() == worldPoint.getRegionY()
&& op.getZ() == worldPoint.getPlane()))
{
log.warn("unable to find object point for unmarked object {}", object.getId());
}
log.debug("Unmarking object: {}", point); log.debug("Unmarking object: {}", point);
} }
else else
@@ -25,11 +25,16 @@
package net.runelite.client.plugins.objectindicators; package net.runelite.client.plugins.objectindicators;
import lombok.Value; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Value @Data
@NoArgsConstructor
@AllArgsConstructor
class ObjectPoint class ObjectPoint
{ {
private int id = -1;
private String name; private String name;
private int regionId; private int regionId;
private int regionX; private int regionX;
@@ -33,7 +33,7 @@ import lombok.Getter;
import net.runelite.client.plugins.raids.solver.Layout; import net.runelite.client.plugins.raids.solver.Layout;
import net.runelite.client.plugins.raids.solver.Room; import net.runelite.client.plugins.raids.solver.Room;
public class Raid class Raid
{ {
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private final RaidRoom[] rooms = new RaidRoom[16]; private final RaidRoom[] rooms = new RaidRoom[16];
@@ -38,7 +38,8 @@ enum TeleportWidget
WidgetInfo.SPELL_LUMBRIDGE_HOME_TELEPORT.getId(), WidgetInfo.SPELL_LUMBRIDGE_HOME_TELEPORT.getId(),
WidgetInfo.SPELL_EDGEVILLE_HOME_TELEPORT.getId(), WidgetInfo.SPELL_EDGEVILLE_HOME_TELEPORT.getId(),
WidgetInfo.SPELL_LUNAR_HOME_TELEPORT.getId(), WidgetInfo.SPELL_LUNAR_HOME_TELEPORT.getId(),
WidgetInfo.SPELL_ARCEUUS_HOME_TELEPORT.getId() WidgetInfo.SPELL_ARCEUUS_HOME_TELEPORT.getId(),
WidgetInfo.SPELL_KOUREND_HOME_TELEPORT.getId()
); );
private static final Collection MINIGAME_TELEPORT_IDS = ImmutableList.of( private static final Collection MINIGAME_TELEPORT_IDS = ImmutableList.of(
WidgetInfo.MINIGAME_TELEPORT_BUTTON.getId() WidgetInfo.MINIGAME_TELEPORT_BUTTON.getId()
@@ -25,23 +25,27 @@
package net.runelite.client.plugins.woodcutting; package net.runelite.client.plugins.woodcutting;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.time.Duration;
import java.util.Map; import java.util.Map;
import lombok.AccessLevel; import javax.annotation.Nullable;
import lombok.Getter; import lombok.Getter;
import static net.runelite.api.ObjectID.REDWOOD; import static net.runelite.api.NullObjectID.NULL_10823;
import static net.runelite.api.ObjectID.REDWOOD_29670; import static net.runelite.api.NullObjectID.NULL_10835;
import net.runelite.api.ObjectID;
import static net.runelite.api.ObjectID.*;
@Getter(AccessLevel.PACKAGE) @Getter
enum Tree enum Tree
{ {
REDWOOD_TREE_SPAWN(REDWOOD, REDWOOD_29670); REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280),
OAK_TREE(Duration.ofMillis(8500), ObjectID.OAK_TREE, OAK_TREE_4540, OAK_10820),
private final int[] treeIds; WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10833, WILLOW_10831),
MAPLE_TREE(Duration.ofSeconds(35), ObjectID.MAPLE_TREE, MAPLE_TREE_10832, MAPLE_TREE_36681),
Tree(final int... treeIds) TEAK_TREE(Duration.ofMillis(8500), TEAK, TEAK_36686),
{ MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688),
this.treeIds = treeIds; YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683),
} MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835),
REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670);
private static final Map<Integer, Tree> TREES; private static final Map<Integer, Tree> TREES;
@@ -60,6 +64,16 @@ enum Tree
TREES = builder.build(); TREES = builder.build();
} }
@Nullable
private final Duration respawnTime;
private final int[] treeIds;
Tree(@org.jetbrains.annotations.Nullable Duration respawnTime, int... treeIds)
{
this.respawnTime = respawnTime;
this.treeIds = treeIds;
}
static Tree findTree(int objectId) static Tree findTree(int objectId)
{ {
return TREES.get(objectId); return TREES.get(objectId);
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* Copyright (c) 2019, David <Dava96@github.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.plugins.woodcutting;
import java.time.Instant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.coords.LocalPoint;
@AllArgsConstructor
@Getter
class TreeRespawn
{
private final Tree tree;
private final LocalPoint location;
private final Instant startTime;
private final int respawnTime;
boolean isExpired()
{
return Instant.now().isAfter(startTime.plusMillis(respawnTime));
}
}
@@ -85,4 +85,15 @@ public interface WoodcuttingConfig extends Config
{ {
return false; return false;
} }
@ConfigItem(
position = 6,
keyName = "showRespawnTimers",
name = "Show respawn timers",
description = "Configures whether to display the respawn timer overlay"
)
default boolean showRespawnTimers()
{
return true;
}
} }
@@ -43,7 +43,6 @@ import net.runelite.client.ui.overlay.components.TitleComponent;
import net.runelite.client.ui.overlay.components.table.TableAlignment; import net.runelite.client.ui.overlay.components.table.TableAlignment;
import net.runelite.client.ui.overlay.components.table.TableComponent; import net.runelite.client.ui.overlay.components.table.TableComponent;
@Singleton @Singleton
class WoodcuttingOverlay extends Overlay class WoodcuttingOverlay extends Overlay
{ {
@@ -51,17 +50,18 @@ class WoodcuttingOverlay extends Overlay
private final Client client; private final Client client;
private final WoodcuttingPlugin plugin; private final WoodcuttingPlugin plugin;
private final WoodcuttingConfig config;
private final XpTrackerService xpTrackerService; private final XpTrackerService xpTrackerService;
private final PanelComponent panelComponent = new PanelComponent(); private final PanelComponent panelComponent = new PanelComponent();
@Inject @Inject
private WoodcuttingOverlay(final Client client, final WoodcuttingPlugin plugin, final XpTrackerService xpTrackerService) private WoodcuttingOverlay(Client client, WoodcuttingPlugin plugin, WoodcuttingConfig config, XpTrackerService xpTrackerService)
{ {
super(plugin); super(plugin);
setPosition(OverlayPosition.TOP_LEFT); setPosition(OverlayPosition.TOP_LEFT);
this.client = client; this.client = client;
this.plugin = plugin; this.plugin = plugin;
this.config = config;
this.xpTrackerService = xpTrackerService; this.xpTrackerService = xpTrackerService;
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Woodcutting overlay")); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Woodcutting overlay"));
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY, WOODCUTTING_RESET, "Woodcutting overlay")); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY, WOODCUTTING_RESET, "Woodcutting overlay"));
@@ -70,7 +70,7 @@ class WoodcuttingOverlay extends Overlay
@Override @Override
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
if (!plugin.isShowWoodcuttingStats()) if (!config.showWoodcuttingStats())
{ {
return null; return null;
} }
@@ -107,7 +107,7 @@ class WoodcuttingOverlay extends Overlay
{ {
tableComponent.addRow("Logs cut:", Integer.toString(actions)); tableComponent.addRow("Logs cut:", Integer.toString(actions));
if (plugin.isShowGPEarned()) if (config.showGPEarned())
{ {
tableComponent.addRow("GP earned:", Integer.toString((plugin.getGpEarned()))); tableComponent.addRow("GP earned:", Integer.toString((plugin.getGpEarned())));
} }
@@ -123,5 +123,4 @@ class WoodcuttingOverlay extends Overlay
return panelComponent.render(graphics); return panelComponent.render(graphics);
} }
} }
@@ -27,17 +27,18 @@ package net.runelite.client.plugins.woodcutting;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameObject; import net.runelite.api.GameObject;
import net.runelite.api.GameState;
import net.runelite.api.ItemID; import net.runelite.api.ItemID;
import net.runelite.api.MenuOpcode; import net.runelite.api.MenuOpcode;
import net.runelite.api.Player; import net.runelite.api.Player;
@@ -51,7 +52,6 @@ import net.runelite.api.events.GameTick;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.OverlayMenuClicked;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
@@ -64,14 +64,21 @@ import net.runelite.client.ui.overlay.OverlayMenuEntry;
@PluginDescriptor( @PluginDescriptor(
name = "Woodcutting", name = "Woodcutting",
description = "Show woodcutting statistics and/or bird nest notifications", description = "Show woodcutting statistics and/or bird nest notifications",
tags = {"birds", "nest", "notifications", "overlay", "skilling", "wc"} tags = {"birds", "nest", "notifications", "overlay", "skilling", "wc"},
enabledByDefault = false
) )
@Singleton
@PluginDependency(XpTrackerPlugin.class) @PluginDependency(XpTrackerPlugin.class)
@Slf4j
public class WoodcuttingPlugin extends Plugin public class WoodcuttingPlugin extends Plugin
{ {
private static final Pattern WOOD_CUT_PATTERN = Pattern.compile("You get (?:some|an)[\\w ]+(?:logs?|mushrooms)\\."); private static final Pattern WOOD_CUT_PATTERN = Pattern.compile("You get (?:some|an)[\\w ]+(?:logs?|mushrooms)\\.");
@Getter
private final Set<GameObject> treeObjects = new HashSet<>();
@Getter(AccessLevel.PACKAGE)
private final List<TreeRespawn> respawns = new ArrayList<>();
@Inject @Inject
private Notifier notifier; private Notifier notifier;
@@ -93,24 +100,13 @@ public class WoodcuttingPlugin extends Plugin
@Inject @Inject
private ItemManager itemManager; private ItemManager itemManager;
@Getter(AccessLevel.PACKAGE) @Getter
private WoodcuttingSession session; private WoodcuttingSession session;
@Getter(AccessLevel.PACKAGE) @Getter
private Axe axe; private Axe axe;
@Getter(AccessLevel.PACKAGE) private boolean recentlyLoggedIn;
private final Set<GameObject> treeObjects = new HashSet<>();
private int statTimeout;
boolean showNestNotification;
@Getter(AccessLevel.PACKAGE)
private boolean showWoodcuttingStats;
@Getter(AccessLevel.PACKAGE)
private boolean showRedwoodTrees;
@Getter(AccessLevel.PACKAGE)
private boolean showGPEarned;
private int treeTypeID; private int treeTypeID;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private int gpEarned; private int gpEarned;
@@ -122,19 +118,18 @@ public class WoodcuttingPlugin extends Plugin
} }
@Override @Override
protected void startUp() protected void startUp() throws Exception
{ {
updateConfig();
overlayManager.add(overlay); overlayManager.add(overlay);
overlayManager.add(treesOverlay); overlayManager.add(treesOverlay);
} }
@Override @Override
protected void shutDown() protected void shutDown() throws Exception
{ {
overlayManager.remove(overlay); overlayManager.remove(overlay);
overlayManager.remove(treesOverlay); overlayManager.remove(treesOverlay);
respawns.clear();
treeObjects.clear(); treeObjects.clear();
session = null; session = null;
axe = null; axe = null;
@@ -155,12 +150,16 @@ public class WoodcuttingPlugin extends Plugin
@Subscribe @Subscribe
private void onGameTick(GameTick gameTick) private void onGameTick(GameTick gameTick)
{ {
recentlyLoggedIn = false;
respawns.removeIf(TreeRespawn::isExpired);
if (session == null || session.getLastLogCut() == null) if (session == null || session.getLastLogCut() == null)
{ {
return; return;
} }
Duration statTimeout = Duration.ofMinutes(this.statTimeout); Duration statTimeout = Duration.ofMinutes(config.statTimeout());
Duration sinceCut = Duration.between(session.getLastLogCut(), Instant.now()); Duration sinceCut = Duration.between(session.getLastLogCut(), Instant.now());
if (sinceCut.compareTo(statTimeout) >= 0) if (sinceCut.compareTo(statTimeout) >= 0)
@@ -189,13 +188,90 @@ public class WoodcuttingPlugin extends Plugin
gpEarned += itemManager.getItemPrice(treeTypeID); gpEarned += itemManager.getItemPrice(treeTypeID);
} }
if (event.getMessage().contains("A bird's nest falls out of the tree") && this.showNestNotification) if (event.getMessage().contains("A bird's nest falls out of the tree") && config.showNestNotification())
{ {
notifier.notify("A bird nest has spawned!"); notifier.notify("A bird nest has spawned!");
} }
} }
} }
@Subscribe
private void onGameObjectSpawned(final GameObjectSpawned event)
{
GameObject gameObject = event.getGameObject();
Tree tree = Tree.findTree(gameObject.getId());
if (tree == Tree.REDWOOD)
{
treeObjects.add(gameObject);
}
}
@Subscribe
private void onGameObjectDespawned(final GameObjectDespawned event)
{
final GameObject object = event.getGameObject();
Tree tree = Tree.findTree(object.getId());
if (tree != null)
{
if (tree.getRespawnTime() != null && !recentlyLoggedIn)
{
log.debug("Adding respawn timer for {} tree at {}", tree, object.getLocalLocation());
TreeRespawn treeRespawn = new TreeRespawn(tree, object.getLocalLocation(), Instant.now(), (int) tree.getRespawnTime().toMillis());
respawns.add(treeRespawn);
}
if (tree == Tree.REDWOOD)
{
treeObjects.remove(event.getGameObject());
}
}
}
@Subscribe
private void onGameObjectChanged(final GameObjectChanged event)
{
treeObjects.remove(event.getGameObject());
}
@Subscribe
private void onGameStateChanged(final GameStateChanged event)
{
switch (event.getGameState())
{
case LOADING:
case HOPPING:
respawns.clear();
treeObjects.clear();
break;
case LOGGED_IN:
// After login trees that are depleted will be changed,
// wait for the next game tick before watching for
// trees to despawn
recentlyLoggedIn = true;
break;
}
}
@Subscribe
private void onAnimationChanged(final AnimationChanged event)
{
Player local = client.getLocalPlayer();
if (event.getActor() != local)
{
return;
}
int animId = local.getAnimation();
Axe axe = Axe.findAxeByAnimId(animId);
if (axe != null)
{
this.axe = axe;
}
}
private void typeOfLogCut(String message) private void typeOfLogCut(String message)
{ {
if (message.contains("mushrooms.")) if (message.contains("mushrooms."))
@@ -239,75 +315,4 @@ public class WoodcuttingPlugin extends Plugin
treeTypeID = ItemID.LOGS; treeTypeID = ItemID.LOGS;
} }
} }
@Subscribe
private void onGameObjectSpawned(final GameObjectSpawned event)
{
GameObject gameObject = event.getGameObject();
Tree tree = Tree.findTree(gameObject.getId());
if (tree != null)
{
treeObjects.add(gameObject);
}
}
@Subscribe
private void onGameObjectDespawned(final GameObjectDespawned event)
{
treeObjects.remove(event.getGameObject());
}
@Subscribe
private void onGameObjectChanged(final GameObjectChanged event)
{
treeObjects.remove(event.getGameObject());
}
@Subscribe
private void onGameStateChanged(final GameStateChanged event)
{
if (event.getGameState() != GameState.LOGGED_IN)
{
treeObjects.clear();
}
}
@Subscribe
private void onAnimationChanged(final AnimationChanged event)
{
Player local = client.getLocalPlayer();
if (event.getActor() != local)
{
return;
}
int animId = local.getAnimation();
Axe axe = Axe.findAxeByAnimId(animId);
if (axe != null)
{
this.axe = axe;
}
}
@Subscribe
private void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals("woodcutting"))
{
return;
}
updateConfig();
}
private void updateConfig()
{
this.statTimeout = config.statTimeout();
this.showNestNotification = config.showNestNotification();
this.showWoodcuttingStats = config.showWoodcuttingStats();
this.showRedwoodTrees = config.showRedwoodTrees();
this.showGPEarned = config.showGPEarned();
}
} }
@@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com> * Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2019, David <Dava96@github.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -25,29 +26,36 @@
*/ */
package net.runelite.client.plugins.woodcutting; package net.runelite.client.plugins.woodcutting;
import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.time.Instant;
import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameObject; import net.runelite.api.GameObject;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.ProgressPieComponent;
@Singleton
class WoodcuttingTreesOverlay extends Overlay class WoodcuttingTreesOverlay extends Overlay
{ {
private final Client client; private final Client client;
private final WoodcuttingConfig config;
private final ItemManager itemManager; private final ItemManager itemManager;
private final WoodcuttingPlugin plugin; private final WoodcuttingPlugin plugin;
@Inject @Inject
private WoodcuttingTreesOverlay(final Client client, final ItemManager itemManager, final WoodcuttingPlugin plugin) private WoodcuttingTreesOverlay(final Client client, final WoodcuttingConfig config, final ItemManager itemManager, final WoodcuttingPlugin plugin)
{ {
this.client = client; this.client = client;
this.config = config;
this.itemManager = itemManager; this.itemManager = itemManager;
this.plugin = plugin; this.plugin = plugin;
setLayer(OverlayLayer.ABOVE_SCENE); setLayer(OverlayLayer.ABOVE_SCENE);
@@ -57,15 +65,22 @@ class WoodcuttingTreesOverlay extends Overlay
@Override @Override
public Dimension render(Graphics2D graphics) public Dimension render(Graphics2D graphics)
{ {
if (plugin.getSession() == null || !plugin.isShowRedwoodTrees()) renderAxes(graphics);
{ renderTimers(graphics);
return null; return null;
} }
private void renderAxes(Graphics2D graphics)
{
if (plugin.getSession() == null || !config.showRedwoodTrees())
{
return;
}
Axe axe = plugin.getAxe(); Axe axe = plugin.getAxe();
if (axe == null) if (axe == null)
{ {
return null; return;
} }
for (GameObject treeObject : plugin.getTreeObjects()) for (GameObject treeObject : plugin.getTreeObjects())
@@ -75,7 +90,34 @@ class WoodcuttingTreesOverlay extends Overlay
OverlayUtil.renderImageLocation(client, graphics, treeObject.getLocalLocation(), itemManager.getImage(axe.getItemId()), 120); OverlayUtil.renderImageLocation(client, graphics, treeObject.getLocalLocation(), itemManager.getImage(axe.getItemId()), 120);
} }
} }
}
return null; private void renderTimers(Graphics2D graphics)
{
List<TreeRespawn> respawns = plugin.getRespawns();
if (respawns.isEmpty() || !config.showRespawnTimers())
{
return;
}
Instant now = Instant.now();
for (TreeRespawn treeRespawn : respawns)
{
LocalPoint loc = treeRespawn.getLocation();
float percent = (now.toEpochMilli() - treeRespawn.getStartTime().toEpochMilli()) / (float) treeRespawn.getRespawnTime();
Point point = Perspective.localToCanvas(client, loc, client.getPlane());
if (point == null || percent > 1.0f)
{
continue;
}
ProgressPieComponent ppc = new ProgressPieComponent();
ppc.setBorderColor(Color.ORANGE);
ppc.setFill(Color.YELLOW);
ppc.setPosition(point);
ppc.setProgress(percent);
ppc.render(graphics);
}
} }
} }
@@ -30,11 +30,9 @@ import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ObjectArrays; import com.google.common.collect.ObjectArrays;
import com.google.inject.Provides; import com.google.inject.Provides;
import io.reactivex.schedulers.Schedulers;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Comparator;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -75,6 +73,8 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.Keybind; import net.runelite.client.config.Keybind;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.WorldsFetch;
import net.runelite.client.game.WorldService;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
@@ -87,7 +87,6 @@ import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.WorldUtil; import net.runelite.client.util.WorldUtil;
import net.runelite.client.util.ping.Ping; import net.runelite.client.util.ping.Ping;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient;
import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldResult;
import net.runelite.http.api.worlds.WorldType; import net.runelite.http.api.worlds.WorldType;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
@@ -126,9 +125,6 @@ public class WorldHopperPlugin extends Plugin
@Inject @Inject
private ChatMessageManager chatMessageManager; private ChatMessageManager chatMessageManager;
@Inject
private ScheduledExecutorService executorService;
@Inject @Inject
private WorldHopperConfig config; private WorldHopperConfig config;
@@ -139,7 +135,7 @@ public class WorldHopperPlugin extends Plugin
private WorldHopperPingOverlay worldHopperOverlay; private WorldHopperPingOverlay worldHopperOverlay;
@Inject @Inject
private WorldClient worldClient; private WorldService worldService;
private ScheduledExecutorService hopperExecutorService; private ScheduledExecutorService hopperExecutorService;
@@ -154,11 +150,9 @@ public class WorldHopperPlugin extends Plugin
private int favoriteWorld1, favoriteWorld2; private int favoriteWorld1, favoriteWorld2;
private ScheduledFuture<?> worldResultFuture, pingFuture, currPingFuture; private ScheduledFuture<?> pingFuture, currPingFuture;
private WorldResult worldResult;
private int currentWorld; private int currentWorld;
private Instant lastFetch; private Instant lastFetch;
private boolean firstRun;
private Keybind previousKey; private Keybind previousKey;
private Keybind nextKey; private Keybind nextKey;
@@ -203,7 +197,6 @@ public class WorldHopperPlugin extends Plugin
{ {
updateConfig(); updateConfig();
firstRun = true;
currentPing = -1; currentPing = -1;
keyManager.registerKeyListener(previousKeyListener); keyManager.registerKeyListener(previousKeyListener);
@@ -231,12 +224,15 @@ public class WorldHopperPlugin extends Plugin
// The plugin has its own executor for pings, as it blocks for a long time // The plugin has its own executor for pings, as it blocks for a long time
hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor());
// On first run this schedules an initial ping on hopperExecutorService // Run the first-run ping
worldResultFuture = executorService.scheduleAtFixedRate(this::tick, 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES); hopperExecutorService.execute(this::pingInitialWorlds);
// Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway // Give some initial delay - this won't run until after pingInitialWorlds finishes from tick() anyway
pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS); pingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingNextWorld, 15, 3, TimeUnit.SECONDS);
currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS); currPingFuture = hopperExecutorService.scheduleWithFixedDelay(this::pingCurrentWorld, 15, 1, TimeUnit.SECONDS);
// populate initial world list
updateList();
} }
@Override @Override
@@ -253,11 +249,6 @@ public class WorldHopperPlugin extends Plugin
keyManager.unregisterKeyListener(previousKeyListener); keyManager.unregisterKeyListener(previousKeyListener);
keyManager.unregisterKeyListener(nextKeyListener); keyManager.unregisterKeyListener(nextKeyListener);
worldResultFuture.cancel(true);
worldResultFuture = null;
worldResult = null;
lastFetch = null;
clientToolbar.removeNavigation(navButton); clientToolbar.removeNavigation(navButton);
hopperExecutorService.shutdown(); hopperExecutorService.shutdown();
@@ -393,6 +384,7 @@ public class WorldHopperPlugin extends Plugin
// Don't add entry if user is offline // Don't add entry if user is offline
ChatPlayer player = getChatPlayerFromName(event.getTarget()); ChatPlayer player = getChatPlayerFromName(event.getTarget());
WorldResult worldResult = worldService.getWorlds();
if (player == null || player.getWorld() == 0 || player.getWorld() == client.getWorld() if (player == null || player.getWorld() == 0 || player.getWorld() == client.getWorld()
|| worldResult == null) || worldResult == null)
@@ -484,26 +476,6 @@ public class WorldHopperPlugin extends Plugin
this.lastFetch = Instant.now(); // This counts as a fetch as it updates populations this.lastFetch = Instant.now(); // This counts as a fetch as it updates populations
} }
private void tick()
{
Instant now = Instant.now();
if (lastFetch != null && now.toEpochMilli() - lastFetch.toEpochMilli() < TICK_THROTTLE)
{
log.debug("Throttling world refresh tick");
return;
}
fetchWorlds();
// Ping worlds once at startup
if (firstRun)
{
firstRun = false;
// On first run we ping all of the worlds at once to initialize the ping values
hopperExecutorService.execute(this::pingInitialWorlds);
}
}
void refresh() void refresh()
{ {
Instant now = Instant.now(); Instant now = Instant.now();
@@ -513,41 +485,31 @@ public class WorldHopperPlugin extends Plugin
return; return;
} }
fetchWorlds(); lastFetch = now;
worldService.refresh();
} }
private void fetchWorlds() @Subscribe
public void onWorldsFetch(WorldsFetch worldsFetch)
{ {
log.debug("Fetching worlds");
worldClient.lookupWorlds()
.subscribeOn(Schedulers.io())
.take(1)
.subscribe(
(worldResult) ->
{
if (worldResult != null)
{
worldResult.getWorlds().sort(Comparator.comparingInt(World::getId));
this.worldResult = worldResult;
this.lastFetch = Instant.now();
updateList(); updateList();
} }
},
(ex) -> log.warn("Error looking up worlds", ex)
);
}
/** /**
* This method ONLY updates the list's UI, not the actual world list and data it displays. * This method ONLY updates the list's UI, not the actual world list and data it displays.
*/ */
private void updateList() private void updateList()
{
WorldResult worldResult = worldService.getWorlds();
if (worldResult != null)
{ {
SwingUtilities.invokeLater(() -> panel.populate(worldResult.getWorlds())); SwingUtilities.invokeLater(() -> panel.populate(worldResult.getWorlds()));
} }
}
private void hop(boolean previous) private void hop(boolean previous)
{ {
WorldResult worldResult = worldService.getWorlds();
if (worldResult == null || client.getGameState() != GameState.LOGGED_IN) if (worldResult == null || client.getGameState() != GameState.LOGGED_IN)
{ {
return; return;
@@ -658,6 +620,7 @@ public class WorldHopperPlugin extends Plugin
private void hop(int worldId) private void hop(int worldId)
{ {
WorldResult worldResult = worldService.getWorlds();
// Don't try to hop if the world doesn't exist // Don't try to hop if the world doesn't exist
World world = worldResult.findWorld(worldId); World world = worldResult.findWorld(worldId);
if (world == null) if (world == null)
@@ -801,6 +764,7 @@ public class WorldHopperPlugin extends Plugin
*/ */
private void pingInitialWorlds() private void pingInitialWorlds()
{ {
WorldResult worldResult = worldService.getWorlds();
if (worldResult == null || !this.showSidebar || !this.ping) if (worldResult == null || !this.showSidebar || !this.ping)
{ {
return; return;
@@ -838,6 +802,7 @@ public class WorldHopperPlugin extends Plugin
*/ */
private void pingNextWorld() private void pingNextWorld()
{ {
WorldResult worldResult = worldService.getWorlds();
if (worldResult == null || !this.showSidebar || !this.ping) if (worldResult == null || !this.showSidebar || !this.ping)
{ {
return; return;
@@ -874,6 +839,7 @@ public class WorldHopperPlugin extends Plugin
*/ */
private void pingCurrentWorld() private void pingCurrentWorld()
{ {
WorldResult worldResult = worldService.getWorlds();
// There is no reason to ping the current world if not logged in, as the overlay doesn't draw // There is no reason to ping the current world if not logged in, as the overlay doesn't draw
if (worldResult == null || !this.displayPing || client.getGameState() != GameState.LOGGED_IN) if (worldResult == null || !this.displayPing || client.getGameState() != GameState.LOGGED_IN)
{ {
@@ -70,7 +70,8 @@ class ClientConfigLoader
supplier = new HostSupplier(); supplier = new HostSupplier();
} }
url = supplier.get(); String host = supplier.get();
url = url.newBuilder().host(host).build();
continue; continue;
} }
@@ -1,6 +1,5 @@
/* /*
* Copyright (c) 2019 Abex * Copyright (c) 2019 Abex
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -25,8 +24,10 @@
*/ */
package net.runelite.client.rs; package net.runelite.client.rs;
import java.io.IOException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.Random; import java.util.Random;
@@ -36,39 +37,44 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldClient; import net.runelite.http.api.worlds.WorldClient;
import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldType;
import okhttp3.HttpUrl;
@Slf4j @Slf4j
class HostSupplier implements Supplier<HttpUrl> class HostSupplier implements Supplier<String>
{ {
private final Random random = new Random(); private final Random random = new Random(System.nanoTime());
private final Queue<HttpUrl> hosts = new ArrayDeque<>(); private Queue<String> hosts = new ArrayDeque<>();
@Override @Override
public HttpUrl get() public String get()
{ {
if (!hosts.isEmpty()) if (!hosts.isEmpty())
{ {
return hosts.poll(); return hosts.poll();
} }
List<HttpUrl> newHosts = new WorldClient(RuneLiteAPI.CLIENT) try
{
List<String> newHosts = new WorldClient(RuneLiteAPI.CLIENT)
.lookupWorlds() .lookupWorlds()
.map(WorldResult::getWorlds) .getWorlds()
.blockingSingle()
.stream() .stream()
.filter(w -> w.getTypes().isEmpty() || EnumSet.of(WorldType.MEMBERS).equals(w.getTypes()))
.map(World::getAddress) .map(World::getAddress)
.map(HttpUrl::parse)
.collect(Collectors.toList()); .collect(Collectors.toList());
Collections.shuffle(newHosts, random); Collections.shuffle(newHosts, random);
hosts.addAll(newHosts.subList(0, 16)); hosts.addAll(newHosts.subList(0, 16));
}
catch (IOException e)
{
log.warn("Unable to retrieve world list", e);
}
while (hosts.size() < 2) while (hosts.size() < 2)
{ {
hosts.add(HttpUrl.parse("oldschool" + (random.nextInt(50) + 1) + ".runescape.COM")); hosts.add("oldschool" + (random.nextInt(50) + 1) + ".runescape.COM");
} }
return hosts.poll(); return hosts.poll();
@@ -1024,9 +1024,9 @@ public class ClientUI
setOpacityMethod.invoke(peerField.get(frame), opacity); setOpacityMethod.invoke(peerField.get(frame), opacity);
} }
catch (NoSuchFieldException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InvocationTargetException e) catch (NoSuchFieldException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InvocationTargetException | NullPointerException e)
{ {
e.printStackTrace(); // e.printStackTrace();
} }
}); });
} }
@@ -0,0 +1,72 @@
/*
* 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.util;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectUtil
{
private ReflectUtil()
{
}
public static MethodHandles.Lookup privateLookupIn(Class clazz)
{
try
{
// Java 9+ has privateLookupIn method on MethodHandles, but since we are shipping and using Java 8
// we need to access it via reflection. This is preferred way because it's Java 9+ public api and is
// likely to not change
final Method privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
return (MethodHandles.Lookup) privateLookupIn.invoke(null, clazz, MethodHandles.lookup());
}
catch (InvocationTargetException | IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (NoSuchMethodException e)
{
try
{
// In Java 8 we first do standard lookupIn class
final MethodHandles.Lookup lookupIn = MethodHandles.lookup().in(clazz);
// and then we mark it as trusted for private lookup via reflection on private field
final Field modes = MethodHandles.Lookup.class.getDeclaredField("allowedModes");
modes.setAccessible(true);
modes.setInt(lookupIn, -1); // -1 == TRUSTED
return lookupIn;
}
catch (ReflectiveOperationException ex)
{
throw new RuntimeException(ex);
}
}
}
}
@@ -8025,7 +8025,8 @@
], ],
"rune pouch": [ "rune pouch": [
12791, 12791,
23650 23650,
24416
], ],
"nest box": [ "nest box": [
12792, 12792,
Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

@@ -48,6 +48,12 @@
"name": "Gold Ring", "name": "Gold Ring",
"xp": 15 "xp": 15
}, },
{
"level": 5,
"icon": 21512,
"name": "Bird House",
"xp": 15
},
{ {
"level": 6, "level": 6,
"icon": 1654, "icon": 1654,
@@ -120,6 +126,12 @@
"name": "Leather Body", "name": "Leather Body",
"xp": 25 "xp": 25
}, },
{
"level": 15,
"icon": 21515,
"name": "Oak Bird House",
"xp": 20
},
{ {
"level": 16, "level": 16,
"icon": 1613, "icon": 1613,
@@ -216,6 +228,12 @@
"name": "Jade Necklace", "name": "Jade Necklace",
"xp": 54 "xp": 54
}, },
{
"level": 25,
"icon": 21518,
"name": "Willow Bird House",
"xp": 25
},
{ {
"level": 26, "level": 26,
"icon": 6209, "icon": 6209,
@@ -318,6 +336,12 @@
"name": "Broodoo shield", "name": "Broodoo shield",
"xp": 100 "xp": 100
}, },
{
"level": 35,
"icon": 21521,
"name": "Teak Bird House",
"xp": 30
},
{ {
"level": 36, "level": 36,
"icon": 5376, "icon": 5376,
@@ -384,6 +408,12 @@
"name": "Snakeskin boots", "name": "Snakeskin boots",
"xp": 30 "xp": 30
}, },
{
"level": 45,
"icon": 22192,
"name": "Maple Bird House",
"xp": 35
},
{ {
"level": 46, "level": 46,
"icon": 567, "icon": 567,
@@ -414,6 +444,12 @@
"name": "Ruby Amulet (U)", "name": "Ruby Amulet (U)",
"xp": 85 "xp": 85
}, },
{
"level": 50,
"icon": 22195,
"name": "Mahogany Bird House",
"xp": 40
},
{ {
"level": 51, "level": 51,
"icon": 6324, "icon": 6324,
@@ -480,6 +516,12 @@
"name": "Green D'hide Chaps", "name": "Green D'hide Chaps",
"xp": 124 "xp": 124
}, },
{
"level": 60,
"icon": 22198,
"name": "Yew Bird House",
"xp": 45
},
{ {
"level": 62, "level": 62,
"icon": 1393, "icon": 1393,
@@ -570,6 +612,12 @@
"name": "Red D'hide Chaps", "name": "Red D'hide Chaps",
"xp": 156 "xp": 156
}, },
{
"level": 75,
"icon": 22201,
"name": "Magic Bird House",
"xp": 50
},
{ {
"level": 76, "level": 76,
"icon": 22281, "icon": 22281,
@@ -666,6 +714,12 @@
"name": "Onyx Amulet (U)", "name": "Onyx Amulet (U)",
"xp": 165 "xp": 165
}, },
{
"level": 90,
"icon": 22204,
"name": "Redwood Bird House",
"xp": 55
},
{ {
"level": 92, "level": 92,
"icon": 19535, "icon": 19535,
@@ -1 +1 @@
32FBC48F8C6D8E62E02BCF09F444BA036F76133B6596396F0AB9E474687D9F3F C85469C2529D794C523505679F14AA20E988513E8FBAF249E41F4760382B4BBB
@@ -25,7 +25,7 @@ LABEL9:
iload 1 iload 1
movecoord movecoord
set_varc_int 207 set_varc_int 207
jump LABEL216 jump LABEL227
LABEL16: LABEL16:
iconst 105 iconst 105
iconst 83 iconst 83
@@ -43,7 +43,7 @@ LABEL25:
iload 1 iload 1
movecoord movecoord
set_varc_int 208 set_varc_int 208
jump LABEL216 jump LABEL227
LABEL32: LABEL32:
iconst 105 iconst 105
iconst 83 iconst 83
@@ -61,7 +61,7 @@ LABEL41:
iload 1 iload 1
movecoord movecoord
set_varc_int 209 set_varc_int 209
jump LABEL216 jump LABEL227
LABEL48: LABEL48:
iconst 105 iconst 105
iconst 83 iconst 83
@@ -79,7 +79,7 @@ LABEL57:
iload 1 iload 1
movecoord movecoord
set_varc_int 210 set_varc_int 210
jump LABEL216 jump LABEL227
LABEL64: LABEL64:
iconst 105 iconst 105
iconst 83 iconst 83
@@ -97,7 +97,7 @@ LABEL73:
iload 1 iload 1
movecoord movecoord
set_varc_int 211 set_varc_int 211
jump LABEL216 jump LABEL227
LABEL80: LABEL80:
iconst 105 iconst 105
iconst 83 iconst 83
@@ -115,7 +115,7 @@ LABEL89:
iload 1 iload 1
movecoord movecoord
set_varc_int 212 set_varc_int 212
jump LABEL216 jump LABEL227
LABEL96: LABEL96:
iconst 105 iconst 105
iconst 83 iconst 83
@@ -133,13 +133,27 @@ LABEL105:
iload 1 iload 1
movecoord movecoord
set_varc_int 213 set_varc_int 213
jump LABEL216 jump LABEL227
LABEL112: LABEL112:
iload 0
iconst 3
if_icmpeq LABEL116
jump LABEL123
LABEL116:
iload 1
iconst 20000001
if_icmpeq LABEL120
jump LABEL123
LABEL120:
iconst 269500481
set_varc_int 207
jump LABEL227
LABEL123:
get_varc_int 207 get_varc_int 207
iconst -1 iconst -1
if_icmpeq LABEL116 if_icmpeq LABEL127
jump LABEL127 jump LABEL138
LABEL116: LABEL127:
iconst 0 iconst 0
iconst 83 iconst 83
iconst 105 iconst 105
@@ -150,13 +164,13 @@ LABEL116:
iload 1 iload 1
movecoord movecoord
set_varc_int 207 set_varc_int 207
jump LABEL216 jump LABEL227
LABEL127: LABEL138:
get_varc_int 208 get_varc_int 208
iconst -1 iconst -1
if_icmpeq LABEL131 if_icmpeq LABEL142
jump LABEL142 jump LABEL153
LABEL131: LABEL142:
iconst 0 iconst 0
iconst 83 iconst 83
iconst 105 iconst 105
@@ -167,13 +181,13 @@ LABEL131:
iload 1 iload 1
movecoord movecoord
set_varc_int 208 set_varc_int 208
jump LABEL216 jump LABEL227
LABEL142: LABEL153:
get_varc_int 209 get_varc_int 209
iconst -1 iconst -1
if_icmpeq LABEL146 if_icmpeq LABEL157
jump LABEL157 jump LABEL168
LABEL146: LABEL157:
iconst 0 iconst 0
iconst 83 iconst 83
iconst 105 iconst 105
@@ -184,13 +198,13 @@ LABEL146:
iload 1 iload 1
movecoord movecoord
set_varc_int 209 set_varc_int 209
jump LABEL216 jump LABEL227
LABEL157: LABEL168:
get_varc_int 210 get_varc_int 210
iconst -1 iconst -1
if_icmpeq LABEL161 if_icmpeq LABEL172
jump LABEL172 jump LABEL183
LABEL161: LABEL172:
iconst 0 iconst 0
iconst 83 iconst 83
iconst 105 iconst 105
@@ -201,13 +215,13 @@ LABEL161:
iload 1 iload 1
movecoord movecoord
set_varc_int 210 set_varc_int 210
jump LABEL216 jump LABEL227
LABEL172: LABEL183:
get_varc_int 211 get_varc_int 211
iconst -1 iconst -1
if_icmpeq LABEL176 if_icmpeq LABEL187
jump LABEL187 jump LABEL198
LABEL176: LABEL187:
iconst 0 iconst 0
iconst 83 iconst 83
iconst 105 iconst 105
@@ -218,13 +232,13 @@ LABEL176:
iload 1 iload 1
movecoord movecoord
set_varc_int 211 set_varc_int 211
jump LABEL216 jump LABEL227
LABEL187: LABEL198:
get_varc_int 212 get_varc_int 212
iconst -1 iconst -1
if_icmpeq LABEL191 if_icmpeq LABEL202
jump LABEL202 jump LABEL213
LABEL191: LABEL202:
iconst 0 iconst 0
iconst 83 iconst 83
iconst 105 iconst 105
@@ -235,13 +249,13 @@ LABEL191:
iload 1 iload 1
movecoord movecoord
set_varc_int 212 set_varc_int 212
jump LABEL216 jump LABEL227
LABEL202: LABEL213:
get_varc_int 213 get_varc_int 213
iconst -1 iconst -1
if_icmpeq LABEL206 if_icmpeq LABEL217
jump LABEL216 jump LABEL227
LABEL206: LABEL217:
iconst 0 iconst 0
iconst 83 iconst 83
iconst 105 iconst 105
@@ -252,5 +266,5 @@ LABEL206:
iload 1 iload 1
movecoord movecoord
set_varc_int 213 set_varc_int 213
LABEL216: LABEL227:
return return
@@ -1 +1 @@
AAA12D64549A1E4573B242AD9D53D8B1A436B947CF55BACBA660812411750E20 A4641387DC1A542BDEB6F3728D23944F968EF2FD3EA2868B5B6AAF6961D0C6E0
@@ -30,13 +30,25 @@ LABEL9:
iload 0 iload 0
iconst 1 iconst 1
if_icmpeq LABEL25 if_icmpeq LABEL25
jump LABEL71 jump LABEL81
LABEL25: LABEL25:
get_varc_int 207 get_varc_int 207
iconst -1 iconst -1
if_icmpne LABEL29 if_icmpne LABEL29
jump LABEL70 jump LABEL80
LABEL29: LABEL29:
get_varc_int 207
iconst 269500481
if_icmpeq LABEL33
jump LABEL39
LABEL33:
iload 1
iload 3
iload 8
iload 9
invoke 997
jump LABEL65
LABEL39:
iload 35 iload 35
iconst 105 iconst 105
iconst 83 iconst 83
@@ -52,20 +64,20 @@ LABEL29:
iload 35 iload 35
get_array_int get_array_int
iconst -1 iconst -1
if_icmpne LABEL46 if_icmpne LABEL56
jump LABEL55 jump LABEL65
LABEL46: LABEL56:
iload 35 iload 35
get_array_int 1 get_array_int 1
iconst 0 iconst 0
if_icmpgt LABEL51 if_icmpgt LABEL61
jump LABEL55 jump LABEL65
LABEL51: LABEL61:
iload 35 iload 35
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL55: LABEL65:
get_varc_int 208 get_varc_int 208
get_varc_int 209 get_varc_int 209
get_varc_int 210 get_varc_int 210
@@ -81,9 +93,9 @@ LABEL55:
set_varc_int 208 set_varc_int 208
set_varc_int 207 set_varc_int 207
jump LABEL25 jump LABEL25
LABEL70: LABEL80:
jump LABEL508 jump LABEL518
LABEL71: LABEL81:
sconst "newXpDrop" sconst "newXpDrop"
runelite_callback runelite_callback
iconst 10 iconst 10
@@ -93,9 +105,9 @@ LABEL71:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL80 if_icmpgt LABEL90
jump LABEL90 jump LABEL100
LABEL80: LABEL90:
iload 35 iload 35
iconst 10 iconst 10
set_array_int set_array_int
@@ -106,7 +118,7 @@ LABEL80:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL90: LABEL100:
iconst 0 iconst 0
stat_xp stat_xp
iload 11 iload 11
@@ -114,9 +126,9 @@ LABEL90:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL99 if_icmpgt LABEL109
jump LABEL109 jump LABEL119
LABEL99: LABEL109:
iload 35 iload 35
iconst 0 iconst 0
set_array_int set_array_int
@@ -127,7 +139,7 @@ LABEL99:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL109: LABEL119:
iconst 2 iconst 2
stat_xp stat_xp
iload 12 iload 12
@@ -135,9 +147,9 @@ LABEL109:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL118 if_icmpgt LABEL128
jump LABEL128 jump LABEL138
LABEL118: LABEL128:
iload 35 iload 35
iconst 2 iconst 2
set_array_int set_array_int
@@ -148,7 +160,7 @@ LABEL118:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL128: LABEL138:
iconst 4 iconst 4
stat_xp stat_xp
iload 13 iload 13
@@ -156,9 +168,9 @@ LABEL128:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL137 if_icmpgt LABEL147
jump LABEL147 jump LABEL157
LABEL137: LABEL147:
iload 35 iload 35
iconst 4 iconst 4
set_array_int set_array_int
@@ -169,7 +181,7 @@ LABEL137:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL147: LABEL157:
iconst 6 iconst 6
stat_xp stat_xp
iload 14 iload 14
@@ -177,9 +189,9 @@ LABEL147:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL156 if_icmpgt LABEL166
jump LABEL166 jump LABEL176
LABEL156: LABEL166:
iload 35 iload 35
iconst 6 iconst 6
set_array_int set_array_int
@@ -190,7 +202,7 @@ LABEL156:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL166: LABEL176:
iconst 1 iconst 1
stat_xp stat_xp
iload 15 iload 15
@@ -198,9 +210,9 @@ LABEL166:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL175 if_icmpgt LABEL185
jump LABEL185 jump LABEL195
LABEL175: LABEL185:
iload 35 iload 35
iconst 1 iconst 1
set_array_int set_array_int
@@ -211,7 +223,7 @@ LABEL175:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL185: LABEL195:
iconst 3 iconst 3
stat_xp stat_xp
iload 16 iload 16
@@ -220,7 +232,7 @@ LABEL185:
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt HP_XP_GAINED if_icmpgt HP_XP_GAINED
jump LABEL204 jump LABEL214
HP_XP_GAINED: HP_XP_GAINED:
iload 35 iload 35
iconst 3 iconst 3
@@ -234,7 +246,7 @@ HP_XP_GAINED:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL204: LABEL214:
iconst 5 iconst 5
stat_xp stat_xp
iload 17 iload 17
@@ -242,9 +254,9 @@ LABEL204:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL213 if_icmpgt LABEL223
jump LABEL223 jump LABEL233
LABEL213: LABEL223:
iload 35 iload 35
iconst 5 iconst 5
set_array_int set_array_int
@@ -255,7 +267,7 @@ LABEL213:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL223: LABEL233:
iconst 16 iconst 16
stat_xp stat_xp
iload 18 iload 18
@@ -263,9 +275,9 @@ LABEL223:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL232 if_icmpgt LABEL242
jump LABEL242 jump LABEL252
LABEL232: LABEL242:
iload 35 iload 35
iconst 16 iconst 16
set_array_int set_array_int
@@ -276,7 +288,7 @@ LABEL232:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL242: LABEL252:
iconst 15 iconst 15
stat_xp stat_xp
iload 19 iload 19
@@ -284,9 +296,9 @@ LABEL242:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL251 if_icmpgt LABEL261
jump LABEL261 jump LABEL271
LABEL251: LABEL261:
iload 35 iload 35
iconst 15 iconst 15
set_array_int set_array_int
@@ -297,7 +309,7 @@ LABEL251:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL261: LABEL271:
iconst 17 iconst 17
stat_xp stat_xp
iload 20 iload 20
@@ -305,9 +317,9 @@ LABEL261:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL270 if_icmpgt LABEL280
jump LABEL280 jump LABEL290
LABEL270: LABEL280:
iload 35 iload 35
iconst 17 iconst 17
set_array_int set_array_int
@@ -318,7 +330,7 @@ LABEL270:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL280: LABEL290:
iconst 12 iconst 12
stat_xp stat_xp
iload 21 iload 21
@@ -326,9 +338,9 @@ LABEL280:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL289 if_icmpgt LABEL299
jump LABEL299 jump LABEL309
LABEL289: LABEL299:
iload 35 iload 35
iconst 12 iconst 12
set_array_int set_array_int
@@ -339,7 +351,7 @@ LABEL289:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL299: LABEL309:
iconst 20 iconst 20
stat_xp stat_xp
iload 22 iload 22
@@ -347,9 +359,9 @@ LABEL299:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL308 if_icmpgt LABEL318
jump LABEL318 jump LABEL328
LABEL308: LABEL318:
iload 35 iload 35
iconst 20 iconst 20
set_array_int set_array_int
@@ -360,7 +372,7 @@ LABEL308:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL318: LABEL328:
iconst 14 iconst 14
stat_xp stat_xp
iload 23 iload 23
@@ -368,9 +380,9 @@ LABEL318:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL327 if_icmpgt LABEL337
jump LABEL337 jump LABEL347
LABEL327: LABEL337:
iload 35 iload 35
iconst 14 iconst 14
set_array_int set_array_int
@@ -381,7 +393,7 @@ LABEL327:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL337: LABEL347:
iconst 13 iconst 13
stat_xp stat_xp
iload 24 iload 24
@@ -389,9 +401,9 @@ LABEL337:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL346 if_icmpgt LABEL356
jump LABEL356 jump LABEL366
LABEL346: LABEL356:
iload 35 iload 35
iconst 13 iconst 13
set_array_int set_array_int
@@ -402,7 +414,7 @@ LABEL346:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL356: LABEL366:
iconst 7 iconst 7
stat_xp stat_xp
iload 26 iload 26
@@ -410,9 +422,9 @@ LABEL356:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL365 if_icmpgt LABEL375
jump LABEL375 jump LABEL385
LABEL365: LABEL375:
iload 35 iload 35
iconst 7 iconst 7
set_array_int set_array_int
@@ -423,7 +435,7 @@ LABEL365:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL375: LABEL385:
iconst 11 iconst 11
stat_xp stat_xp
iload 27 iload 27
@@ -431,9 +443,9 @@ LABEL375:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL384 if_icmpgt LABEL394
jump LABEL394 jump LABEL404
LABEL384: LABEL394:
iload 35 iload 35
iconst 11 iconst 11
set_array_int set_array_int
@@ -444,7 +456,7 @@ LABEL384:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL394: LABEL404:
iconst 8 iconst 8
stat_xp stat_xp
iload 28 iload 28
@@ -452,9 +464,9 @@ LABEL394:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL403 if_icmpgt LABEL413
jump LABEL413 jump LABEL423
LABEL403: LABEL413:
iload 35 iload 35
iconst 8 iconst 8
set_array_int set_array_int
@@ -465,7 +477,7 @@ LABEL403:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL413: LABEL423:
iconst 9 iconst 9
stat_xp stat_xp
iload 29 iload 29
@@ -473,9 +485,9 @@ LABEL413:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL422 if_icmpgt LABEL432
jump LABEL432 jump LABEL442
LABEL422: LABEL432:
iload 35 iload 35
iconst 9 iconst 9
set_array_int set_array_int
@@ -486,7 +498,7 @@ LABEL422:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL432: LABEL442:
iconst 18 iconst 18
stat_xp stat_xp
iload 30 iload 30
@@ -494,9 +506,9 @@ LABEL432:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL441 if_icmpgt LABEL451
jump LABEL451 jump LABEL461
LABEL441: LABEL451:
iload 35 iload 35
iconst 18 iconst 18
set_array_int set_array_int
@@ -507,7 +519,7 @@ LABEL441:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL451: LABEL461:
iconst 19 iconst 19
stat_xp stat_xp
iload 31 iload 31
@@ -515,9 +527,9 @@ LABEL451:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL460 if_icmpgt LABEL470
jump LABEL470 jump LABEL480
LABEL460: LABEL470:
iload 35 iload 35
iconst 19 iconst 19
set_array_int set_array_int
@@ -528,7 +540,7 @@ LABEL460:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL470: LABEL480:
iconst 22 iconst 22
stat_xp stat_xp
iload 32 iload 32
@@ -536,9 +548,9 @@ LABEL470:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL479 if_icmpgt LABEL489
jump LABEL489 jump LABEL499
LABEL479: LABEL489:
iload 35 iload 35
iconst 22 iconst 22
set_array_int set_array_int
@@ -549,7 +561,7 @@ LABEL479:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL489: LABEL499:
iconst 21 iconst 21
stat_xp stat_xp
iload 33 iload 33
@@ -557,9 +569,9 @@ LABEL489:
istore 36 istore 36
iload 36 iload 36
iconst 0 iconst 0
if_icmpgt LABEL498 if_icmpgt LABEL508
jump LABEL508 jump LABEL518
LABEL498: LABEL508:
iload 35 iload 35
iconst 21 iconst 21
set_array_int set_array_int
@@ -570,7 +582,7 @@ LABEL498:
iconst 1 iconst 1
add add
istore 35 istore 35
LABEL508: LABEL518:
iconst 0 iconst 0
istore 37 istore 37
iconst 0 iconst 0
@@ -597,67 +609,67 @@ LABEL508:
sstore 0 sstore 0
iload 35 iload 35
iconst 0 iconst 0
if_icmpgt LABEL536 if_icmpgt LABEL546
jump LABEL779 jump LABEL789
LABEL536: LABEL546:
iload 16 iload 16
iconst 0 iconst 0
if_icmpgt LABEL540 if_icmpgt LABEL550
jump LABEL779 jump LABEL789
LABEL540: LABEL550:
clientclock clientclock
get_varc_int 76 get_varc_int 76
sub sub
iconst 10 iconst 10
if_icmpgt LABEL546 if_icmpgt LABEL556
jump LABEL779 jump LABEL789
LABEL546: LABEL556:
get_varbit 4693 get_varbit 4693
iconst 1 iconst 1
if_icmpeq LABEL550 if_icmpeq LABEL560
jump LABEL561 jump LABEL571
LABEL550: LABEL560:
invoke 1972 invoke 1972
iconst 0 iconst 0
if_icmpeq LABEL554 if_icmpeq LABEL564
jump LABEL561 jump LABEL571
LABEL554: LABEL564:
iconst 495 iconst 495
iconst 495 iconst 495
iconst 25 iconst 25
istore 41 istore 41
istore 40 istore 40
istore 39 istore 39
jump LABEL575 jump LABEL585
LABEL561: LABEL571:
get_varbit 4693 get_varbit 4693
iconst 2 iconst 2
if_icmpeq LABEL565 if_icmpeq LABEL575
jump LABEL575 jump LABEL585
LABEL565: LABEL575:
invoke 1972 invoke 1972
iconst 0 iconst 0
if_icmpeq LABEL569 if_icmpeq LABEL579
jump LABEL575 jump LABEL585
LABEL569: LABEL579:
iconst 496 iconst 496
iconst 496 iconst 496
iconst 25 iconst 25
istore 41 istore 41
istore 40 istore 40
istore 39 istore 39
LABEL575: LABEL585:
iload 8 iload 8
if_getheight if_getheight
istore 42 istore 42
iload 42 iload 42
iconst 100 iconst 100
if_icmplt LABEL582 if_icmplt LABEL592
jump LABEL584 jump LABEL594
LABEL582: LABEL592:
iconst 100 iconst 100
istore 42 istore 42
LABEL584: LABEL594:
iload 41 iload 41
iconst 105 iconst 105
iconst 105 iconst 105
@@ -670,58 +682,58 @@ LABEL584:
iconst 1 iconst 1
add add
istore 43 istore 43
LABEL596: LABEL606:
iload 37 iload 37
iload 35 iload 35
if_icmplt LABEL600 if_icmplt LABEL610
jump LABEL774 jump LABEL784
LABEL600: LABEL610:
iload 38 iload 38
iconst 0 iconst 0
if_icmpeq LABEL604 if_icmpeq LABEL614
jump LABEL613 jump LABEL623
LABEL604: LABEL614:
iload 0 iload 0
iconst 0 iconst 0
if_icmpeq LABEL608 if_icmpeq LABEL618
jump LABEL613 jump LABEL623
LABEL608: LABEL618:
iload 37 iload 37
get_array_int get_array_int
set_varc_int 72 set_varc_int 72
iconst 1 iconst 1
istore 38 istore 38
LABEL613: LABEL623:
get_varc_int 71 get_varc_int 71
iconst 0 iconst 0
if_icmpgt LABEL617 if_icmpgt LABEL627
jump LABEL628 jump LABEL638
LABEL617: LABEL627:
get_varc_int 71 get_varc_int 71
clientclock clientclock
iload 43 iload 43
sub sub
if_icmpgt LABEL623 if_icmpgt LABEL633
jump LABEL628 jump LABEL638
LABEL623: LABEL633:
get_varc_int 71 get_varc_int 71
iload 43 iload 43
add add
istore 44 istore 44
jump LABEL630 jump LABEL640
LABEL628: LABEL638:
clientclock clientclock
istore 44 istore 44
LABEL630: LABEL640:
iload 44 iload 44
clientclock clientclock
iload 43 iload 43
iload 10 iload 10
multiply multiply
add add
if_icmplt LABEL638 if_icmplt LABEL648
jump LABEL771 jump LABEL781
LABEL638: LABEL648:
iconst 105 iconst 105
iconst 73 iconst 73
iconst 1163 iconst 1163
@@ -758,27 +770,27 @@ LABEL638:
iconst 1 iconst 1
add add
istore 37 istore 37
LABEL674: LABEL684:
get_varbit 4696 get_varbit 4696
iconst 1 iconst 1
if_icmpeq LABEL678 if_icmpeq LABEL688
jump LABEL722 jump LABEL732
LABEL678: LABEL688:
iload 37 iload 37
iload 35 iload 35
if_icmplt LABEL682 if_icmplt LABEL692
jump LABEL722 jump LABEL732
LABEL682: LABEL692:
iload 45 iload 45
iconst 5 iconst 5
if_icmplt LABEL686 if_icmplt LABEL696
jump LABEL722 jump LABEL732
LABEL686: LABEL696:
iload 46 iload 46
iconst 1000000 iconst 1000000
if_icmplt LABEL690 if_icmplt LABEL700
jump LABEL722 jump LABEL732
LABEL690: LABEL700:
iload 46 iload 46
iload 37 iload 37
get_array_int 1 get_array_int 1
@@ -810,8 +822,8 @@ LABEL690:
iconst 1 iconst 1
add add
istore 37 istore 37
jump LABEL674 jump LABEL684
LABEL722: LABEL732:
iload 46 iload 46
sconst "," sconst ","
invoke 46 invoke 46
@@ -820,22 +832,22 @@ LABEL722:
sstore 0 sstore 0
iload 0 iload 0
iconst 1 iconst 1
if_icmpeq LABEL730 if_icmpeq LABEL740
jump LABEL735 jump LABEL745
LABEL730: LABEL740:
sconst "<img=11>" sconst "<img=11>"
sconst " " sconst " "
sload 0 sload 0
join_string 3 join_string 3
sstore 0 sstore 0
LABEL735: LABEL745:
iload 47 iload 47
iconst 0 iconst 0
cc_find cc_find
iconst 1 iconst 1
if_icmpeq LABEL741 if_icmpeq LABEL751
jump LABEL756 jump LABEL766
LABEL741: LABEL751:
sload 0 sload 0
cc_settext cc_settext
iconst 0 iconst 0
@@ -851,7 +863,7 @@ LABEL741:
iload 40 iload 40
sload 0 sload 0
invoke 996 invoke 996
LABEL756: LABEL766:
iconst 1005 iconst 1005
iload 47 iload 47
iload 44 iload 44
@@ -866,24 +878,24 @@ LABEL756:
iload 10 iload 10
mod mod
set_varc_int 70 set_varc_int 70
jump LABEL773 jump LABEL783
LABEL771: LABEL781:
iload 35 iload 35
istore 37 istore 37
LABEL773: LABEL783:
jump LABEL596 jump LABEL606
LABEL774: LABEL784:
iload 1 iload 1
iload 3 iload 3
iload 8 iload 8
iload 9 iload 9
invoke 997 invoke 997
LABEL779: LABEL789:
iload 0 iload 0
iconst 0 iconst 0
if_icmpeq LABEL783 if_icmpeq LABEL793
jump LABEL802 jump LABEL812
LABEL783: LABEL793:
iload 3 iload 3
iload 4 iload 4
iload 5 iload 5
@@ -903,5 +915,5 @@ LABEL783:
iload 9 iload 9
iload 10 iload 10
invoke 1003 invoke 1003
LABEL802: LABEL812:
return return
@@ -31,6 +31,7 @@ import java.time.Instant;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.client.account.AccountSession; import net.runelite.client.account.AccountSession;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import org.junit.Assert; import org.junit.Assert;
@@ -43,6 +44,10 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class ConfigManagerTest public class ConfigManagerTest
{ {
@Mock
@Bind
Client client;
@Mock @Mock
@Bind @Bind
EventBus eventBus; EventBus eventBus;
@@ -44,6 +44,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
@@ -133,11 +134,11 @@ public class WoodcuttingPluginTest
{ {
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", BIRDS_NEST_MESSAGE, "", 0); ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", BIRDS_NEST_MESSAGE, "", 0);
woodcuttingPlugin.showNestNotification = true; when(woodcuttingConfig.showNestNotification()).thenReturn(true);
woodcuttingPlugin.onChatMessage(chatMessage); woodcuttingPlugin.onChatMessage(chatMessage);
verify(notifier).notify("A bird nest has spawned!"); verify(notifier).notify("A bird nest has spawned!");
woodcuttingPlugin.showNestNotification = false; when(woodcuttingConfig.showNestNotification()).thenReturn(false);
woodcuttingPlugin.onChatMessage(chatMessage); woodcuttingPlugin.onChatMessage(chatMessage);
verifyNoMoreInteractions(notifier); verifyNoMoreInteractions(notifier);
} }
@@ -38,7 +38,7 @@ public class DevicePcmPlayer extends PcmPlayer {
) )
@Export("init") @Export("init")
protected void init() { protected void init() {
this.format = new AudioFormat((float)Messages.field1274, 16, PcmPlayer.PcmPlayer_stereo ? 2 : 1, true, false); this.format = new AudioFormat((float)Messages.PcmPlayer_sampleRate, 16, PcmPlayer.PcmPlayer_stereo ? 2 : 1, true, false);
this.byteSamples = new byte[256 << (PcmPlayer.PcmPlayer_stereo ? 2 : 1)]; this.byteSamples = new byte[256 << (PcmPlayer.PcmPlayer_stereo ? 2 : 1)];
} }
@@ -136,7 +136,7 @@ final class GrandExchangeOfferAgeComparator implements Comparator {
) )
public static final void method170(int var0, boolean var1, int var2) { public static final void method170(int var0, boolean var1, int var2) {
if (var0 >= 8000 && var0 <= 48000) { if (var0 >= 8000 && var0 <= 48000) {
Messages.field1274 = var0; Messages.PcmPlayer_sampleRate = var0;
PcmPlayer.PcmPlayer_stereo = var1; PcmPlayer.PcmPlayer_stereo = var1;
RouteStrategy.field2114 = var2; RouteStrategy.field2114 = var2;
} else { } else {
@@ -174,7 +174,7 @@ public class GrandExchangeOfferOwnWorldComparator implements Comparator {
class60.pcmPlayer1 = HealthBarUpdate.method1776(GameShell.taskHandler, 1, 2048); class60.pcmPlayer1 = HealthBarUpdate.method1776(GameShell.taskHandler, 1, 2048);
ClientPacket.pcmStreamMixer = new PcmStreamMixer(); ClientPacket.pcmStreamMixer = new PcmStreamMixer();
class60.pcmPlayer1.setStream(ClientPacket.pcmStreamMixer); class60.pcmPlayer1.setStream(ClientPacket.pcmStreamMixer);
LoginScreenAnimation.decimator = new Decimator(22050, Messages.field1274); LoginScreenAnimation.decimator = new Decimator(22050, Messages.PcmPlayer_sampleRate);
Login.Login_loadingText = "Prepared sound engine"; Login.Login_loadingText = "Prepared sound engine";
Login.Login_loadingPercent = 35; Login.Login_loadingPercent = 35;
Client.titleLoadingStage = 50; Client.titleLoadingStage = 50;
@@ -78,7 +78,7 @@ public class HealthBarUpdate extends Node {
garbageValue = "148025221" garbageValue = "148025221"
) )
public static final PcmPlayer method1776(TaskHandler var0, int var1, int var2) { public static final PcmPlayer method1776(TaskHandler var0, int var1, int var2) {
if (Messages.field1274 == 0) { if (Messages.PcmPlayer_sampleRate == 0) {
throw new IllegalStateException(); throw new IllegalStateException();
} else if (var1 >= 0 && var1 < 2) { } else if (var1 >= 0 && var1 < 2) {
if (var2 < 256) { if (var2 < 256) {
@@ -138,12 +138,12 @@ public class JagexCache {
int var6 = (var3 - 32 - var5) * var2 / (var4 - var3); int var6 = (var3 - 32 - var5) * var2 / (var4 - var3);
Rasterizer2D.Rasterizer2D_fillRectangle(var0, var6 + var1 + 16, 16, var5, Client.field706); Rasterizer2D.Rasterizer2D_fillRectangle(var0, var6 + var1 + 16, 16, var5, Client.field706);
Rasterizer2D.rasterizerDrawVerticalLine(var0, var6 + var1 + 16, var5, Client.field708); Rasterizer2D.Rasterizer2D_drawVerticalLine(var0, var6 + var1 + 16, var5, Client.field708);
Rasterizer2D.rasterizerDrawVerticalLine(var0 + 1, var6 + var1 + 16, var5, Client.field708); Rasterizer2D.Rasterizer2D_drawVerticalLine(var0 + 1, var6 + var1 + 16, var5, Client.field708);
Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var1 + 16, 16, Client.field708); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var1 + 16, 16, Client.field708);
Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var1 + 17, 16, Client.field708); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var1 + 17, 16, Client.field708);
Rasterizer2D.rasterizerDrawVerticalLine(var0 + 15, var6 + var1 + 16, var5, Client.field707); Rasterizer2D.Rasterizer2D_drawVerticalLine(var0 + 15, var6 + var1 + 16, var5, Client.field707);
Rasterizer2D.rasterizerDrawVerticalLine(var0 + 14, var6 + var1 + 17, var5 - 1, Client.field707); Rasterizer2D.Rasterizer2D_drawVerticalLine(var0 + 14, var6 + var1 + 17, var5 - 1, Client.field707);
Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var5 + var1 + 15, 16, Client.field707); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0, var6 + var5 + var1 + 15, 16, Client.field707);
Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0 + 1, var6 + var5 + var1 + 14, 15, Client.field707); Rasterizer2D.Rasterizer2D_drawHorizontalLine(var0 + 1, var6 + var5 + var1 + 14, 15, Client.field707);
} }
+2 -1
View File
@@ -35,7 +35,8 @@ public class Messages {
@ObfuscatedGetter( @ObfuscatedGetter(
intValue = -1088425627 intValue = -1088425627
) )
public static int field1274; @Export("PcmPlayer_sampleRate")
public static int PcmPlayer_sampleRate;
@ObfuscatedName("c") @ObfuscatedName("c")
@ObfuscatedSignature( @ObfuscatedSignature(
signature = "Lat;" signature = "Lat;"
@@ -245,7 +245,7 @@ public class MidiPcmStream extends PcmStream {
@Export("fill") @Export("fill")
protected synchronized void fill(int[] var1, int var2, int var3) { protected synchronized void fill(int[] var1, int var2, int var3) {
if (this.midiFile.isReady()) { if (this.midiFile.isReady()) {
int var4 = this.midiFile.division * this.field2419 * -727379968 / Messages.field1274; int var4 = this.midiFile.division * this.field2419 * -727379968 / Messages.PcmPlayer_sampleRate;
do { do {
long var5 = this.field2431 + (long)var4 * (long)var3; long var5 = this.field2431 + (long)var4 * (long)var3;
@@ -294,7 +294,7 @@ public class MidiPcmStream extends PcmStream {
@Export("skip") @Export("skip")
protected synchronized void skip(int var1) { protected synchronized void skip(int var1) {
if (this.midiFile.isReady()) { if (this.midiFile.isReady()) {
int var2 = this.midiFile.division * this.field2419 * -727379968 / Messages.field1274; int var2 = this.midiFile.division * this.field2419 * -727379968 / Messages.PcmPlayer_sampleRate;
do { do {
long var3 = this.field2431 + (long)var2 * (long)var1; long var3 = this.field2431 + (long)var2 * (long)var1;
@@ -519,7 +519,7 @@ public class MidiPcmStream extends PcmStream {
for (MusicPatchNode var2 = (MusicPatchNode)this.patchStream.queue.last(); var2 != null; var2 = (MusicPatchNode)this.patchStream.queue.previous()) { for (MusicPatchNode var2 = (MusicPatchNode)this.patchStream.queue.last(); var2 != null; var2 = (MusicPatchNode)this.patchStream.queue.previous()) {
if (var1 < 0 || var2.field2449 == var1) { if (var1 < 0 || var2.field2449 == var1) {
if (var2.stream != null) { if (var2.stream != null) {
var2.stream.method2582(Messages.field1274 / 100); var2.stream.method2582(Messages.PcmPlayer_sampleRate / 100);
if (var2.stream.method2686()) { if (var2.stream.method2686()) {
this.patchStream.mixer.addSubStream(var2.stream); this.patchStream.mixer.addSubStream(var2.stream);
} }
@@ -858,7 +858,7 @@ public class MidiPcmStream extends PcmStream {
var2 += (int)(var6 * (double)var4); var2 += (int)(var6 * (double)var4);
} }
var4 = (int)((double)(var1.rawSound.sampleRate * 256) * Math.pow(2.0D, (double)var2 * 3.255208333333333E-4D) / (double)Messages.field1274 + 0.5D); var4 = (int)((double)(var1.rawSound.sampleRate * 256) * Math.pow(2.0D, (double)var2 * 3.255208333333333E-4D) / (double)Messages.PcmPlayer_sampleRate + 0.5D);
return var4 < 1 ? 1 : var4; return var4 < 1 ? 1 : var4;
} }
@@ -990,7 +990,7 @@ public class MidiPcmStream extends PcmStream {
garbageValue = "178317578" garbageValue = "178317578"
) )
boolean method3802(MusicPatchNode var1, int[] var2, int var3, int var4) { boolean method3802(MusicPatchNode var1, int[] var2, int var3, int var4) {
var1.field2464 = Messages.field1274 / 100; var1.field2464 = Messages.PcmPlayer_sampleRate / 100;
if (var1.field2459 < 0 || var1.stream != null && !var1.stream.method2585()) { if (var1.field2459 < 0 || var1.stream != null && !var1.stream.method2585()) {
int var5 = var1.field2455; int var5 = var1.field2455;
if (var5 > 0) { if (var5 > 0) {
@@ -41,7 +41,7 @@ public class MusicPatchPcmStream extends PcmStream {
) )
void method3962(MusicPatchNode var1, int[] var2, int var3, int var4, int var5) { void method3962(MusicPatchNode var1, int[] var2, int var3, int var4, int var5) {
if ((this.superStream.field2428[var1.field2449] & 4) != 0 && var1.field2459 < 0) { if ((this.superStream.field2428[var1.field2449] & 4) != 0 && var1.field2459 < 0) {
int var6 = this.superStream.field2433[var1.field2449] / Messages.field1274; int var6 = this.superStream.field2433[var1.field2449] / Messages.PcmPlayer_sampleRate;
while (true) { while (true) {
int var7 = (var6 + 1048575 - var1.field2463) / var6; int var7 = (var6 + 1048575 - var1.field2463) / var6;
@@ -54,7 +54,7 @@ public class MusicPatchPcmStream extends PcmStream {
var3 += var7; var3 += var7;
var4 -= var7; var4 -= var7;
var1.field2463 += var7 * var6 - 1048576; var1.field2463 += var7 * var6 - 1048576;
int var8 = Messages.field1274 / 100; int var8 = Messages.PcmPlayer_sampleRate / 100;
int var9 = 262144 / var6; int var9 = 262144 / var6;
if (var9 < var8) { if (var9 < var8) {
var8 = var9; var8 = var9;
@@ -91,7 +91,7 @@ public class MusicPatchPcmStream extends PcmStream {
) )
void method3959(MusicPatchNode var1, int var2) { void method3959(MusicPatchNode var1, int var2) {
if ((this.superStream.field2428[var1.field2449] & 4) != 0 && var1.field2459 < 0) { if ((this.superStream.field2428[var1.field2449] & 4) != 0 && var1.field2459 < 0) {
int var3 = this.superStream.field2433[var1.field2449] / Messages.field1274; int var3 = this.superStream.field2433[var1.field2449] / Messages.PcmPlayer_sampleRate;
int var4 = (var3 + 1048575 - var1.field2463) / var3; int var4 = (var3 + 1048575 - var1.field2463) / var3;
var1.field2463 = var3 * var2 + var1.field2463 & 1048575; var1.field2463 = var3 * var2 + var1.field2463 & 1048575;
if (var4 <= var2) { if (var4 <= var2) {
@@ -263,7 +263,7 @@ public class PcmPlayer {
while (var1 > 5000L + this.timeMs) { while (var1 > 5000L + this.timeMs) {
this.skip(256); this.skip(256);
this.timeMs += (long)(256000 / Messages.field1274); this.timeMs += (long)(256000 / Messages.PcmPlayer_sampleRate);
} }
} catch (Exception var6) { } catch (Exception var6) {
this.timeMs = var1; this.timeMs = var1;
@@ -359,7 +359,7 @@ public class PcmPlayer {
class300.clearIntArray(var1, 0, var3); class300.clearIntArray(var1, 0, var3);
this.field1409 -= var2; this.field1409 -= var2;
if (this.stream != null && this.field1409 <= 0) { if (this.stream != null && this.field1409 <= 0) {
this.field1409 += Messages.field1274 >> 4; this.field1409 += Messages.PcmPlayer_sampleRate >> 4;
class1.PcmStream_disable(this.stream); class1.PcmStream_disable(this.stream);
this.method2452(this.stream, this.stream.vmethod2741()); this.method2452(this.stream, this.stream.vmethod2741());
int var4 = 0; int var4 = 0;
@@ -609,8 +609,8 @@ public class Rasterizer2D extends DualNode {
public static void Rasterizer2D_drawRectangle(int var0, int var1, int var2, int var3, int var4) { public static void Rasterizer2D_drawRectangle(int var0, int var1, int var2, int var3, int var4) {
Rasterizer2D_drawHorizontalLine(var0, var1, var2, var4); Rasterizer2D_drawHorizontalLine(var0, var1, var2, var4);
Rasterizer2D_drawHorizontalLine(var0, var3 + var1 - 1, var2, var4); Rasterizer2D_drawHorizontalLine(var0, var3 + var1 - 1, var2, var4);
rasterizerDrawVerticalLine(var0, var1, var3, var4); Rasterizer2D_drawVerticalLine(var0, var1, var3, var4);
rasterizerDrawVerticalLine(var0 + var2 - 1, var1, var3, var4); Rasterizer2D_drawVerticalLine(var0 + var2 - 1, var1, var3, var4);
} }
@ObfuscatedName("df") @ObfuscatedName("df")
@@ -679,7 +679,7 @@ public class Rasterizer2D extends DualNode {
@ObfuscatedName("eg") @ObfuscatedName("eg")
@Export("Rasterizer2D_drawVerticalLine") @Export("Rasterizer2D_drawVerticalLine")
public static void rasterizerDrawVerticalLine(int var0, int var1, int var2, int var3) { public static void Rasterizer2D_drawVerticalLine(int var0, int var1, int var2, int var3) {
if (var0 >= Rasterizer2D_xClipStart && var0 < Rasterizer2D_xClipEnd) { if (var0 >= Rasterizer2D_xClipStart && var0 < Rasterizer2D_xClipEnd) {
if (var1 < Rasterizer2D_yClipStart) { if (var1 < Rasterizer2D_yClipStart) {
var2 -= Rasterizer2D_yClipStart - var1; var2 -= Rasterizer2D_yClipStart - var1;
@@ -744,9 +744,9 @@ public class Rasterizer2D extends DualNode {
} else if (var2 == 0) { } else if (var2 == 0) {
if (var3 >= 0) { if (var3 >= 0) {
rasterizerDrawVerticalLine(var0, var1, var3 + 1, var4); Rasterizer2D_drawVerticalLine(var0, var1, var3 + 1, var4);
} else { } else {
rasterizerDrawVerticalLine(var0, var3 + var1, -var3 + 1, var4); Rasterizer2D_drawVerticalLine(var0, var3 + var1, -var3 + 1, var4);
} }
} else { } else {
@@ -846,7 +846,7 @@ public class RawPcmStream extends PcmStream {
) )
@Export("createRawPcmStream") @Export("createRawPcmStream")
public static RawPcmStream createRawPcmStream(RawSound var0, int var1, int var2) { public static RawPcmStream createRawPcmStream(RawSound var0, int var1, int var2) {
return var0.samples != null && var0.samples.length != 0 ? new RawPcmStream(var0, (int)((long)var0.sampleRate * 256L * (long)var1 / (long)(Messages.field1274 * 100)), var2 << 6) : null; return var0.samples != null && var0.samples.length != 0 ? new RawPcmStream(var0, (int)((long)var0.sampleRate * 256L * (long)var1 / (long)(Messages.PcmPlayer_sampleRate * 100)), var2 << 6) : null;
} }
@ObfuscatedName("g") @ObfuscatedName("g")
@@ -897,7 +897,7 @@ public class WorldMapRegion {
void method469(int var1, int var2, int var3, int var4) { void method469(int var1, int var2, int var3, int var4) {
var3 %= 4; var3 %= 4;
if (var3 == 0) { if (var3 == 0) {
Rasterizer2D.rasterizerDrawVerticalLine(this.pixelsPerTile * var1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4); Rasterizer2D.Rasterizer2D_drawVerticalLine(this.pixelsPerTile * var1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4);
} }
if (var3 == 1) { if (var3 == 1) {
@@ -905,7 +905,7 @@ public class WorldMapRegion {
} }
if (var3 == 2) { if (var3 == 2) {
Rasterizer2D.rasterizerDrawVerticalLine(this.pixelsPerTile * var1 + this.pixelsPerTile - 1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4); Rasterizer2D.Rasterizer2D_drawVerticalLine(this.pixelsPerTile * var1 + this.pixelsPerTile - 1, this.pixelsPerTile * (63 - var2), this.pixelsPerTile, var4);
} }
if (var3 == 3) { if (var3 == 3) {