Merge remote-tracking branch 'runelite/master' into runelite

This commit is contained in:
Owain van Brakel
2021-02-25 06:09:44 +01:00
17 changed files with 415 additions and 54 deletions

View File

@@ -155,15 +155,15 @@ public enum ItemMapping
ITEM_ENSOULED_DRAGON_HEAD(ENSOULED_DRAGON_HEAD_13511, ENSOULED_DRAGON_HEAD),
// Imbued rings
ITEM_BERSERKER_RING(BERSERKER_RING, BERSERKER_RING_I),
ITEM_SEERS_RING(SEERS_RING, SEERS_RING_I),
ITEM_WARRIOR_RING(WARRIOR_RING, WARRIOR_RING_I),
ITEM_ARCHERS_RING(ARCHERS_RING, ARCHERS_RING_I),
ITEM_TREASONOUS_RING(TREASONOUS_RING, TREASONOUS_RING_I),
ITEM_TYRANNICAL_RING(TYRANNICAL_RING, TYRANNICAL_RING_I),
ITEM_RING_OF_THE_GODS(RING_OF_THE_GODS, RING_OF_THE_GODS_I),
ITEM_RING_OF_SUFFERING(RING_OF_SUFFERING, RING_OF_SUFFERING_I, RING_OF_SUFFERING_R, RING_OF_SUFFERING_RI),
ITEM_GRANITE_RING(GRANITE_RING, GRANITE_RING_I),
ITEM_BERSERKER_RING(BERSERKER_RING, BERSERKER_RING_I, BERSERKER_RING_I_25264),
ITEM_SEERS_RING(SEERS_RING, SEERS_RING_I, SEERS_RING_I_25258),
ITEM_WARRIOR_RING(WARRIOR_RING, WARRIOR_RING_I, WARRIOR_RING_I_25262),
ITEM_ARCHERS_RING(ARCHERS_RING, ARCHERS_RING_I, ARCHERS_RING_I_25260),
ITEM_TREASONOUS_RING(TREASONOUS_RING, TREASONOUS_RING_I, TREASONOUS_RING_I_25256),
ITEM_TYRANNICAL_RING(TYRANNICAL_RING, TYRANNICAL_RING_I, TYRANNICAL_RING_I_25254),
ITEM_RING_OF_THE_GODS(RING_OF_THE_GODS, RING_OF_THE_GODS_I, RING_OF_THE_GODS_I_25252),
ITEM_RING_OF_SUFFERING(RING_OF_SUFFERING, RING_OF_SUFFERING_I, RING_OF_SUFFERING_R, RING_OF_SUFFERING_RI, RING_OF_SUFFERING_I_25246, RING_OF_SUFFERING_RI_25248),
ITEM_GRANITE_RING(GRANITE_RING, GRANITE_RING_I, GRANITE_RING_I_25193),
// Bounty hunter
ITEM_GRANITE_MAUL(GRANITE_MAUL, GRANITE_MAUL_12848),
@@ -227,7 +227,9 @@ public enum ItemMapping
BLACK_MASK, BLACK_MASK_I, BLACK_MASK_1, BLACK_MASK_1_I, BLACK_MASK_2, BLACK_MASK_2_I, BLACK_MASK_3, BLACK_MASK_3_I, BLACK_MASK_4, BLACK_MASK_4_I, BLACK_MASK_5,
BLACK_MASK_5_I, BLACK_MASK_6, BLACK_MASK_6_I, BLACK_MASK_7, BLACK_MASK_7_I, BLACK_MASK_8, BLACK_MASK_8_I, BLACK_MASK_9, BLACK_MASK_9_I, BLACK_MASK_10_I,
SLAYER_HELMET, SLAYER_HELMET_I, BLACK_SLAYER_HELMET, BLACK_SLAYER_HELMET_I, PURPLE_SLAYER_HELMET, PURPLE_SLAYER_HELMET_I, RED_SLAYER_HELMET, RED_SLAYER_HELMET_I,
GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I, TWISTED_SLAYER_HELMET, TWISTED_SLAYER_HELMET_I, HYDRA_SLAYER_HELMET, HYDRA_SLAYER_HELMET_I),
GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I, TWISTED_SLAYER_HELMET, TWISTED_SLAYER_HELMET_I, HYDRA_SLAYER_HELMET, HYDRA_SLAYER_HELMET_I,
SLAYER_HELMET_I_25177, BLACK_SLAYER_HELMET_I_25179, GREEN_SLAYER_HELMET_I_25181, RED_SLAYER_HELMET_I_25183, PURPLE_SLAYER_HELMET_I_25185, TURQUOISE_SLAYER_HELMET_I_25187, HYDRA_SLAYER_HELMET_I_25189, TWISTED_SLAYER_HELMET_I_25191,
BLACK_MASK_I_25276, BLACK_MASK_1_I_25275, BLACK_MASK_2_I_25274, BLACK_MASK_3_I_25273, BLACK_MASK_4_I_25272, BLACK_MASK_5_I_25271, BLACK_MASK_6_I_25270, BLACK_MASK_7_I_25269, BLACK_MASK_8_I_25268, BLACK_MASK_9_I_25267, BLACK_MASK_10_I_25266),
// Pharaoh's Sceptres
ITEM_PHARAOHS_SCEPTRE_1(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_1),
@@ -245,7 +247,7 @@ public enum ItemMapping
ITEM_BOTTOMLESS_COMPOST_BUCKET(BOTTOMLESS_COMPOST_BUCKET, BOTTOMLESS_COMPOST_BUCKET_22997),
ITEM_BASILISK_JAW(BASILISK_JAW, NEITIZNOT_FACEGUARD),
ITEM_HELM_OF_NEITIZNOT(HELM_OF_NEITIZNOT, NEITIZNOT_FACEGUARD),
ITEM_TWISTED_HORNS(TWISTED_HORNS, TWISTED_SLAYER_HELMET, TWISTED_SLAYER_HELMET_I),
ITEM_TWISTED_HORNS(TWISTED_HORNS, TWISTED_SLAYER_HELMET, TWISTED_SLAYER_HELMET_I, TWISTED_SLAYER_HELMET_I_25191),
ITEM_ELDRITCH_ORB(ELDRITCH_ORB, ELDRITCH_NIGHTMARE_STAFF),
ITEM_HARMONISED_ORB(HARMONISED_ORB, HARMONISED_NIGHTMARE_STAFF),
ITEM_VOLATILE_ORB(VOLATILE_ORB, VOLATILE_NIGHTMARE_STAFF),

