From 859b0f110e40fae70fcce3bcaf6f6d9a849c91d4 Mon Sep 17 00:00:00 2001 From: Vetricci <81270549+Vetricci@users.noreply.github.com> Date: Sun, 8 Aug 2021 21:52:54 -0500 Subject: [PATCH 1/6] roof removal: add overrides for Prifddinas --- .../client/plugins/roofremoval/overrides.jsonc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/roofremoval/overrides.jsonc b/runelite-client/src/main/resources/net/runelite/client/plugins/roofremoval/overrides.jsonc index 200d6b8b8d..9967406372 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/roofremoval/overrides.jsonc +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/roofremoval/overrides.jsonc @@ -151,6 +151,14 @@ "ry2": 47, "z1": 0, "z2": 0 + }, + { // Tatie's house + "rx1": 28, + "ry1": 5, + "rx2": 35, + "ry2": 12, + "z1": 0, + "z2": 0 } ], "13151":[ // Prif NE @@ -315,6 +323,14 @@ "ry2": 25, "z1": 0, "z2": 0 + }, + { // Crafting shop + "rx1": 21, + "ry1": 60, + "rx2": 23, + "ry2": 60, + "z1": 0, + "z2": 0 } ], "13150": [ // Prif SE From 152077b286a9051059992b4c4177cad9fdad42c9 Mon Sep 17 00:00:00 2001 From: Vetricci <81270549+Vetricci@users.noreply.github.com> Date: Wed, 11 Aug 2021 18:29:55 -0500 Subject: [PATCH 2/6] skillcalculator: Add new amethyst items (#13890) --- .../plugins/skillcalculator/skill_crafting.json | 12 +++++++++--- .../plugins/skillcalculator/skill_fletching.json | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json index 0f2a5c6922..d8e6c6e9d2 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_crafting.json @@ -719,7 +719,7 @@ "level": 83, "icon": 21338, "name": "Amethyst Bolt Tips", - "xp": 60 + "xp": 4 }, { "level": 83, @@ -743,13 +743,13 @@ "level": 85, "icon": 21350, "name": "Amethyst Arrowtips", - "xp": 60 + "xp": 4 }, { "level": 87, "icon": 21352, "name": "Amethyst Javelin Heads", - "xp": 60 + "xp": 12 }, { "level": 87, @@ -757,6 +757,12 @@ "name": "Light Orb", "xp": 70 }, + { + "level": 89, + "icon": 25853, + "name": "Amethyst Dart Tip", + "xp": 7.5 + }, { "level": 89, "icon": 19538, diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json index bb6e56fc59..53e3042478 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json @@ -564,6 +564,12 @@ "name": "Magic Shield", "xp": 183 }, + { + "level": 90, + "icon": 25849, + "name": "Amethyst Dart", + "xp": 21 + }, { "level": 90, "icon": 11212, From 33ff3a2749372a1d98329d2c4aeddbeadf19434e Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 11 Aug 2021 16:51:14 -0400 Subject: [PATCH 3/6] npc indicators: add fill color config --- .../npchighlight/NpcIndicatorsConfig.java | 19 +++++++++-- .../npchighlight/NpcIndicatorsPlugin.java | 2 +- .../npchighlight/NpcMinimapOverlay.java | 2 +- .../plugins/npchighlight/NpcSceneOverlay.java | 32 ++++++++----------- .../npchighlight/NpcIndicatorsPluginTest.java | 2 +- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java index ba45c310ef..6c24e004fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsConfig.java @@ -95,16 +95,29 @@ public interface NpcIndicatorsConfig extends Config position = 4, keyName = "npcColor", name = "Highlight Color", - description = "Color of the NPC highlight", + description = "Color of the NPC highlight border, menu, and text", section = renderStyleSection ) - default Color getHighlightColor() + default Color highlightColor() { return Color.CYAN; } + @Alpha @ConfigItem( position = 5, + keyName = "fillColor", + name = "Fill Color", + description = "Color of the NPC highlight fill", + section = renderStyleSection + ) + default Color fillColor() + { + return new Color(0, 255, 255, 20); + } + + @ConfigItem( + position = 6, keyName = "borderWidth", name = "Border Width", description = "Width of the highlighted NPC border", @@ -116,7 +129,7 @@ public interface NpcIndicatorsConfig extends Config } @ConfigItem( - position = 6, + position = 7, keyName = "outlineFeather", name = "Outline feather", description = "Specify between 0-4 how much of the model outline should be faded", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index de84c15666..7ebe470d97 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -267,7 +267,7 @@ public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService if (color == null && highlightedNpcs.contains(npc) && config.highlightMenuNames() && (!npc.isDead() || !config.ignoreDeadNpcs())) { - color = config.getHighlightColor(); + color = config.highlightColor(); } if (color != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java index e1fd961216..52a17975a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java @@ -57,7 +57,7 @@ public class NpcMinimapOverlay extends Overlay { for (NPC npc : plugin.getHighlightedNpcs()) { - renderNpcOverlay(graphics, npc, Text.removeTags(npc.getName()), config.getHighlightColor()); + renderNpcOverlay(graphics, npc, Text.removeTags(npc.getName()), config.highlightColor()); } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java index 7b7bf9b461..8c2b2b3b06 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java @@ -49,7 +49,6 @@ import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.outline.ModelOutlineRenderer; -import net.runelite.client.util.ColorUtil; import net.runelite.client.util.Text; public class NpcSceneOverlay extends Overlay @@ -92,7 +91,7 @@ public class NpcSceneOverlay extends Overlay for (NPC npc : plugin.getHighlightedNpcs()) { - renderNpcOverlay(graphics, npc, config.getHighlightColor()); + renderNpcOverlay(graphics, npc); } return null; @@ -113,18 +112,12 @@ public class NpcSceneOverlay extends Overlay return; } - final Color color = config.getHighlightColor(); - final LocalPoint centerLp = new LocalPoint( lp.getX() + Perspective.LOCAL_TILE_SIZE * (npc.getNpcSize() - 1) / 2, lp.getY() + Perspective.LOCAL_TILE_SIZE * (npc.getNpcSize() - 1) / 2); final Polygon poly = Perspective.getCanvasTileAreaPoly(client, centerLp, npc.getNpcSize()); - - if (poly != null) - { - OverlayUtil.renderPolygon(graphics, poly, color); - } + renderPoly(graphics, config.highlightColor(), config.fillColor(), poly); final Instant now = Instant.now(); final double baseTick = ((npc.getDiedOnTick() + npc.getRespawnTime()) - client.getTickCount()) * (Constants.GAME_TICK_LENGTH / 1000.0); @@ -148,7 +141,7 @@ public class NpcSceneOverlay extends Overlay } } - private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color) + private void renderNpcOverlay(Graphics2D graphics, NPC actor) { NPCComposition npcComposition = actor.getTransformedComposition(); if (npcComposition == null || !npcComposition.isInteractible() @@ -157,10 +150,13 @@ public class NpcSceneOverlay extends Overlay return; } + final Color borderColor = config.highlightColor(); + final Color fillColor = config.fillColor(); + if (config.highlightHull()) { Shape objectClickbox = actor.getConvexHull(); - renderPoly(graphics, color, objectClickbox); + renderPoly(graphics, borderColor, fillColor, objectClickbox); } if (config.highlightTile()) @@ -169,7 +165,7 @@ public class NpcSceneOverlay extends Overlay LocalPoint lp = actor.getLocalLocation(); Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); - renderPoly(graphics, color, tilePoly); + renderPoly(graphics, borderColor, fillColor, tilePoly); } if (config.highlightSouthWestTile()) @@ -182,12 +178,12 @@ public class NpcSceneOverlay extends Overlay Polygon southWestTilePoly = Perspective.getCanvasTilePoly(client, new LocalPoint(x, y)); - renderPoly(graphics, color, southWestTilePoly); + renderPoly(graphics, borderColor, fillColor, southWestTilePoly); } if (config.highlightOutline()) { - modelOutlineRenderer.drawOutline(actor, (int)config.borderWidth(), color, config.outlineFeather()); + modelOutlineRenderer.drawOutline(actor, (int)config.borderWidth(), borderColor, config.outlineFeather()); } if (config.drawNames() && actor.getName() != null) @@ -197,19 +193,19 @@ public class NpcSceneOverlay extends Overlay if (textLocation != null) { - OverlayUtil.renderTextLocation(graphics, textLocation, npcName, color); + OverlayUtil.renderTextLocation(graphics, textLocation, npcName, borderColor); } } } - private void renderPoly(Graphics2D graphics, Color color, Shape polygon) + private void renderPoly(Graphics2D graphics, Color borderColor, Color fillColor, Shape polygon) { if (polygon != null) { - graphics.setColor(color); + graphics.setColor(borderColor); graphics.setStroke(new BasicStroke((float) config.borderWidth())); graphics.draw(polygon); - graphics.setColor(ColorUtil.colorWithAlpha(color, 20)); + graphics.setColor(fillColor); graphics.fill(polygon); } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java index 9ccbcf3423..8fd814b491 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java @@ -122,7 +122,7 @@ public class NpcIndicatorsPluginTest { when(npcIndicatorsConfig.getNpcToHighlight()).thenReturn("goblin"); when(npcIndicatorsConfig.highlightMenuNames()).thenReturn(true); - when(npcIndicatorsConfig.getHighlightColor()).thenReturn(Color.BLUE); + when(npcIndicatorsConfig.highlightColor()).thenReturn(Color.BLUE); npcIndicatorsPlugin.rebuild(); From 36f97aa412c6da208e4d91e421071e6b27c71edf Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 12 Aug 2021 16:01:41 -0400 Subject: [PATCH 4/6] woodcutting: remove respawn timers from construction trees --- .../java/net/runelite/client/plugins/woodcutting/Tree.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java index 94105988b5..f6cc53254f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java @@ -58,9 +58,9 @@ import static net.runelite.api.ObjectID.YEW_36683; enum Tree { 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), + OAK_TREE(Duration.ofMillis(8500), OAK_TREE_4540, OAK_10820), WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), - MAPLE_TREE(Duration.ofSeconds(35), ObjectID.MAPLE_TREE, MAPLE_TREE_10832, MAPLE_TREE_36681) + MAPLE_TREE(Duration.ofSeconds(35), MAPLE_TREE_10832, MAPLE_TREE_36681) { @Override Duration getRespawnTime(int region) From 8fa085f4f9f2431ed92e2d7b5043e9b885a669fc Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 13 Aug 2021 13:04:56 -0400 Subject: [PATCH 5/6] ping: add macos support for icmp ping --- .../client/plugins/worldhopper/ping/Ping.java | 76 ++++++++++++++++--- .../plugins/worldhopper/ping/RLLibC.java | 5 +- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/Ping.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/Ping.java index 59f7eb85d4..2902017512 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/Ping.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/Ping.java @@ -29,6 +29,7 @@ import com.google.common.primitives.Bytes; import com.sun.jna.Memory; import com.sun.jna.Pointer; import java.io.IOException; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; @@ -43,6 +44,7 @@ public class Ping private static final byte[] RUNELITE_PING = "RuneLitePing".getBytes(Charsets.UTF_8); private static final int TIMEOUT = 2000; // ms private static final int PORT = 43594; + private static final int MAX_IPV4_HEADER_SIZE = 60; private static short seq; @@ -59,19 +61,27 @@ public class Ping return -1; } + if (!(inetAddress instanceof Inet4Address)) + { + log.debug("Only ipv4 ping is supported"); + return -1; + } + try { switch (OSType.getOSType()) { case Windows: return windowsPing(inetAddress); + case MacOS: case Linux: try { - return linuxPing(inetAddress); + return icmpPing(inetAddress, OSType.getOSType() == OSType.MacOS); } catch (Exception ex) { + log.debug("error during icmp ping", ex); return tcpPing(inetAddress); } default: @@ -111,7 +121,7 @@ public class Ping } } - private static int linuxPing(InetAddress inetAddress) throws IOException + private static int icmpPing(InetAddress inetAddress, boolean includeIpHeader) throws IOException { RLLibC libc = RLLibC.INSTANCE; byte[] address = inetAddress.getAddress(); @@ -137,12 +147,19 @@ public class Ping byte[] request = { 8, // type 8 - ipv4 echo request 0, // code - 0, 0, // checksum (set by kernel) - 0, 0, // id (set by kernel) + 0, 0, // checksum + 0, 0, // id - set by kernel on Linux. MacOS uses pid, however sending 0 appears to work fine. (byte) (((seqno >> 8) & 0xff)), (byte) (seqno & 0xff) }; // append payload request = Bytes.concat(request, RUNELITE_PING); + + final short checksum = checksum(request); + // on Linux the kernel automatically sets the checksum and ignores what we set, + // however it is required on MacOS + request[2] = (byte) ((checksum >> 8) & 0xff); + request[3] = (byte) (checksum & 0xff); + // struct sockaddr_in byte[] addr = { (byte) libc.AF_INET, 0, // sin_family @@ -151,21 +168,44 @@ public class Ping 0, 0, 0, 0, 0, 0, 0, 0 // padding }; + // response size/buffer + int size = 8 + RUNELITE_PING.length + // struct icmphdr + response + (includeIpHeader ? MAX_IPV4_HEADER_SIZE : 0); // struct ip + Memory response = new Memory(size); + long start = System.nanoTime(); if (libc.sendto(sock, request, request.length, 0, addr, addr.length) != request.length) { return -1; } - int size = 8 + RUNELITE_PING.length; // struct icmphdr + response - Memory response = new Memory(size); - if (libc.recvfrom(sock, response, size, 0, null, null) != size) + int rlen = libc.recvfrom(sock, response, size, 0, null, null); + long end = System.nanoTime(); + if (rlen <= 0) { return -1; } - long end = System.nanoTime(); - short seq = (short) (((response.getByte(6) & 0xff) << 8) | response.getByte(7) & 0xff); + int icmpHeaderOffset = 0; + if (includeIpHeader) + { + int ihl = response.getByte(0) & 0xf; + icmpHeaderOffset = ihl << 2; // to bytes + } + + if (icmpHeaderOffset + 7 >= rlen) + { + log.warn("packet too short (received {} bytes but icmp header offset is {})", rlen, icmpHeaderOffset); + return -1; + } + + if (response.getByte(icmpHeaderOffset) != 0) // ICMP type - echo reply + { + log.warn("non-echo reply"); + return -1; + } + + short seq = (short) (((response.getByte(icmpHeaderOffset + 6) & 0xff) << 8) | response.getByte(icmpHeaderOffset + 7) & 0xff); if (seqno != seq) { log.warn("sequence number mismatch ({} != {})", seqno, seq); @@ -180,6 +220,24 @@ public class Ping } } + // IP checksum + private static short checksum(byte[] data) + { + int a = 0; + for (int i = 0; i < data.length - 1; i += 2) + { + a += ((data[i] & 0xff) << 8) | (data[i + 1] & 0xff); + } + + if ((data.length & 1) != 0) + { + a += (data[data.length - 1] & 0xff) << 8; + } + + a = (a >> 16 & 0xffff) + (a & 0xffff); + return (short) (~a & 0xffff); + } + private static int tcpPing(InetAddress inetAddress) throws IOException { try (Socket socket = new Socket()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/RLLibC.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/RLLibC.java index 4692f04a71..f495ccff83 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/RLLibC.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/ping/RLLibC.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.worldhopper.ping; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.unix.LibC; +import net.runelite.client.util.OSType; interface RLLibC extends LibC { @@ -34,9 +35,9 @@ interface RLLibC extends LibC int AF_INET = 2; int SOCK_DGRAM = 2; - int SOL_SOCKET = 1; + int SOL_SOCKET = OSType.getOSType() == OSType.MacOS ? 0xffff : 1; int IPPROTO_ICMP = 1; - int SO_RCVTIMEO = 20; + int SO_RCVTIMEO = OSType.getOSType() == OSType.MacOS ? 0x1006 : 20; int socket(int domain, int type, int protocol); From 06b6f845e899fd1e23a2dfe54ec8debfe55b807b Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 13 Aug 2021 18:00:54 -0400 Subject: [PATCH 6/6] config manager: fsync temp config file --- .../net/runelite/client/config/ConfigManager.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 7e66bb0fdc..f06319c68f 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -44,6 +44,7 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; +import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.nio.file.AtomicMoveNotSupportedException; import java.nio.file.Files; @@ -374,11 +375,14 @@ public class ConfigManager File tempFile = File.createTempFile("runelite", null, parent); - try (FileOutputStream out = new FileOutputStream(tempFile)) + try (FileOutputStream out = new FileOutputStream(tempFile); + FileChannel channel = out.getChannel(); + OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) { - out.getChannel().lock(); - properties.store(new OutputStreamWriter(out, StandardCharsets.UTF_8), "RuneLite configuration"); - // FileOutputStream.close() closes the associated channel, which frees the lock + channel.lock(); + properties.store(writer, "RuneLite configuration"); + channel.force(true); + // FileChannel.close() frees the lock } try