Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/java/dinkplugin/DinkPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import dinkplugin.notifiers.LeaguesNotifier;
import dinkplugin.util.AccountTypeTracker;
import dinkplugin.util.KillCountService;
import dinkplugin.util.SlayerService;
import dinkplugin.util.Utils;
import dinkplugin.util.WorldTypeTracker;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -86,6 +87,7 @@ public class DinkPlugin extends Plugin {
private @Inject WorldTypeTracker worldTracker;

private @Inject KillCountService killCountService;
private @Inject SlayerService slayerService;

private @Inject CollectionNotifier collectionNotifier;
private @Inject PetNotifier petNotifier;
Expand Down Expand Up @@ -145,6 +147,7 @@ protected void shutDown() {
accountTracker.clear();
worldTracker.clear();
metaNotifier.reset();
slayerService.reset();
}

void resetNotifiers() {
Expand Down Expand Up @@ -263,6 +266,7 @@ public void onChatMessage(ChatMessage message) {
return;
}

slayerService.onGameMessage(chatMessage);
collectionNotifier.onChatMessage(chatMessage);
lootNotifier.onGameMessage(chatMessage);
petNotifier.onChatMessage(chatMessage);
Expand Down Expand Up @@ -319,6 +323,7 @@ public void onActorDeath(ActorDeath actor) {
@Subscribe
public void onInteractingChanged(InteractingChanged event) {
deathNotifier.onInteraction(event);
slayerService.onInteraction(event);
}

@Subscribe
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/dinkplugin/notifiers/LootNotifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import dinkplugin.notifiers.data.LootNotificationData;
import dinkplugin.notifiers.data.RareItemStack;
import dinkplugin.notifiers.data.SerializedItemStack;
import dinkplugin.notifiers.data.SlayerMetadata;
import dinkplugin.util.ConfigUtil;
import dinkplugin.util.ItemUtils;
import dinkplugin.util.KillCountService;
import dinkplugin.util.MathUtils;
import dinkplugin.util.ThievingService;
import dinkplugin.util.RarityService;
import dinkplugin.util.SlayerService;
import dinkplugin.util.ThievingService;
import dinkplugin.util.Utils;
import dinkplugin.util.WorldUtils;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -63,6 +65,9 @@ public class LootNotifier extends BaseNotifier {
@Inject
private RarityService rarityService;

@Inject
private SlayerService slayerService;

@Inject
private ThievingService thievingService;

Expand Down Expand Up @@ -303,6 +308,13 @@ private void handleNotify(Collection<ItemStack> items, String dropper, LootRecor
.orElse(null);
}

Boolean onTask = type == LootRecordType.NPC && slayerService.isTaskActive().filter(b -> b).isPresent()
? slayerService.getTargetName().filter(dropper::equals).isPresent()
: null;
SlayerMetadata slayerMetadata = onTask != null
? SlayerMetadata.from(onTask, slayerService.getRuneliteService())
: null;

String overrideUrl = getWebhookUrl();
if (config.lootRedirectPlayerKill() && !config.pkWebhook().isBlank()) {
if (type == LootRecordType.PLAYER || (type == LootRecordType.EVENT && "Loot Chest".equals(dropper))) {
Expand All @@ -328,7 +340,7 @@ private void handleNotify(Collection<ItemStack> items, String dropper, LootRecor
NotificationBody.builder()
.text(notifyMessage)
.embeds(embeds)
.extra(new LootNotificationData(serializedItems, dropper, type, kc, rarity, party, npcId))
.extra(new LootNotificationData(serializedItems, dropper, type, kc, rarity, party, npcId, slayerMetadata))
.type(NotificationType.LOOT)
.thumbnailUrl(ItemUtils.getItemImageUrl(max.getId()))
.build()
Expand Down
13 changes: 5 additions & 8 deletions src/main/java/dinkplugin/notifiers/SlayerNotifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,20 @@
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;

import javax.inject.Singleton;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static dinkplugin.util.SlayerService.BOSS_REGEX;
import static dinkplugin.util.SlayerService.SLAYER_COMPLETE_REGEX;
import static dinkplugin.util.SlayerService.SLAYER_TASK_REGEX;
import static dinkplugin.util.SlayerService.TASK_MONSTER_REGEX;

@Singleton
public class SlayerNotifier extends BaseNotifier {
private static final Pattern BOSS_REGEX = Pattern.compile("You are granted .+ Slayer XP for completing your boss task against(?: the)? (?<name>.+)\\.$");
@VisibleForTesting
static final Pattern SLAYER_TASK_REGEX = Pattern.compile("You have completed your task! You killed (?<task>[\\d,]+ [^.]+)\\..*");
private static final Pattern SLAYER_COMPLETE_REGEX = Pattern.compile("You've completed (?:at least )?(?<taskCount>[\\d,]+) (?:Wilderness )?tasks?(?: and received (?<points>[\\d,]+) points, giving you a total of [\\d,]+|\\.You'll be eligible to earn reward points if you complete tasks from a more advanced Slayer Master\\.| and reached the maximum amount of Slayer points \\((?<points2>[\\d,]+)\\))?");
private static final Pattern TASK_MONSTER_REGEX = Pattern.compile("^(?<count>\\d*)\\s*(?<monster>.+)$");

private final AtomicReference<String> slayerTask = new AtomicReference<>("");
private final AtomicInteger badTicks = new AtomicInteger(); // used to prevent notifs from using stale data

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ public class LootNotificationData extends NotificationData {
@Nullable
Integer npcId;

@Nullable
SlayerMetadata slayerMetadata;

@Override
public List<Field> getFields() {
List<Field> fields = new ArrayList<>(4);
List<Field> fields = new ArrayList<>(5);
if (killCount != null) {
fields.add(
new Field(
Expand All @@ -57,6 +60,10 @@ public List<Field> getFields() {
if (party != null && !party.isEmpty()) {
fields.add(new Field("Party Size", Field.formatBlock("", String.valueOf(party.size()))));
}
if (slayerMetadata != null) {
String slayerStatus = slayerMetadata.isOnTask() ? "On Task" : "Not on task";
fields.add(new Field("Slayer Status", Field.formatBlock("", slayerStatus)));
}
return fields;
}

Expand Down
28 changes: 28 additions & 0 deletions src/main/java/dinkplugin/notifiers/data/SlayerMetadata.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dinkplugin.notifiers.data;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.runelite.client.plugins.slayer.SlayerPluginService;
import org.jetbrains.annotations.Nullable;

@Data
@Setter(AccessLevel.NONE)
@RequiredArgsConstructor
@AllArgsConstructor
public class SlayerMetadata {
private final boolean onTask;
private @Nullable String task;
private @Nullable String taskLocation;
private @Nullable Integer initialAmount;
private @Nullable Integer remainingAmount;

public static SlayerMetadata from(boolean onTask, SlayerPluginService service) {
if (!onTask) {
return new SlayerMetadata(false);
}
return new SlayerMetadata(true, service.getTask(), service.getTaskLocation(), service.getInitialAmount(), service.getRemainingAmount());
}
}
82 changes: 82 additions & 0 deletions src/main/java/dinkplugin/util/SlayerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package dinkplugin.util;

import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.NPC;
import net.runelite.api.events.InteractingChanged;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.plugins.slayer.SlayerPlugin;
import net.runelite.client.plugins.slayer.SlayerPluginService;
import org.apache.commons.lang3.StringUtils;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.lang.ref.WeakReference;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

@Singleton
public class SlayerService {

public static final Pattern BOSS_REGEX = Pattern.compile("You are granted .+ Slayer XP for completing your boss task against(?: the)? (?<name>.+)\\.$");
public static final Pattern SLAYER_TASK_REGEX = Pattern.compile("You have completed your task! You killed (?<task>[\\d,]+ [^.]+)\\..*");
public static final Pattern SLAYER_COMPLETE_REGEX = Pattern.compile("You've completed (?:at least )?(?<taskCount>[\\d,]+) (?:Wilderness )?tasks?(?: and received (?<points>[\\d,]+) points, giving you a total of [\\d,]+|\\.You'll be eligible to earn reward points if you complete tasks from a more advanced Slayer Master\\.| and reached the maximum amount of Slayer points \\((?<points2>[\\d,]+)\\))?");
public static final Pattern TASK_MONSTER_REGEX = Pattern.compile("^(?<count>\\d*)\\s*(?<monster>.+)$");

private static final String RL_PLUGIN_CLASS_NAME = SlayerPlugin.class.getSimpleName().toLowerCase();

@Inject
private Client client;

@Inject
private ConfigManager configManager;

@Getter
@Inject
private SlayerPluginService runeliteService;

@Inject
private ScheduledExecutorService executor;

private boolean hasTask = false;
private WeakReference<NPC> slayerTarget = new WeakReference<>(null);

public void reset() {
this.hasTask = false;
this.slayerTarget.clear();
}

public void onGameMessage(String chatMessage) {
if (SLAYER_TASK_REGEX.matcher(chatMessage).matches() || SLAYER_COMPLETE_REGEX.matcher(chatMessage).matches()) {
executor.schedule(this::reset, 30, TimeUnit.SECONDS);
}
}

public void onInteraction(InteractingChanged event) {
if (event.getSource() != client.getLocalPlayer()) return;
if (!(event.getTarget() instanceof NPC)) return;

this.hasTask = StringUtils.isNotEmpty(runeliteService.getTask());
if (!hasTask) return;

NPC npc = (NPC) event.getTarget();
if (runeliteService.getTargets().contains(npc)) {
this.slayerTarget = new WeakReference<>(npc);
}
}

public Optional<Boolean> isTaskActive() {
return ConfigUtil.isPluginDisabled(configManager, RL_PLUGIN_CLASS_NAME)
? Optional.empty()
: Optional.of(this.hasTask);
}

public Optional<String> getTargetName() {
NPC npc = slayerTarget.get();
if (npc == null) return Optional.empty();
return Optional.ofNullable(npc.getName());
}

}
Loading