View File

@@ -140,8 +140,8 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
new EmoteClue("Panic by the pilot on White Wolf Mountain. Beware of double agents! Equip mithril platelegs, a ring of life and a rune axe.", "White Wolf Mountain", GNOME_GLIDER_ON_WHITE_WOLF_MOUNTAIN, new WorldPoint(2847, 3499, 0), DOUBLE_AGENT_108, PANIC, item(MITHRIL_PLATELEGS), item(RING_OF_LIFE), item(RUNE_AXE)),
new EmoteClue("Panic by the big egg where no one dare goes and the ground is burnt. Beware of double agents! Equip a dragon med helm, a TokTz-Ket-Xil, a brine sabre, rune platebody and an uncharged amulet of glory.", "Lava dragon isle", SOUTHEAST_CORNER_OF_LAVA_DRAGON_ISLE, new WorldPoint(3227, 3831, 0), DOUBLE_AGENT_141, PANIC, item(DRAGON_MED_HELM), item(TOKTZKETXIL), item(BRINE_SABRE), item(RUNE_PLATEBODY), any("Uncharged Amulet of glory", item(AMULET_OF_GLORY))),
new EmoteClue("Panic at the area flowers meet snow. Equip Blue D'hide vambraces, a dragon spear and a rune plateskirt.", "Trollweiss mountain", HALFWAY_DOWN_TROLLWEISS_MOUNTAIN, new WorldPoint(2776, 3781, 0), PANIC, item(BLUE_DHIDE_VAMBRACES), item(DRAGON_SPEAR), item(RUNE_PLATESKIRT), item(SLED_4084)),
new EmoteClue("Do a push up at the bank of the Warrior's guild. Beware of double agents! Equip a dragon battleaxe, a dragon defender and a slayer helm of any kind.", "Warriors' guild", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), DOUBLE_AGENT_141, PUSH_UP, item(DRAGON_BATTLEAXE), any("Dragon defender", item(DRAGON_DEFENDER), item(DRAGON_DEFENDER_T), item(DRAGON_DEFENDER_L)), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I), item(HYDRA_SLAYER_HELMET), item(HYDRA_SLAYER_HELMET_I), item(TWISTED_SLAYER_HELMET), item(TWISTED_SLAYER_HELMET_I))),
new EmoteClue("Blow a raspberry in the bank of the Warriors' Guild. Beware of double agents! Equip a dragon battleaxe, a slayer helm of any kind and a dragon defender or avernic defender.", "Warriors' guild", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), DOUBLE_AGENT_141, RASPBERRY, item(DRAGON_BATTLEAXE), any("Dragon defender or Avernic defender", item(DRAGON_DEFENDER), item(DRAGON_DEFENDER_T), item(DRAGON_DEFENDER_L), item(AVERNIC_DEFENDER), item(AVERNIC_DEFENDER_L)), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I), item(HYDRA_SLAYER_HELMET), item(HYDRA_SLAYER_HELMET_I), item(TWISTED_SLAYER_HELMET), item(TWISTED_SLAYER_HELMET_I))),
new EmoteClue("Do a push up at the bank of the Warrior's guild. Beware of double agents! Equip a dragon battleaxe, a dragon defender and a slayer helm of any kind.", "Warriors' guild", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), DOUBLE_AGENT_141, PUSH_UP, item(DRAGON_BATTLEAXE), any("Dragon defender", item(DRAGON_DEFENDER), item(DRAGON_DEFENDER_T), item(DRAGON_DEFENDER_L)), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I), item(HYDRA_SLAYER_HELMET), item(HYDRA_SLAYER_HELMET_I), item(TWISTED_SLAYER_HELMET), item(TWISTED_SLAYER_HELMET_I), item(SLAYER_HELMET_I_25177), item(BLACK_SLAYER_HELMET_I_25179), item(GREEN_SLAYER_HELMET_I_25181), item(RED_SLAYER_HELMET_I_25183), item(PURPLE_SLAYER_HELMET_I_25185), item(TURQUOISE_SLAYER_HELMET_I_25187), item(HYDRA_SLAYER_HELMET_I_25189), item(TWISTED_SLAYER_HELMET_I_25191))),
new EmoteClue("Blow a raspberry in the bank of the Warriors' Guild. Beware of double agents! Equip a dragon battleaxe, a slayer helm of any kind and a dragon defender or avernic defender.", "Warriors' guild", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), DOUBLE_AGENT_141, RASPBERRY, item(DRAGON_BATTLEAXE), any("Dragon defender or Avernic defender", item(DRAGON_DEFENDER), item(DRAGON_DEFENDER_T), item(DRAGON_DEFENDER_L), item(AVERNIC_DEFENDER), item(AVERNIC_DEFENDER_L)), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I), item(HYDRA_SLAYER_HELMET), item(HYDRA_SLAYER_HELMET_I), item(TWISTED_SLAYER_HELMET), item(TWISTED_SLAYER_HELMET_I), item(SLAYER_HELMET_I_25177), item(BLACK_SLAYER_HELMET_I_25179), item(GREEN_SLAYER_HELMET_I_25181), item(RED_SLAYER_HELMET_I_25183), item(PURPLE_SLAYER_HELMET_I_25185), item(TURQUOISE_SLAYER_HELMET_I_25187), item(HYDRA_SLAYER_HELMET_I_25189), item(TWISTED_SLAYER_HELMET_I_25191))),
new EmoteClue("Blow a raspberry at the monkey cage in Ardougne Zoo. Equip a studded leather body, bronze platelegs and a normal staff with no orb.", "Ardougne Zoo", NEAR_THE_PARROTS_IN_ARDOUGNE_ZOO, new WorldPoint(2607, 3282, 0), RASPBERRY, item(STUDDED_BODY), item(BRONZE_PLATELEGS), item(STAFF)),
new EmoteClue("Blow raspberries outside the entrance to Keep Le Faye. Equip a coif, an iron platebody and leather gloves.", "Keep Le Faye", OUTSIDE_KEEP_LE_FAYE, new WorldPoint(2757, 3401, 0), RASPBERRY, item(COIF), item(IRON_PLATEBODY), item(LEATHER_GLOVES)),
new EmoteClue("Blow a raspberry in the Fishing Guild bank. Beware of double agents! Equip an elemental shield, blue dragonhide chaps and a rune warhammer.", "Fishing Guild", FISHING_GUILD_BANK, new WorldPoint(2588, 3419, 0), DOUBLE_AGENT_108, RASPBERRY, item(ELEMENTAL_SHIELD), item(BLUE_DHIDE_CHAPS), item(RUNE_WARHAMMER)),

View File

@@ -146,7 +146,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam
new SkillChallengeClue("Steal from a chest in Ardougne Castle."),
new SkillChallengeClue("Craft a green dragonhide body.", xOfItem(ItemID.GREEN_DRAGON_LEATHER, 3), item(ItemID.NEEDLE), item(ItemID.THREAD)),
new SkillChallengeClue("String a yew longbow.", item(ItemID.YEW_LONGBOW_U), item(ItemID.BOW_STRING)),
new SkillChallengeClue("Kill a Dust Devil.", "slay a dust devil.", true, any("Facemask or Slayer Helmet", item(ItemID.FACEMASK), item(ItemID.SLAYER_HELMET), item(ItemID. SLAYER_HELMET_I), item(ItemID. BLACK_SLAYER_HELMET), item(ItemID. BLACK_SLAYER_HELMET_I), item(ItemID. PURPLE_SLAYER_HELMET), item(ItemID. PURPLE_SLAYER_HELMET_I), item(ItemID. RED_SLAYER_HELMET), item(ItemID. RED_SLAYER_HELMET_I), item(ItemID.GREEN_SLAYER_HELMET), item(ItemID. GREEN_SLAYER_HELMET_I), item(ItemID. TURQUOISE_SLAYER_HELMET), item(ItemID. TURQUOISE_SLAYER_HELMET_I), item(ItemID. HYDRA_SLAYER_HELMET), item(ItemID. HYDRA_SLAYER_HELMET_I), item(ItemID.TWISTED_SLAYER_HELMET), item(ItemID.TWISTED_SLAYER_HELMET_I))),
new SkillChallengeClue("Kill a Dust Devil.", "slay a dust devil.", true, any("Facemask or Slayer Helmet", item(ItemID.FACEMASK), item(ItemID.SLAYER_HELMET), item(ItemID. SLAYER_HELMET_I), item(ItemID. BLACK_SLAYER_HELMET), item(ItemID. BLACK_SLAYER_HELMET_I), item(ItemID. PURPLE_SLAYER_HELMET), item(ItemID. PURPLE_SLAYER_HELMET_I), item(ItemID. RED_SLAYER_HELMET), item(ItemID. RED_SLAYER_HELMET_I), item(ItemID.GREEN_SLAYER_HELMET), item(ItemID. GREEN_SLAYER_HELMET_I), item(ItemID. TURQUOISE_SLAYER_HELMET), item(ItemID. TURQUOISE_SLAYER_HELMET_I), item(ItemID. HYDRA_SLAYER_HELMET), item(ItemID. HYDRA_SLAYER_HELMET_I), item(ItemID.TWISTED_SLAYER_HELMET), item(ItemID.TWISTED_SLAYER_HELMET_I), item(ItemID.SLAYER_HELMET_I_25177), item(ItemID.BLACK_SLAYER_HELMET_I_25179), item(ItemID.GREEN_SLAYER_HELMET_I_25181), item(ItemID.RED_SLAYER_HELMET_I_25183), item(ItemID.PURPLE_SLAYER_HELMET_I_25185), item(ItemID.TURQUOISE_SLAYER_HELMET_I_25187), item(ItemID.HYDRA_SLAYER_HELMET_I_25189), item(ItemID.TWISTED_SLAYER_HELMET_I_25191))),
new SkillChallengeClue("Catch a black warlock.", item(ItemID.BUTTERFLY_JAR), any("Butterfly Net", item(ItemID.BUTTERFLY_NET), item(ItemID.MAGIC_BUTTERFLY_NET))),
new SkillChallengeClue("Catch a red chinchompa.", item(ItemID.BOX_TRAP)),
new SkillChallengeClue("Mine a mithril ore.", ANY_PICKAXE),

View File

@@ -705,7 +705,7 @@ public class MusicPlugin extends Plugin
return;
}
int arg = client.getIntStackSize() - 7;
int arg = client.getIntStackSize() - 8;
int[] is = client.getIntStack();
Channel channel;
switch (is[arg])

View File

@@ -52,20 +52,28 @@ class SlayerOverlay extends WidgetItemOverlay
private final static Set<Integer> ALL_SLAYER_ITEMS = ImmutableSet.of(
ItemID.SLAYER_HELMET,
ItemID.SLAYER_HELMET_I,
ItemID.SLAYER_HELMET_I_25177,
ItemID.BLACK_SLAYER_HELMET,
ItemID.BLACK_SLAYER_HELMET_I,
ItemID.BLACK_SLAYER_HELMET_I_25179,
ItemID.GREEN_SLAYER_HELMET,
ItemID.GREEN_SLAYER_HELMET_I,
ItemID.GREEN_SLAYER_HELMET_I_25181,
ItemID.PURPLE_SLAYER_HELMET,
ItemID.PURPLE_SLAYER_HELMET_I,
ItemID.PURPLE_SLAYER_HELMET_I_25185,
ItemID.RED_SLAYER_HELMET,
ItemID.RED_SLAYER_HELMET_I,
ItemID.RED_SLAYER_HELMET_I_25183,
ItemID.TURQUOISE_SLAYER_HELMET,
ItemID.TURQUOISE_SLAYER_HELMET_I,
ItemID.TURQUOISE_SLAYER_HELMET_I_25187,
ItemID.TWISTED_SLAYER_HELMET,
ItemID.TWISTED_SLAYER_HELMET_I,
ItemID.TWISTED_SLAYER_HELMET_I_25191,
ItemID.HYDRA_SLAYER_HELMET,
ItemID.HYDRA_SLAYER_HELMET_I,
ItemID.HYDRA_SLAYER_HELMET_I_25189,
ItemID.SLAYER_RING_ETERNAL,
ItemID.ENCHANTED_GEM,
ItemID.ETERNAL_GEM,

View File

@@ -24,6 +24,8 @@
*/
package net.runelite.client.plugins.worldhopper.ping;
import com.google.common.base.Charsets;
import com.google.common.primitives.Bytes;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import java.io.IOException;
@@ -38,21 +40,42 @@ import net.runelite.http.api.worlds.World;
@Slf4j
public class Ping
{
private static final String RUNELITE_PING = "RuneLitePing";
private static final int TIMEOUT = 2000;
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 short seq;
public static int ping(World world)
{
InetAddress inetAddress;
try
{
inetAddress = InetAddress.getByName(world.getAddress());
}
catch (UnknownHostException ex)
{
log.warn("error resolving host for world ping", ex);
return -1;
}
try
{
switch (OSType.getOSType())
{
case Windows:
return windowsPing(world);
return windowsPing(inetAddress);
case Linux:
try
{
return linuxPing(inetAddress);
}
catch (Exception ex)
{
return tcpPing(inetAddress);
}
default:
return tcpPing(world);
return tcpPing(inetAddress);
}
}
catch (IOException ex)
@@ -62,22 +85,19 @@ public class Ping
}
}
private static int windowsPing(World world) throws UnknownHostException
private static int windowsPing(InetAddress inetAddress)
{
IPHlpAPI ipHlpAPI = IPHlpAPI.INSTANCE;
Pointer ptr = ipHlpAPI.IcmpCreateFile();
try
{
InetAddress inetAddress = InetAddress.getByName(world.getAddress());
byte[] address = inetAddress.getAddress();
String dataStr = RUNELITE_PING;
int dataLength = dataStr.length() + 1;
Pointer data = new Memory(dataLength);
data.setString(0L, dataStr);
IcmpEchoReply icmpEchoReply = new IcmpEchoReply(new Memory(IcmpEchoReply.SIZE + dataLength));
Memory data = new Memory(RUNELITE_PING.length);
data.write(0, RUNELITE_PING, 0, RUNELITE_PING.length);
IcmpEchoReply icmpEchoReply = new IcmpEchoReply(new Memory(IcmpEchoReply.SIZE + data.size()));
assert icmpEchoReply.size() == IcmpEchoReply.SIZE;
int packed = (address[0] & 0xff) | ((address[1] & 0xff) << 8) | ((address[2] & 0xff) << 16) | ((address[3] & 0xff) << 24);
int ret = ipHlpAPI.IcmpSendEcho(ptr, packed, data, (short) (dataLength), Pointer.NULL, icmpEchoReply, IcmpEchoReply.SIZE + dataLength, TIMEOUT);
int ret = ipHlpAPI.IcmpSendEcho(ptr, packed, data, (short) data.size(), Pointer.NULL, icmpEchoReply, IcmpEchoReply.SIZE + (int) data.size(), TIMEOUT);
if (ret != 1)
{
return -1;
@@ -91,12 +111,80 @@ public class Ping
}
}
private static int tcpPing(World world) throws IOException
private static int linuxPing(InetAddress inetAddress) throws IOException
{
RLLibC libc = RLLibC.INSTANCE;
byte[] address = inetAddress.getAddress();
int sock = libc.socket(libc.AF_INET, libc.SOCK_DGRAM, libc.IPPROTO_ICMP);
if (sock < 0)
{
throw new IOException("failed to open ICMP socket");
}
try
{
Timeval tv = new Timeval();
tv.tv_sec = TIMEOUT / 1000;
if (libc.setsockopt(sock, libc.SOL_SOCKET, libc.SO_RCVTIMEO, tv.getPointer(), tv.size()) < 0)
{
throw new IOException("failed to set SO_RCVTIMEO");
}
short seqno = seq++;
// struct icmphdr
byte[] request = {
8, // type 8 - ipv4 echo request
0, // code
0, 0, // checksum (set by kernel)
0, 0, // id (set by kernel)
(byte) (((seqno >> 8) & 0xff)), (byte) (seqno & 0xff)
};
// append payload
request = Bytes.concat(request, RUNELITE_PING);
// struct sockaddr_in
byte[] addr = {
(byte) libc.AF_INET, 0, // sin_family
0, 0, // sin_port
address[0], address[1], address[2], address[3], // sin_addr.s_addr
0, 0, 0, 0, 0, 0, 0, 0 // padding
};
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)
{
return -1;
}
long end = System.nanoTime();
short seq = (short) (((response.getByte(6) & 0xff) << 8) | response.getByte(7) & 0xff);
if (seqno != seq)
{
log.warn("sequence number mismatch ({} != {})", seqno, seq);
return -1;
}
return (int) ((end - start) / 1_000_000);
}
finally
{
libc.close(sock);
}
}
private static int tcpPing(InetAddress inetAddress) throws IOException
{
try (Socket socket = new Socket())
{
socket.setSoTimeout(TIMEOUT);
InetAddress inetAddress = InetAddress.getByName(world.getAddress());
long start = System.nanoTime();
socket.connect(new InetSocketAddress(inetAddress, PORT));
long end = System.nanoTime();

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2021, 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.worldhopper.ping;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.unix.LibC;
interface RLLibC extends LibC
{
RLLibC INSTANCE = Native.loadLibrary(NAME, RLLibC.class);
int AF_INET = 2;
int SOCK_DGRAM = 2;
int SOL_SOCKET = 1;
int IPPROTO_ICMP = 1;
int SO_RCVTIMEO = 20;
int socket(int domain, int type, int protocol);
void close(int socket);
int sendto(int sockfd, byte[] buf, int len, int flags, byte[] dest_addr, int addrlen);
int recvfrom(int sockfd, Pointer buf, int len, int flags, Pointer src_addr, Pointer addrlen);
int setsockopt(int sockfd, int level, int optname, Pointer optval, int optlen);
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021, 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.worldhopper.ping;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.List;
public class Timeval extends Structure
{
public long tv_sec;
public long tv_usec;
@Override
protected List<String> getFieldOrder()
{
return Arrays.asList("tv_sec", "tv_usec");
}
}