From 129ccd2de9ad9eadfd2b2527e589514b6f7f50b7 Mon Sep 17 00:00:00 2001 From: Ganom Date: Sun, 1 Dec 2019 01:09:27 -0500 Subject: [PATCH] playermanager: add. (#1952) * playermanager: add. playerscouter: update to use new player manager. playerscouter: add minify option. * playermanager: use concurrent maps over standard hash maps. * playermanager: add attackStyleChanged event. * playermanager: add all attacking method. * prayagainst: completely rework it to use playerManager. playermanager: add friend/clan methods. * playermanager: utilize new event rather than gametick. * playermanager: remove gam tick update. * playermanager: remove gametick method reference. * hideunder: use playermanager. * equipmentinspector: use playermanager. * events: add new docs. * playermanager: add combat stats sub-class. * playermanager: add timeout to updateStats * playermanager: gamepack update. * playermanager: remove debugging. * playerscouter: remove unused import --- .../api/events/PlayerAppearanceChanged.java | 13 + .../java/net/runelite/client/RuneLite.java | 5 + .../client/events/AttackStyleChanged.java | 34 ++ .../AttackStyle.java} | 32 +- .../net/runelite/client/game/CombatStats.java | 24 + .../PlayerContainer.java | 52 +- .../runelite/client/game/PlayerManager.java | 551 ++++++++++++++++++ .../EquipmentInspectorConfig.java | 10 +- .../EquipmentInspectorPlugin.java | 271 ++++----- .../client/plugins/hideunder/HideUnder.java | 136 +---- .../plugins/playerscouter/PlayerScouter.java | 403 ++++--------- .../playerscouter/PlayerScouterConfig.java | 12 + .../prayagainstplayer/PlayerContainer.java | 64 -- .../PrayAgainstPlayerConfig.java | 170 +----- .../PrayAgainstPlayerOverlay.java | 197 +------ .../PrayAgainstPlayerOverlayPrayerTab.java | 75 +-- .../PrayAgainstPlayerPlugin.java | 352 +---------- .../plugins/prayagainstplayer/WeaponType.java | 140 ----- .../net/runelite/mixins/RSPlayerMixin.java | 18 + .../runelite/rs/api/RSPlayerAppearance.java | 3 + .../src/main/java/PlayerAppearance.java | 60 +- 21 files changed, 1048 insertions(+), 1574 deletions(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/events/PlayerAppearanceChanged.java create mode 100644 runelite-client/src/main/java/net/runelite/client/events/AttackStyleChanged.java rename runelite-client/src/main/java/net/runelite/client/{plugins/hideunder/PlayerContainer.java => game/AttackStyle.java} (75%) create mode 100644 runelite-client/src/main/java/net/runelite/client/game/CombatStats.java rename runelite-client/src/main/java/net/runelite/client/{plugins/playerscouter => game}/PlayerContainer.java (74%) create mode 100644 runelite-client/src/main/java/net/runelite/client/game/PlayerManager.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java diff --git a/runelite-api/src/main/java/net/runelite/api/events/PlayerAppearanceChanged.java b/runelite-api/src/main/java/net/runelite/api/events/PlayerAppearanceChanged.java new file mode 100644 index 0000000000..501b5664a2 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/PlayerAppearanceChanged.java @@ -0,0 +1,13 @@ +package net.runelite.api.events; + +import lombok.Value; +import net.runelite.api.Player; + +/** + * This will fire whenever the {@link net.runelite.api.PlayerAppearance} hash changes. + */ +@Value +public class PlayerAppearanceChanged implements Event +{ + private Player player; +} diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 924de7ca81..3ba63b48fa 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -62,6 +62,7 @@ import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ClanManager; import net.runelite.client.game.ItemManager; import net.runelite.client.game.LootManager; +import net.runelite.client.game.PlayerManager; import net.runelite.client.game.XpDropManager; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.graphics.ModelOutlineRenderer; @@ -158,6 +159,9 @@ public class RuneLite @Inject private Provider xpDropManager; + @Inject + private Provider playerManager; + @Inject private Provider chatboxPanelManager; @@ -366,6 +370,7 @@ public class RuneLite commandManager.get(); lootManager.get(); xpDropManager.get(); + playerManager.get(); chatboxPanelManager.get(); eventBus.subscribe(GameStateChanged.class, this, hooks::onGameStateChanged); diff --git a/runelite-client/src/main/java/net/runelite/client/events/AttackStyleChanged.java b/runelite-client/src/main/java/net/runelite/client/events/AttackStyleChanged.java new file mode 100644 index 0000000000..59aad57147 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/events/AttackStyleChanged.java @@ -0,0 +1,34 @@ +package net.runelite.client.events; + +import lombok.Value; +import net.runelite.api.Player; +import net.runelite.api.events.Event; +import net.runelite.client.game.AttackStyle; + +/** + * This will fire when {@link net.runelite.client.game.PlayerManager} detects + * a change in the player appearance that resulted in the shifting of an attack style. + * For example, ranged str went to 0, but melee str went to 108. + */ +@Value +public class AttackStyleChanged implements Event +{ + /** + * The player that changed styles. + */ + private final Player player; + + /** + * Can be Unknown(nullable) + * + * @see net.runelite.client.game.AttackStyle + */ + private final AttackStyle oldStyle; + + /** + * Can be Unknown(nullable) + * + * @see net.runelite.client.game.AttackStyle + */ + private final AttackStyle newStyle; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideunder/PlayerContainer.java b/runelite-client/src/main/java/net/runelite/client/game/AttackStyle.java similarity index 75% rename from runelite-client/src/main/java/net/runelite/client/plugins/hideunder/PlayerContainer.java rename to runelite-client/src/main/java/net/runelite/client/game/AttackStyle.java index c1393f19a5..65e110e59b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hideunder/PlayerContainer.java +++ b/runelite-client/src/main/java/net/runelite/client/game/AttackStyle.java @@ -21,25 +21,23 @@ * (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.hideunder; +package net.runelite.client.game; -import lombok.AccessLevel; +import java.awt.Color; +import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.Setter; -import net.runelite.api.Player; +import net.runelite.api.Prayer; -@Getter(AccessLevel.PACKAGE) -@Setter(AccessLevel.PACKAGE) -class PlayerContainer +@AllArgsConstructor +@Getter +public enum AttackStyle { - private Player player; - private boolean target; - private int timer; + MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC), + RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES), + MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE), + UNKNOWN("Unknown", Color.WHITE, null); - PlayerContainer(Player player) - { - this.player = player; - this.target = false; - this.timer = 0; - } -} \ No newline at end of file + private String name; + private Color color; + private Prayer prayer; +} diff --git a/runelite-client/src/main/java/net/runelite/client/game/CombatStats.java b/runelite-client/src/main/java/net/runelite/client/game/CombatStats.java new file mode 100644 index 0000000000..3f940b5e41 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/CombatStats.java @@ -0,0 +1,24 @@ +package net.runelite.client.game; + +import lombok.Value; + +@Value +public class CombatStats +{ + private int magicAttack; + private int magicDefence; + private int magicStr; + private int meleeAtkCrush; + private int meleeAtkSlash; + private int meleeAtkStab; + private int meleeAttack; + private int meleeDefCrush; + private int meleeDefence; + private int meleeDefSlash; + private int meleeDefStab; + private int meleeStr; + private int rangeAttack; + private int rangeDefence; + private int rangeStr; + private int speed; +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerContainer.java b/runelite-client/src/main/java/net/runelite/client/game/PlayerContainer.java similarity index 74% rename from runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerContainer.java rename to runelite-client/src/main/java/net/runelite/client/game/PlayerContainer.java index f159a1efb3..60e54e28a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerContainer.java +++ b/runelite-client/src/main/java/net/runelite/client/game/PlayerContainer.java @@ -21,7 +21,7 @@ * (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.playerscouter; +package net.runelite.client.game; import java.util.LinkedHashMap; import lombok.AccessLevel; @@ -31,41 +31,73 @@ import lombok.ToString; import net.runelite.api.Player; import net.runelite.http.api.hiscore.HiscoreResult; -@Getter(AccessLevel.PACKAGE) -@Setter(AccessLevel.PACKAGE) +@Getter +@Setter @ToString(exclude = "player") -class PlayerContainer +public class PlayerContainer { + private AttackStyle attackStyle; + private AttackStyle weakness; private HiscoreResult skills; private LinkedHashMap gear; private LinkedHashMap riskedGear; + private MeleeStyle meleeStyle; private Player player; private String location; private String name; private String targetString; + private CombatStats combatStats; private boolean httpRetry; private boolean scouted; - private int prayer; + private boolean attacking; + private boolean friend; + private boolean clan; + private int hpLevel; + private int potionBoost; + private int prayerLevel; private int risk; private int scoutTimer; + private int shield; + private int timer; private int weapon; private int wildyLevel; PlayerContainer(Player player) { + this.attackStyle = AttackStyle.UNKNOWN; this.gear = new LinkedHashMap<>(); - this.httpRetry = false; + this.hpLevel = 0; this.location = "N/A"; + this.meleeStyle = MeleeStyle.STAB; this.name = player.getName(); this.player = player; - this.prayer = -1; - this.risk = 0; this.riskedGear = new LinkedHashMap<>(); this.scoutTimer = 500; this.scouted = false; this.skills = null; this.targetString = ""; - this.weapon = 0; - this.wildyLevel = 0; + this.weakness = AttackStyle.UNKNOWN; + } + + void reset() + { + setMeleeStyle(MeleeStyle.NONE); + if (getTimer() > 0) + { + setTimer(getTimer() - 1); + if (getTimer() == 0) + { + setAttacking(false); + } + } + } + + @Getter(AccessLevel.PACKAGE) + enum MeleeStyle + { + CRUSH, + SLASH, + STAB, + NONE } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/game/PlayerManager.java b/runelite-client/src/main/java/net/runelite/client/game/PlayerManager.java new file mode 100644 index 0000000000..df728e19ad --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/PlayerManager.java @@ -0,0 +1,551 @@ +package net.runelite.client.game; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Actor; +import net.runelite.api.Client; +import net.runelite.api.ItemDefinition; +import net.runelite.api.ItemID; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.PlayerAppearanceChanged; +import net.runelite.api.events.PlayerDespawned; +import net.runelite.api.events.PlayerSpawned; +import net.runelite.api.kit.KitType; +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.eventbus.EventScheduler; +import net.runelite.client.events.AttackStyleChanged; +import net.runelite.client.util.PvPUtil; +import net.runelite.http.api.hiscore.HiscoreClient; +import net.runelite.http.api.hiscore.HiscoreResult; +import net.runelite.http.api.item.ItemEquipmentStats; +import net.runelite.http.api.item.ItemStats; + +@Singleton +@Slf4j +@SuppressWarnings("unused") +public class PlayerManager +{ + private static final HiscoreClient HISCORE_CLIENT = new HiscoreClient(); + private final Client client; + private final ItemManager itemManager; + private final EventBus eventBus; + private final Map playerMap = new ConcurrentHashMap<>(); + private final Map resultCache = new ConcurrentHashMap<>(); + private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); + + @Inject + PlayerManager( + final Client client, + final EventBus eventBus, + final ItemManager itemManager + ) + { + this.client = client; + this.itemManager = itemManager; + this.eventBus = eventBus; + eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(PlayerAppearanceChanged.class, this, this::onAppearenceChanged, -1, EventScheduler.DEFAULT, EventScheduler.COMPUTATION); + } + + /** + * @return Collection of {@link PlayerContainer} that are attacking you, this can be empty. + */ + public Set getAllAttackers() + { + final Set set = new HashSet<>(); + for (PlayerContainer p : playerMap.values()) + { + if (p.isAttacking()) + { + set.add(p); + } + } + return set; + } + + /** + * @return Collection of {@link PlayerContainer}, this can be empty. + */ + public Collection getPlayerContainers() + { + return playerMap.values(); + } + + /** + * @param name Players name. + * @return {@link PlayerContainer} if provided with proper name, else null. + */ + @Nullable + public PlayerContainer getPlayer(String name) + { + return playerMap.get(name); + } + + /** + * @param player Player object. + * @return {@link PlayerContainer} if provided with proper name, else null. + */ + @Nullable + public PlayerContainer getPlayer(Player player) + { + if (player == null) + { + return null; + } + + return playerMap.get(player.getName()); + } + + /** + * This will keep submitting an http request until it successfully updates. + * + * @param name The player name you wish to update. + */ + public void updateStats(String name) + { + final PlayerContainer p = playerMap.get(name); + + if (p == null) + { + return; + } + + updateStats(p.getPlayer()); + } + + /** + * This will keep submitting an http request until it successfully updates. + * + * @param requestedPlayer The player object you wish to update. + */ + public void updateStats(Player requestedPlayer) + { + if (requestedPlayer == null) + { + return; + } + + final PlayerContainer player = playerMap.get(requestedPlayer.getName()); + + if (player == null) + { + return; + } + + if (resultCache.containsKey(player.getName())) + { + player.setSkills(resultCache.get(player.getName())); + player.setPrayerLevel(player.getSkills().getPrayer().getLevel()); + player.setHpLevel(player.getSkills().getHitpoints().getLevel()); + return; + } + + executorService.submit(() -> + { + player.setHttpRetry(true); + int timeout = 0; + HiscoreResult result; + do + { + try + { + result = HISCORE_CLIENT.lookup(player.getName()); + } + catch (IOException ex) + { + if (timeout == 10) + { + log.error("HiScore Lookup timed out on: {}", player.getName()); + return; + } + result = null; + timeout++; + try + { + Thread.sleep(1000); + } + catch (InterruptedException ignored) + { + } + } + } + while (result == null); + + resultCache.put(player.getName(), result); + player.setSkills(result); + player.setPrayerLevel(player.getSkills().getPrayer().getLevel()); + player.setHpLevel(player.getSkills().getHitpoints().getLevel()); + player.setHttpRetry(false); + }); + } + + private void onAppearenceChanged(PlayerAppearanceChanged event) + { + final PlayerContainer player = playerMap.get(event.getPlayer().getName()); + + if (player == null) + { + return; + } + + update(player); + player.reset(); + player.setFriend(client.isFriended(player.getName(), false)); + player.setClan(client.isClanMember(player.getName())); + } + + private void onPlayerDespawned(PlayerDespawned event) + { + final Player player = event.getPlayer(); + playerMap.remove(player.getName()); + } + + private void onPlayerSpawned(PlayerSpawned event) + { + final Player player = event.getPlayer(); + playerMap.put(player.getName(), new PlayerContainer(player)); + } + + private void onAnimationChanged(AnimationChanged event) + { + final Actor actor = event.getActor(); + + if (actor.getInteracting() != client.getLocalPlayer() || !(actor instanceof Player) || actor.getAnimation() == -1) + { + return; + } + + final PlayerContainer player = playerMap.getOrDefault(actor.getName(), null); + + if (player == null) + { + return; + } + + if (player.getPlayer().getInteracting() != null && + player.getPlayer().getInteracting() == client.getLocalPlayer()) + { + if (player.getSkills() == null) + { + updateStats(player.getPlayer()); + } + + player.setAttacking(true); + player.setTimer(8); + } + } + + private void update(PlayerContainer player) + { + player.setRisk(0); + updatePlayerGear(player); + updateAttackStyle(player); + updateWeakness(player); + player.setLocation(WorldLocation.location(player.getPlayer().getWorldLocation())); + player.setWildyLevel(PvPUtil.getWildernessLevelFrom(player.getPlayer().getWorldLocation())); + player.setTargetString(targetStringBuilder(player)); + } + + private void updatePlayerGear(PlayerContainer player) + { + final Map prices = new HashMap<>(); + + if (player.getPlayer().getPlayerAppearance() == null) + { + return; + } + + int magicAttack = 0, + magicDefence = 0, + magicStr = 0, + meleeAtkCrush = 0, + meleeAtkStab = 0, + meleeAtkSlash = 0, + meleeDefCrush = 0, + meleeDefStab = 0, + meleeDefSlash = 0, + meleeStr = 0, + rangeAttack = 0, + rangeDefence = 0, + rangeStr = 0, + speed = 0; + + for (KitType kitType : KitType.values()) + { + if (kitType.equals(KitType.RING) || kitType.equals(KitType.AMMUNITION)) + { + continue; + } + + final int id = player.getPlayer().getPlayerAppearance().getEquipmentId(kitType); + + if (id == -1) + { + continue; + } + + if (kitType.equals(KitType.WEAPON)) + { + player.setWeapon(id); + + switch (id) + { + case ItemID.HEAVY_BALLISTA: + case ItemID.HEAVY_BALLISTA_23630: + case ItemID.LIGHT_BALLISTA: + rangeStr += 150; + break; + case ItemID.MAPLE_LONGBOW: + case ItemID.MAPLE_SHORTBOW: + rangeStr += 31; + break; + case ItemID.MAGIC_SHORTBOW: + case ItemID.MAGIC_SHORTBOW_20558: + case ItemID.MAGIC_SHORTBOW_I: + rangeStr += +55; + break; + case ItemID.DARK_BOW: + case ItemID.DARK_BOW_12765: + case ItemID.DARK_BOW_12766: + case ItemID.DARK_BOW_12767: + case ItemID.DARK_BOW_12768: + case ItemID.DARK_BOW_20408: + rangeStr += +60; + break; + case ItemID.RUNE_CROSSBOW: + case ItemID.RUNE_CROSSBOW_23601: + rangeStr += +117; + break; + case ItemID.DRAGON_CROSSBOW: + case ItemID.ARMADYL_CROSSBOW: + case ItemID.ARMADYL_CROSSBOW_23611: + rangeStr += +122; + break; + } + } + + final ItemStats item = itemManager.getItemStats(id, false); + final ItemDefinition itemDefinition = itemManager.getItemDefinition(id); + + if (item == null) + { + log.debug("Item is null: {}", id); + continue; + } + + final ItemEquipmentStats stats = item.getEquipment(); + + speed += stats.getAspeed(); + meleeAtkCrush += stats.getAcrush(); + meleeAtkStab += stats.getAstab(); + meleeAtkSlash += stats.getAslash(); + meleeDefCrush += stats.getDcrush(); + meleeDefStab += stats.getDstab(); + meleeDefSlash += stats.getDslash(); + magicAttack += stats.getAmagic(); + rangeAttack += stats.getArange(); + magicDefence += stats.getDmagic(); + rangeDefence += stats.getDrange(); + rangeStr += stats.getRstr(); + meleeStr += stats.getStr(); + magicStr += stats.getMdmg(); + + if (ItemReclaimCost.breaksOnDeath(id)) + { + prices.put(id, itemManager.getRepairValue(id)); + log.debug("Item has a broken value: Id {}, Value {}", id, itemManager.getRepairValue(id)); + continue; + } + + if (!itemDefinition.isTradeable() && !ItemMapping.isMapped(id)) + { + prices.put(id, itemDefinition.getPrice()); + } + else if (itemDefinition.isTradeable()) + { + prices.put(id, itemManager.getItemPrice(id, false)); + } + } + + player.setCombatStats(new CombatStats( + magicAttack, + magicDefence, + magicStr, + meleeAtkCrush, + meleeAtkSlash, + meleeAtkStab, + (meleeAtkCrush + meleeAtkSlash + meleeAtkStab) / 3, + meleeDefCrush, + (meleeDefCrush + meleeDefSlash + meleeDefStab) / 3, + meleeDefSlash, + meleeDefStab, + meleeStr, + rangeAttack, + rangeDefence, + rangeStr, + speed + )); + updateGear(player, prices); + updateMeleeStyle(player); + } + + private void updateGear(PlayerContainer player, Map prices) + { + player.setGear(prices.entrySet() + .stream() + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)) + ); + + player.setRiskedGear(prices.entrySet() + .stream() + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)) + ); + + if (player.getPlayer().getSkullIcon() == null) + { + removeEntries(player.getRiskedGear(), player.getPrayerLevel() <= 25 ? 3 : 4); + } + else + { + removeEntries(player.getRiskedGear(), player.getPrayerLevel() <= 25 ? 0 : 1); + } + + player.getRiskedGear().values().forEach(price -> player.setRisk(player.getRisk() + price)); + prices.clear(); + } + + private void updateMeleeStyle(PlayerContainer player) + { + final CombatStats stats = player.getCombatStats(); + + if (stats.getMeleeAtkCrush() >= stats.getMeleeAtkSlash() && stats.getMeleeAtkCrush() >= stats.getMeleeAtkStab()) + { + player.setMeleeStyle(PlayerContainer.MeleeStyle.CRUSH); + } + else if (stats.getMeleeAtkSlash() >= stats.getMeleeAtkCrush() && stats.getMeleeAtkSlash() >= stats.getMeleeAtkStab()) + { + player.setMeleeStyle(PlayerContainer.MeleeStyle.SLASH); + } + else + { + player.setMeleeStyle(PlayerContainer.MeleeStyle.STAB); + } + } + + private void updateAttackStyle(PlayerContainer player) + { + final AttackStyle oldStyle = player.getAttackStyle(); + boolean staff = false; + + for (int id : player.getGear().keySet()) + { + ItemDefinition def = itemManager.getItemDefinition(id); + if (def.getName().toLowerCase().contains("staff")) + { + player.setAttackStyle(AttackStyle.MAGE); + staff = true; + break; + } + } + + if (staff) + { + if (oldStyle != player.getAttackStyle()) + { + eventBus.post(AttackStyleChanged.class, new AttackStyleChanged( + player.getPlayer(), oldStyle, player.getAttackStyle()) + ); + } + return; + } + + final CombatStats stats = player.getCombatStats(); + + if (stats.getMagicStr() >= stats.getRangeStr() && stats.getMagicStr() >= stats.getMeleeStr()) + { + player.setAttackStyle(AttackStyle.MAGE); + } + else if (stats.getRangeStr() >= stats.getMagicStr() && stats.getRangeStr() >= stats.getMeleeStr()) + { + player.setAttackStyle(AttackStyle.RANGE); + } + else + { + player.setAttackStyle(AttackStyle.MELEE); + } + + if (oldStyle != player.getAttackStyle()) + { + eventBus.post(AttackStyleChanged.class, new AttackStyleChanged( + player.getPlayer(), oldStyle, player.getAttackStyle()) + ); + } + } + + private void updateWeakness(PlayerContainer player) + { + final CombatStats stats = player.getCombatStats(); + + if (stats.getMagicDefence() <= stats.getRangeDefence() && stats.getMagicDefence() <= stats.getMeleeDefence()) + { + player.setWeakness(AttackStyle.MAGE); + } + else if (stats.getRangeDefence() <= stats.getMagicDefence() && stats.getRangeDefence() <= stats.getMeleeDefence()) + { + player.setWeakness(AttackStyle.RANGE); + } + else + { + player.setWeakness(AttackStyle.MELEE); + } + } + + private static void removeEntries(LinkedHashMap map, int quantity) + { + for (int i = 0; i < quantity; i++) + { + if (!map.entrySet().iterator().hasNext()) + { + return; + } + map.entrySet().remove(map.entrySet().iterator().next()); + } + } + + private String targetStringBuilder(PlayerContainer player) + { + if (player.getPlayer().getInteracting() != null) + { + Actor actor = player.getPlayer().getInteracting(); + if (actor instanceof Player) + { + return "(Player) " + actor.getName(); + } + else if (actor instanceof NPC) + { + return "(NPC) " + actor.getName(); + } + } + return "No Target Detected"; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java index 713779892a..526a49144b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorConfig.java @@ -38,7 +38,7 @@ public interface EquipmentInspectorConfig extends Config description = "shows the total value of the items", position = 1 ) - default boolean ShowValue() + default boolean showValue() { return true; } @@ -49,11 +49,11 @@ public interface EquipmentInspectorConfig extends Config ) @ConfigItem( keyName = "protecteditems", - name = "protected items", - description = "Limit 4", + name = "Protected Items", + description = "Limited to 4", position = 2 ) - default int protecteditems() + default int protectedItems() { return 1; } @@ -64,7 +64,7 @@ public interface EquipmentInspectorConfig extends Config description = "shows the excact gp value", position = 3 ) - default boolean ExactValue() + default boolean exactValue() { return false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java index 6acd23e680..bdb574111a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java @@ -29,12 +29,9 @@ import java.awt.image.BufferedImage; import java.lang.reflect.InvocationTargetException; import java.text.NumberFormat; import java.util.HashMap; -import java.util.List; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; -import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; import javax.swing.SwingUtilities; @@ -42,7 +39,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.ItemDefinition; -import net.runelite.api.Player; import net.runelite.api.events.PlayerMenuOptionClicked; import net.runelite.api.kit.KitType; import net.runelite.api.util.Text; @@ -54,6 +50,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; import net.runelite.client.game.ItemManager; +import net.runelite.client.game.PlayerContainer; +import net.runelite.client.game.PlayerManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -61,6 +59,7 @@ import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.QuantityFormatter; @PluginDescriptor( name = "Equipment Inspector", @@ -74,37 +73,27 @@ public class EquipmentInspectorPlugin extends Plugin private static final String INSPECT_EQUIPMENT = "Gear"; @Inject - @Nullable private Client client; - @Inject private ItemManager itemManager; - @Inject private EquipmentInspectorConfig config; - @Inject private ChatMessageManager chatMessageManager; @Inject private MenuManager menuManager; - @Inject private ScheduledExecutorService executor; - @Inject private ClientToolbar pluginToolbar; + @Inject + private PlayerManager playerManager; private NavigationButton navButton; private EquipmentInspectorPanel equipmentInspectorPanel; - private int TotalPrice = 0; - private int Prot1 = 0; - private int Prot2 = 0; - private int Prot3 = 0; - private int Prot4 = 0; - - private boolean ShowValue; - private int protecteditems; - private boolean ExactValue; + private boolean showValue; + private int protectedItems; + private boolean exactValue; @Provides EquipmentInspectorConfig provideConfig(ConfigManager configManager) @@ -146,152 +135,88 @@ public class EquipmentInspectorPlugin extends Plugin @Subscribe private void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) { - if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) + if (!event.getMenuOption().equals(INSPECT_EQUIPMENT)) { - executor.execute(() -> - { - try - { - SwingUtilities.invokeAndWait(() -> - { - if (!navButton.isSelected()) - { - navButton.getOnSelect().run(); - } - }); - } - catch (InterruptedException | InvocationTargetException e) - { - - throw new RuntimeException(e); - - } - String playerName = Text.removeTags(event.getMenuTarget()); - // The player menu uses a non-breaking space in the player name, we need to replace this to compare - // against the playerName in the player cache. - String finalPlayerName = playerName.replace('\u00A0', ' '); - List players = null; - if (client != null) - { - players = client.getPlayers(); - } - Optional targetPlayer = Optional.empty(); - if (players != null) - { - targetPlayer = players.stream() - .filter(Objects::nonNull) - .filter(p -> p.getName().equals(finalPlayerName)).findFirst(); - } - - if (targetPlayer.isPresent()) - { - TotalPrice = 0; - Prot1 = 0; - Prot2 = 0; - Prot3 = 0; - Prot4 = 0; - Player p = targetPlayer.get(); - Map playerEquipment = new HashMap<>(); - - for (KitType kitType : KitType.values()) - { - if (kitType == KitType.RING) - { - continue; //prevents the equipment inspector from breaking - } - if (kitType == KitType.AMMUNITION) - { - continue; - } - - int itemId = p.getPlayerAppearance().getEquipmentId(kitType); - if (itemId != -1) - { - ItemDefinition itemComposition = client.getItemDefinition(itemId); - playerEquipment.put(kitType, itemComposition); - int ItemPrice = itemManager.getItemPrice(itemId); - TotalPrice += ItemPrice; - if (ItemPrice > Prot1) - { - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = Prot1; - - Prot1 = ItemPrice; - } - else if (ItemPrice > Prot2) - { - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = ItemPrice; - } - else if (ItemPrice > Prot3) - { - Prot4 = Prot3; - Prot3 = ItemPrice; - } - else if (ItemPrice > Prot4) - { - Prot4 = ItemPrice; - } - } - } - int IgnoredItems = this.protecteditems; - if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) - { - IgnoredItems = 4; - - } - if (this.ShowValue) - { - switch (IgnoredItems) - { - case 1: - TotalPrice = TotalPrice - Prot1; - break; - case 2: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - - break; - case 3: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - break; - case 4: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - TotalPrice = TotalPrice - Prot4; - break; - } - String StringPrice = ""; - if (!this.ExactValue) - { - TotalPrice = TotalPrice / 1000; - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - StringPrice = StringPrice + 'K'; - } - if (this.ExactValue) - { - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - } - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.CONSOLE) - .runeLiteFormattedMessage(new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append("Risked Value: ") - .append(ChatColorType.NORMAL) - .append(StringPrice) - .build()) - .build()); - } - equipmentInspectorPanel.update(playerEquipment, playerName); - - } - }); + return; } + + executor.execute(() -> + { + try + { + SwingUtilities.invokeAndWait(() -> + { + if (!navButton.isSelected()) + { + navButton.getOnSelect().run(); + } + }); + } + catch (InterruptedException | InvocationTargetException e) + { + throw new RuntimeException(e); + } + + String playerName = Text.removeTags(event.getMenuTarget()).replace('\u00A0', ' '); + final PlayerContainer player = playerManager.getPlayer(playerName); + final Map playerEquipment = new HashMap<>(); + + if (player == null) + { + return; + } + + for (KitType kitType : KitType.values()) + { + if (kitType == KitType.RING || kitType == KitType.AMMUNITION || + player.getPlayer().getPlayerAppearance() == null) + { + continue; + } + + final int itemId = player.getPlayer().getPlayerAppearance().getEquipmentId(kitType); + + if (itemId != -1) + { + ItemDefinition itemComposition = client.getItemDefinition(itemId); + playerEquipment.put(kitType, itemComposition); + } + } + + if (this.showValue) + { + final LinkedHashMap gear = new LinkedHashMap<>(player.getGear()); + removeEntries(gear, this.protectedItems); + + int risk = 0; + for (int value : gear.values()) + { + risk += value; + } + + String price; + + if (!this.exactValue) + { + price = QuantityFormatter.quantityToRSDecimalStack(risk); + } + else + { + price = NumberFormat.getIntegerInstance().format(risk); + } + + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("Risked Value: ") + .append(ChatColorType.NORMAL) + .append(price) + .build()) + .build()); + } + equipmentInspectorPanel.update(playerEquipment, playerName); + }); } @Subscribe @@ -303,10 +228,22 @@ public class EquipmentInspectorPlugin extends Plugin } } + private static void removeEntries(LinkedHashMap map, int quantity) + { + for (int i = 0; i < quantity; i++) + { + if (!map.entrySet().iterator().hasNext()) + { + return; + } + map.entrySet().remove(map.entrySet().iterator().next()); + } + } + private void updateConfig() { - this.ShowValue = config.ShowValue(); - this.protecteditems = config.protecteditems(); - this.ExactValue = config.ExactValue(); + this.showValue = config.showValue(); + this.protectedItems = config.protectedItems(); + this.exactValue = config.exactValue(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideunder/HideUnder.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideunder/HideUnder.java index 7d21aac95a..de92bff3fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hideunder/HideUnder.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideunder/HideUnder.java @@ -23,23 +23,18 @@ */ package net.runelite.client.plugins.hideunder; -import java.util.HashSet; -import java.util.Set; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Actor; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.Player; import net.runelite.api.Varbits; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; -import net.runelite.api.events.InteractingChanged; -import net.runelite.api.events.PlayerDespawned; -import net.runelite.api.events.PlayerSpawned; -import net.runelite.client.eventbus.EventBus; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.PlayerContainer; +import net.runelite.client.game.PlayerManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -56,35 +51,22 @@ public class HideUnder extends Plugin { @Inject private Client client; - @Inject - private EventBus eventBus; + private PlayerManager playerManager; - private final Set playerContainer = new HashSet<>(); @Override protected void startUp() { - addSubscriptions(); - playerContainer.clear(); } @Override protected void shutDown() { - eventBus.unregister(this); - } - - private void addSubscriptions() - { - eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); - eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); - eventBus.subscribe(GameTick.class, this, this::onGameTick); - eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); - eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); - eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + @Subscribe private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) @@ -93,122 +75,32 @@ public class HideUnder extends Plugin } } - private void onInteractingChanged(InteractingChanged event) - { - if ((event.getSource() instanceof Player) && (event.getTarget() instanceof Player)) - { - final Player source = (Player) event.getSource(); - final Player target = (Player) event.getTarget(); - - if (source == client.getLocalPlayer()) - { - for (PlayerContainer player : playerContainer) - { - if (player.getPlayer() == target) - { - player.setTimer(16); - player.setTarget(true); - } - } - } - else if (target == client.getLocalPlayer()) - { - for (PlayerContainer player : playerContainer) - { - if (player.getPlayer() == source) - { - player.setTimer(16); - player.setTarget(true); - } - } - } - } - } - - private void onAnimationChanged(AnimationChanged event) - { - final Actor actor = event.getActor(); - - if (actor.getInteracting() != client.getLocalPlayer() || !(actor instanceof Player)) - { - return; - } - - if (actor.getAnimation() != -1 && actor.getInteracting() != null && actor.getInteracting() == client.getLocalPlayer()) - { - for (PlayerContainer player : playerContainer) - { - if (player.getPlayer() == actor) - { - player.setTimer(16); - player.setTarget(true); - } - } - } - } - - private void onPlayerSpawned(PlayerSpawned event) - { - final Player player = event.getPlayer(); - - if (player == client.getLocalPlayer()) - { - return; - } - - playerContainer.add(new PlayerContainer(player)); - } - - private void onPlayerDespawned(PlayerDespawned event) - { - final Player player = event.getPlayer(); - playerContainer.removeIf(playa -> playa.getPlayer() == player); - } - + @Subscribe private void onGameTick(GameTick event) { - if (playerContainer.isEmpty() || client.getLocalPlayer() == null) + if (client.getLocalPlayer() == null) { return; } - final WorldPoint lp = client.getLocalPlayer().getWorldLocation(); - final WorldPoint localPlayerWp = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()); - client.setLocalPlayerHidden(false); - if (localPlayerWp == null) + final WorldPoint localPlayerWp = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()); + final WorldPoint lp = client.getLocalPlayer().getWorldLocation(); + + for (PlayerContainer player : playerManager.getAllAttackers()) { - return; - } - - for (PlayerContainer player : playerContainer) - { - if (player.getTimer() > 0) - { - player.setTimer(player.getTimer() - 1); - } - else - { - player.setTarget(false); - } - - if (!player.isTarget()) - { - continue; - } - if (client.getVar(Varbits.LMS_IN_GAME) == 1) { final WorldPoint playerWp = WorldPoint.fromLocalInstance(client, player.getPlayer().getLocalLocation()); - if (playerWp != null && localPlayerWp.distanceTo(playerWp) == 0) + if (localPlayerWp != null && localPlayerWp.distanceTo(playerWp) == 0) { client.setLocalPlayerHidden(true); } continue; } - if (player.getPlayer().getWorldLocation().distanceTo(lp) == 0) + if (lp != null && player.getPlayer().getWorldLocation().distanceTo(lp) == 0) { client.setLocalPlayerHidden(true); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java index 317e4d475b..501440123a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouter.java @@ -24,52 +24,34 @@ package net.runelite.client.plugins.playerscouter; import com.google.inject.Provides; -import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; +import java.util.Comparator; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Actor; import net.runelite.api.Client; import net.runelite.api.GameState; -import net.runelite.api.ItemDefinition; -import net.runelite.api.NPC; -import net.runelite.api.Player; import net.runelite.api.Varbits; import net.runelite.api.WorldType; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; -import net.runelite.api.events.PlayerDespawned; -import net.runelite.api.events.PlayerSpawned; -import net.runelite.api.kit.KitType; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; import net.runelite.client.game.ItemManager; -import net.runelite.client.game.ItemMapping; -import net.runelite.client.game.ItemReclaimCost; +import net.runelite.client.game.PlayerContainer; +import net.runelite.client.game.PlayerManager; import net.runelite.client.game.WorldLocation; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; -import net.runelite.client.util.PvPUtil; import net.runelite.client.util.QuantityFormatter; import net.runelite.http.api.discord.DiscordClient; import net.runelite.http.api.discord.DiscordEmbed; @@ -78,8 +60,6 @@ import net.runelite.http.api.discord.embed.AuthorEmbed; import net.runelite.http.api.discord.embed.FieldEmbed; import net.runelite.http.api.discord.embed.FooterEmbed; import net.runelite.http.api.discord.embed.ThumbnailEmbed; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreResult; import net.runelite.http.api.item.ItemStats; import okhttp3.HttpUrl; @@ -92,27 +72,19 @@ import okhttp3.HttpUrl; @Slf4j public class PlayerScouter extends Plugin { - private static final HiscoreClient HISCORE_CLIENT = new HiscoreClient(); private static final DiscordClient DISCORD_CLIENT = new DiscordClient(); - private static final Map WILD_LOCS = WorldLocation.getLOCATION_MAP(); private static final SimpleDateFormat SDF = new SimpleDateFormat("MMM dd h:mm a z"); private static final String ICON_URL = "https://www.osrsbox.com/osrsbox-db/items-icons/"; // Add item id + ".png" @Inject private Client client; - @Inject private ItemManager itemManager; - @Inject private PlayerScouterConfig config; - @Inject - private EventBus eventBus; + private PlayerManager playerManager; - private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); - private final Set playerContainer = new HashSet<>(); - private final Map resultCache = new HashMap<>(); private final Map blacklist = new HashMap<>(); private HttpUrl webhook; private int minimumRisk; @@ -135,31 +107,13 @@ public class PlayerScouter extends Plugin protected void startUp() { blacklist.clear(); - addSubscriptions(); updateConfig(); - if (client.getGameState() == GameState.LOGGED_IN) - { - for (Player player : client.getPlayers()) - { - addPlayer(player); - } - } } @Override protected void shutDown() { - playerContainer.clear(); blacklist.clear(); - eventBus.unregister(this); - } - - private void addSubscriptions() - { - eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); - eventBus.subscribe(GameTick.class, this, this::onGameTick); - eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); - eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); } @Subscribe @@ -173,6 +127,7 @@ public class PlayerScouter extends Plugin updateConfig(); } + @Subscribe private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) @@ -183,48 +138,68 @@ public class PlayerScouter extends Plugin blacklist.clear(); } + @Subscribe private void onGameTick(GameTick event) { - resetBlacklist(); - if (!checkWildy() || playerContainer.isEmpty() || this.webhook == null) + if (!checkWildy() || this.webhook == null) { return; } - playerContainer.forEach(player -> + final List players = new ArrayList<>(); + + for (PlayerContainer player : playerManager.getPlayerContainers()) { - update(player); - if (player.getPlayer().getCombatLevel() < this.minimumCombat - || player.getPlayer().getCombatLevel() > this.maximumCombat) + if (player.isScouted()) { - return; + player.setScoutTimer(player.getScoutTimer() - 1); + if (player.getScoutTimer() <= 0) + { + player.setScouted(false); + player.setScoutTimer(500); + } + continue; } - if ((player.getPlayer().getCombatLevel() >= this.minimumCombat - && player.getPlayer().getCombatLevel() <= this.maximumCombat) && player.getRisk() > this.minimumRisk) + + if (player.getPlayer().getCombatLevel() < this.minimumCombat || player.getPlayer().getCombatLevel() > this.maximumCombat) { - scoutPlayer(player); + continue; } - }); + + if ((player.getPlayer().getCombatLevel() >= this.minimumCombat && + player.getPlayer().getCombatLevel() <= this.maximumCombat) && + player.getRisk() > this.minimumRisk) + { + if (player.getSkills() == null) + { + if (player.isHttpRetry()) + { + continue; + } + playerManager.updateStats(player.getPlayer()); + continue; + } + if (config.mini()) + { + players.add(player); + continue; + } + addPlayer(player); + } + } + + if (config.mini()) + { + players.sort(Comparator.comparingInt(PlayerContainer::getRisk).reversed()); + scoutMini(players); + } } - private void onPlayerDespawned(PlayerDespawned event) + private void addPlayer(PlayerContainer player) { - final Player player = event.getPlayer(); - - playerContainer.removeIf(p -> p.getPlayer() == player); - } - - private void onPlayerSpawned(PlayerSpawned event) - { - final Player player = event.getPlayer(); - addPlayer(player); - } - - private void addPlayer(Player player) - { - if (player == client.getLocalPlayer() + if (player.getPlayer() == client.getLocalPlayer() || (!blacklist.isEmpty() && blacklist.containsKey(player.getName())) || (!this.scoutFriends && client.isFriended(player.getName(), false) || (!this.scoutClan && client.isClanMember(player.getName())))) @@ -233,8 +208,8 @@ public class PlayerScouter extends Plugin return; } - playerContainer.add(new PlayerContainer(player)); blacklist.put(player.getName(), client.getTickCount() + this.timeout); + scoutPlayer(player); } private void resetBlacklist() @@ -279,203 +254,79 @@ public class PlayerScouter extends Plugin this.maximumCombat = config.maximumCombat(); } - private void update(PlayerContainer player) + private void scoutMini(List players) { - if (player.isScouted()) - { - player.setScoutTimer(player.getScoutTimer() - 1); - if (player.getScoutTimer() <= 0) - { - player.setScouted(false); - player.setScoutTimer(500); - } - return; - } - player.setRisk(0); - updatePlayerGear(player); - updateStats(player); - player.setLocation(location(player)); - player.setWildyLevel(PvPUtil.getWildernessLevelFrom(player.getPlayer().getWorldLocation())); - player.setTargetString(targetStringBuilder(player)); - log.debug(player.toString()); - } - - private void updateStats(PlayerContainer player) - { - if (player.isHttpRetry() || player.getSkills() != null) + if (client.getLocalPlayer() == null) { return; } - executorService.submit(() -> + final List fieldList = new ArrayList<>(); + final String location = WorldLocation.location(client.getLocalPlayer().getWorldLocation()); + final int cap = Math.min(players.size(), 25); + + int highestValue = 0; + int id = 0; + int risk = 0; + for (int i = 0; i < cap; i++) { - player.setHttpRetry(true); - HiscoreResult result; - if (resultCache.containsKey(player.getName())) + final PlayerContainer player = players.get(i); + final Map.Entry entry = getEntry(player.getGear()); + risk += player.getRisk(); + if (entry != null) { - result = resultCache.get(player.getName()); - } - else - { - try + final int mostValued = (int) entry.getValue(); + final int mostValuedId = (int) entry.getKey(); + + if (mostValued > highestValue) { - result = HISCORE_CLIENT.lookup(player.getName()); - } - catch (IOException ex) - { - log.warn("Error fetching Hiscore data " + ex.getMessage()); - player.setHttpRetry(false); - return; + highestValue = mostValued; + id = mostValuedId; } } - if (result == null) + + String name = "☠️ " + player.getName() + " ☠️"; + + if (player.getPlayer().getSkullIcon() == null) { - player.setHttpRetry(false); - return; + name = player.getName(); } - resultCache.put(player.getName(), result); - player.setSkills(result); - player.setPrayer(player.getSkills().getPrayer().getLevel()); - }); - } - private void updatePlayerGear(PlayerContainer player) - { - Map prices = new HashMap<>(); + fieldList.add(FieldEmbed.builder() + .name(name) + .value(QuantityFormatter.quantityToRSDecimalStack(player.getRisk())) + .inline(true) + .build()); - if (player.getPlayer().getPlayerAppearance() == null) - { - return; + player.setScouted(true); } - for (KitType kitType : KitType.values()) + String iconId = String.valueOf(id); + String icon = ICON_URL + iconId + ".png"; + + ThumbnailEmbed image = ThumbnailEmbed.builder() + .url(ICON_URL + iconId + ".png") + .build(); + + String color = "8388352"; + + if (risk < 1000000 && risk > 150000) { - if (kitType.equals(KitType.RING) || kitType.equals(KitType.AMMUNITION)) - { - continue; - } - - final int id = player.getPlayer().getPlayerAppearance().getEquipmentId(kitType); - - if (id == -1) - { - continue; - } - - if (kitType.equals(KitType.WEAPON)) - { - player.setWeapon(id); - } - - final ItemStats item = itemManager.getItemStats(id, false); - final ItemDefinition itemDefinition = itemManager.getItemDefinition(id); - - if (item == null) - { - log.debug("Item is null: {}", id); - continue; - } - - if (ItemReclaimCost.breaksOnDeath(id)) - { - prices.put(id, itemManager.getRepairValue(id)); - log.debug("Item has a broken value: Id {}, Value {}", id, itemManager.getRepairValue(id)); - continue; - } - - if (!itemDefinition.isTradeable() && !ItemMapping.isMapped(id)) - { - prices.put(id, itemDefinition.getPrice()); - } - else if (itemDefinition.isTradeable()) - { - prices.put(id, itemManager.getItemPrice(id, false)); - } + //blue + color = "32767"; } - updateGear(player, prices); - } - - private void updateGear(PlayerContainer player, Map prices) - { - player.setGear(prices.entrySet() - .stream() - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)) - ); - - player.setRiskedGear(prices.entrySet() - .stream() - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)) - ); - - if (player.getPlayer().getSkullIcon() == null) + else if (risk > 1000000) { - removeEntries(player.getRiskedGear(), player.getPrayer() <= 25 ? 3 : 4); - } - else - { - removeEntries(player.getRiskedGear(), player.getPrayer() <= 25 ? 0 : 1); + //orange + color = "16744448"; } - player.getRiskedGear().values().forEach(price -> player.setRisk(player.getRisk() + price)); - prices.clear(); - } - - private static void removeEntries(LinkedHashMap map, int quantity) - { - if (map.size() < quantity) - { - log.debug("Size is lower than removal quantity."); - } - for (int i = 0; i < quantity; i++) - { - if (!map.entrySet().iterator().hasNext()) - { - log.debug("Attempted to remove entries, but there was not enough to remove."); - return; - } - log.debug("Entry Removed: " + map.entrySet().iterator().next()); - map.entrySet().remove(map.entrySet().iterator().next()); - } - } - - private static Map.Entry getEntry(LinkedHashMap map) - { - if (!map.isEmpty()) - { - Iterator> entry = map.entrySet().iterator(); - - for (int i = 0; i < 1; i++) - { - entry.next(); - } - - return entry.next(); - } - return null; - } - - private String targetStringBuilder(PlayerContainer player) - { - if (player.getPlayer().getInteracting() != null) - { - Actor actor = player.getPlayer().getInteracting(); - if (actor instanceof Player) - { - return "(Player) " + actor.getName(); - } - else if (actor instanceof NPC) - { - return "(NPC) " + actor.getName(); - } - } - return "No Target Detected"; + message(location, icon, image, fieldList, color); } private void scoutPlayer(PlayerContainer player) { - if (player.isScouted() || player.getSkills() == null) + if (player.isScouted()) { return; } @@ -516,6 +367,7 @@ public class PlayerScouter extends Plugin .value(Integer.toString(player.getPlayer().getCombatLevel())) .inline(true) .build()); + if (client.getVar(Varbits.IN_WILDERNESS) == 1) { fieldList.add(FieldEmbed.builder() @@ -582,7 +434,10 @@ public class PlayerScouter extends Plugin } } - String icon = ICON_URL + Objects.requireNonNull(getEntry(player.getGear())).getKey() + ".png"; + + Map.Entry entry = getEntry(player.getGear()); + String iconId = entry == null ? String.valueOf(1) : String.valueOf(entry.getKey()); + String icon = ICON_URL + iconId + ".png"; String name = "☠️ " + player.getName() + " ☠️"; if (player.getPlayer().getSkullIcon() == null) @@ -601,7 +456,7 @@ public class PlayerScouter extends Plugin if (name.isEmpty() || fields.isEmpty()) { - log.error("Discord message will fail with a missing name/description/field"); + log.debug("Discord message will fail with a missing name/description/field"); return; } @@ -627,50 +482,12 @@ public class PlayerScouter extends Plugin DISCORD_CLIENT.message(this.webhook, discordMessage); } - private String location(PlayerContainer player) + private static Map.Entry getEntry(LinkedHashMap map) { - final WorldPoint wl = player.getPlayer().getWorldLocation(); - int dist = 10000; - String s = ""; - WorldArea closestArea = null; - for (Map.Entry entry : WILD_LOCS.entrySet()) + if (!map.isEmpty()) { - WorldArea worldArea = entry.getKey(); - - if (worldArea.toWorldPointList().contains(wl)) - { - s = entry.getValue(); - return s; - } - int distTo = worldArea.distanceTo(wl); - if (distTo < dist) - { - dist = distTo; - closestArea = worldArea; - } + return map.entrySet().iterator().next(); } - if (wl.getY() > (Objects.requireNonNull(closestArea).toWorldPoint().getY() + closestArea.getHeight())) - { - s = s + "N"; - } - if (wl.getY() < closestArea.toWorldPoint().getY()) - { - s = s + "S"; - } - if (wl.getX() < closestArea.toWorldPoint().getX()) - { - s = s + "W"; - } - if (wl.getX() > (closestArea.toWorldPoint().getX() + closestArea.getWidth())) - { - s = s + "E"; - } - s = s + " of "; - s = s + WILD_LOCS.get(closestArea); - if (s.startsWith(" of ")) - { - s = s.substring(3); - } - return s; + return null; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java index f83976bfed..d60513e890 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerscouter/PlayerScouterConfig.java @@ -43,6 +43,18 @@ public interface PlayerScouterConfig extends Config return ""; } + @ConfigItem( + keyName = "mini", + name = "Minify Output", + description = "", + position = 0, + secret = true + ) + default boolean mini() + { + return true; + } + @ConfigItem( keyName = "onlyWildy", name = "Only Scout in Wildy", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java deleted file mode 100644 index 338fcd4357..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PlayerContainer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * 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.prayagainstplayer; - -import net.runelite.api.Player; - -/** - * Contains a player object - * When they attacked me - * And (in milliseconds) when to expire the overlay around them - */ -public class PlayerContainer -{ - - private final Player player; - private final long whenTheyAttackedMe; - private final int millisToExpireHighlight; - - PlayerContainer(final Player player, final long whenTheyAttackedMe, final int millisToExpireHighlight) - { - this.player = player; - this.whenTheyAttackedMe = whenTheyAttackedMe; - this.millisToExpireHighlight = millisToExpireHighlight; - } - - //getters - public Player getPlayer() - { - return player; - } - - long getWhenTheyAttackedMe() - { - return whenTheyAttackedMe; - } - - int getMillisToExpireHighlight() - { - return millisToExpireHighlight; - } - -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java index 6317c62a07..58d99491fd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerConfig.java @@ -24,7 +24,6 @@ package net.runelite.client.plugins.prayagainstplayer; -import java.awt.Color; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -32,63 +31,8 @@ import net.runelite.client.config.ConfigItem; @ConfigGroup("prayagainstplayer") public interface PrayAgainstPlayerConfig extends Config { - @ConfigItem( - position = 0, - keyName = "attackerPlayerColor", - name = "Attacker color", - description = "This is the color that will be used to highlight attackers." - ) - default Color attackerPlayerColor() - { - return new Color(0xFF0006); - } - @ConfigItem( position = 1, - keyName = "potentialPlayerColor", - name = "Potential Attacker color", - description = "This is the color that will be used to highlight potential attackers." - ) - default Color potentialPlayerColor() - { - return new Color(0xFFFF00); - } - - @ConfigItem( - position = 2, - keyName = "attackerTargetTimeout", - name = "Attacker Timeout", - description = "Seconds until attacker is no longer highlighted." - ) - default int attackerTargetTimeout() - { - return 10; - } - - @ConfigItem( - position = 3, - keyName = "potentialTargetTimeout", - name = "Potential Attacker Timeout", - description = "Seconds until potential attacker is no longer highlighted." - ) - default int potentialTargetTimeout() - { - return 10; - } - - @ConfigItem( - position = 4, - keyName = "newSpawnTimeout", - name = "New Player Timeout", - description = "Seconds until logged in/spawned player is no longer highlighted." - ) - default int newSpawnTimeout() - { - return 5; - } - - @ConfigItem( - position = 5, keyName = "ignoreFriends", name = "Ignore Friends", description = "This lets you decide whether you want friends to be highlighted by this plugin." @@ -99,7 +43,7 @@ public interface PrayAgainstPlayerConfig extends Config } @ConfigItem( - position = 6, + position = 2, keyName = "ignoreClanMates", name = "Ignore Clan Mates", description = "This lets you decide whether you want clan mates to be highlighted by this plugin." @@ -110,40 +54,7 @@ public interface PrayAgainstPlayerConfig extends Config } @ConfigItem( - position = 7, - keyName = "markNewPlayer", - name = "Mark new player as potential attacker", - description = "Marks someone that logged in or teleported as a potential attacker for your safety\nDO NOT RUN THIS IN WORLD 1-2 GRAND EXCHANGE!" - ) - default boolean markNewPlayer() - { - return false; - } - - @ConfigItem( - position = 8, - keyName = "drawTargetPrayAgainst", - name = "Draw what to pray on attacker", - description = "Tells you what to pray from what weapon the attacker is holding" - ) - default boolean drawTargetPrayAgainst() - { - return true; - } - - @ConfigItem( - position = 9, - keyName = "drawPotentialTargetPrayAgainst", - name = "Draw what to pray on potential attacker", - description = "Tells you what to pray from what weapon the potential attacker is holding" - ) - default boolean drawPotentialTargetPrayAgainst() - { - return true; - } - - @ConfigItem( - position = 10, + position = 3, keyName = "drawTargetPrayAgainstPrayerTab", name = "Draw what to pray from prayer tab", description = "Tells you what to pray from what weapon the attacker is holding from the prayer tab" @@ -152,81 +63,4 @@ public interface PrayAgainstPlayerConfig extends Config { return false; } - - @ConfigItem( - position = 11, - keyName = "drawTargetsName", - name = "Draw name on attacker", - description = "Configures whether or not the attacker\'s name should be shown" - ) - default boolean drawTargetsName() - { - return true; - } - - @ConfigItem( - position = 12, - keyName = "drawPotentialTargetsName", - name = "Draw name on potential attacker", - description = "Configures whether or not the potential attacker\'s name should be shown" - ) - default boolean drawPotentialTargetsName() - { - return true; - } - - @ConfigItem( - position = 13, - keyName = "drawTargetHighlight", - name = "Draw highlight around attacker", - description = "Configures whether or not the attacker should be highlighted" - ) - default boolean drawTargetHighlight() - { - return true; - } - - @ConfigItem( - position = 14, - keyName = "drawPotentialTargetHighlight", - name = "Draw highlight around potential attacker", - description = "Configures whether or not the potential attacker should be highlighted" - ) - default boolean drawPotentialTargetHighlight() - { - return true; - } - - @ConfigItem( - position = 15, - keyName = "drawTargetTile", - name = "Draw tile under attacker", - description = "Configures whether or not the attacker\'s tile be highlighted" - ) - default boolean drawTargetTile() - { - return false; - } - - @ConfigItem( - position = 16, - keyName = "drawPotentialTargetTile", - name = "Draw tile under potential attacker", - description = "Configures whether or not the potential attacker\'s tile be highlighted" - ) - default boolean drawPotentialTargetTile() - { - return false; - } - - @ConfigItem( - position = 17, - keyName = "drawUnknownWeapons", - name = "Draw unknown weapons", - description = "Configures whether or not the unknown weapons should be shown when a player equips one" - ) - default boolean drawUnknownWeapons() - { - return false; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java index 7ba5f8835d..9a5298af4e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlay.java @@ -24,204 +24,55 @@ package net.runelite.client.plugins.prayagainstplayer; -import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.awt.Polygon; -import java.awt.image.BufferedImage; -import java.util.ConcurrentModificationException; import javax.inject.Inject; import javax.inject.Singleton; -import net.runelite.api.Client; -import net.runelite.api.ItemDefinition; -import net.runelite.api.Player; -import net.runelite.api.Point; -import net.runelite.api.kit.KitType; -import net.runelite.api.util.Text; +import net.runelite.client.game.PlayerContainer; +import net.runelite.client.game.PlayerManager; +import net.runelite.client.graphics.ModelOutlineRenderer; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; @Singleton class PrayAgainstPlayerOverlay extends Overlay { - private final PrayAgainstPlayerPlugin plugin; - private final Client client; + private final PlayerManager playerManager; + private final ModelOutlineRenderer outlineRenderer; @Inject - private PrayAgainstPlayerOverlay(final PrayAgainstPlayerPlugin plugin, final Client client) + private PrayAgainstPlayerOverlay( + final PrayAgainstPlayerPlugin plugin, + final PlayerManager playerManager, + final ModelOutlineRenderer outlineRenderer + ) { - super(plugin); this.plugin = plugin; - this.client = client; - + this.playerManager = playerManager; + this.outlineRenderer = outlineRenderer; setLayer(OverlayLayer.ABOVE_SCENE); setPosition(OverlayPosition.DYNAMIC); setPriority(OverlayPriority.HIGH); } - @Override public Dimension render(Graphics2D graphics) { - renderPotentialPlayers(graphics); - renderAttackingPlayers(graphics); + for (PlayerContainer player : playerManager.getAllAttackers()) + { + if (player.getPlayer() == null + || (plugin.isIgnoreFriends() && player.isFriend() + || (plugin.isIgnoreClanMates() && player.isClan())) + ) + { + continue; + } + outlineRenderer.drawOutline(player.getPlayer(), 4, player.getAttackStyle().getColor()); + + } return null; } - - private void renderPotentialPlayers(Graphics2D graphics) - { - if (plugin.getPotentialPlayersAttackingMe() == null || !plugin.getPotentialPlayersAttackingMe().isEmpty()) - { - try - { - if (plugin.getPotentialPlayersAttackingMe() != null) - { - for (PlayerContainer container : plugin.getPotentialPlayersAttackingMe()) - { - if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) - { - plugin.removePlayerFromPotentialContainer(container); - } - if (plugin.isDrawPotentialTargetsName()) - { - renderNameAboveHead(graphics, container.getPlayer(), plugin.getPotentialPlayerColor()); - } - if (plugin.isDrawPotentialTargetHighlight()) - { - renderHighlightedPlayer(graphics, container.getPlayer(), plugin.getPotentialPlayerColor()); - } - if (plugin.isDrawPotentialTargetTile()) - { - renderTileUnderPlayer(graphics, container.getPlayer(), plugin.getPotentialPlayerColor()); - } - if (plugin.isDrawPotentialTargetPrayAgainst()) - { - renderPrayAgainstOnPlayer(graphics, container.getPlayer(), plugin.getPotentialPlayerColor()); - } - } - } - } - catch (ConcurrentModificationException ignored) - { - } - } - } - - private void renderAttackingPlayers(Graphics2D graphics) - { - if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) - { - try - { - if (plugin.getPlayersAttackingMe() != null) - { - for (PlayerContainer container : plugin.getPlayersAttackingMe()) - { - if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) - { - plugin.removePlayerFromAttackerContainer(container); - } - - if (plugin.isDrawTargetsName()) - { - renderNameAboveHead(graphics, container.getPlayer(), plugin.getAttackerPlayerColor()); - } - if (plugin.isDrawTargetHighlight()) - { - renderHighlightedPlayer(graphics, container.getPlayer(), plugin.getAttackerPlayerColor()); - } - if (plugin.isDrawTargetTile()) - { - renderTileUnderPlayer(graphics, container.getPlayer(), plugin.getAttackerPlayerColor()); - } - if (plugin.isDrawTargetPrayAgainst()) - { - renderPrayAgainstOnPlayer(graphics, container.getPlayer(), plugin.getAttackerPlayerColor()); - } - } - } - } - catch (ConcurrentModificationException ignored) - { - } - } - } - - private void renderNameAboveHead(Graphics2D graphics, Player player, Color color) - { - final String name = Text.sanitize(player.getName()); - final int offset = player.getLogicalHeight() + 40; - Point textLocation = player.getCanvasTextLocation(graphics, name, offset); - if (textLocation != null) - { - OverlayUtil.renderTextLocation(graphics, textLocation, name, color); - } - } - - private void renderHighlightedPlayer(Graphics2D graphics, Player player, Color color) - { - try - { - OverlayUtil.renderPolygon(graphics, player.getConvexHull(), color); - } - catch (NullPointerException ignored) - { - } - } - - private void renderTileUnderPlayer(Graphics2D graphics, Player player, Color color) - { - Polygon poly = player.getCanvasTilePoly(); - OverlayUtil.renderPolygon(graphics, poly, color); - } - - private void renderPrayAgainstOnPlayer(Graphics2D graphics, Player player, Color color) - { - final int offset = (player.getLogicalHeight() / 2) + 75; - BufferedImage icon; - - switch (WeaponType.checkWeaponOnPlayer(client, player)) - { - case WEAPON_MELEE: - icon = plugin.getProtectionIcon(WeaponType.WEAPON_MELEE); - break; - case WEAPON_MAGIC: - icon = plugin.getProtectionIcon(WeaponType.WEAPON_MAGIC); - break; - case WEAPON_RANGED: - icon = plugin.getProtectionIcon(WeaponType.WEAPON_RANGED); - break; - default: - icon = null; - break; - } - try - { - if (icon != null) - { - Point point = player.getCanvasImageLocation(icon, offset); - OverlayUtil.renderImageLocation(graphics, point, icon); - } - else - { - if (plugin.isDrawUnknownWeapons()) - { - int itemId = player.getPlayerAppearance().getEquipmentId(KitType.WEAPON); - ItemDefinition itemComposition = client.getItemDefinition(itemId); - - final String str = itemComposition.getName().toUpperCase(); - Point point = player.getCanvasTextLocation(graphics, str, offset); - OverlayUtil.renderTextLocation(graphics, point, str, color); - } - } - } - catch (Exception ignored) - { - } - } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java index c4380983f3..62317d12f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerOverlayPrayerTab.java @@ -29,13 +29,15 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Polygon; import java.awt.Rectangle; -import java.util.ConcurrentModificationException; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; -import net.runelite.api.Player; +import net.runelite.api.VarClientInt; +import net.runelite.api.vars.InterfaceTab; import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.game.AttackStyle; +import net.runelite.client.game.PlayerContainer; +import net.runelite.client.game.PlayerManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; @@ -46,16 +48,17 @@ import net.runelite.client.ui.overlay.OverlayUtil; class PrayAgainstPlayerOverlayPrayerTab extends Overlay { - private final PrayAgainstPlayerPlugin plugin; + private final PlayerManager playerManager; private final Client client; @Inject - private PrayAgainstPlayerOverlayPrayerTab(final PrayAgainstPlayerPlugin plugin, final Client client) + private PrayAgainstPlayerOverlayPrayerTab( + final PlayerManager playerManager, + final Client client + ) { - super(plugin); - this.plugin = plugin; this.client = client; - + this.playerManager = playerManager; setPosition(OverlayPosition.DETACHED); setLayer(OverlayLayer.ALWAYS_ON_TOP); setPriority(OverlayPriority.MED); @@ -65,55 +68,30 @@ class PrayAgainstPlayerOverlayPrayerTab extends Overlay @Override public Dimension render(Graphics2D graphics) { - if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) + for (PlayerContainer player : playerManager.getAllAttackers()) { - try + if (player.getAttackStyle() == AttackStyle.UNKNOWN) { - if (plugin.getPlayersAttackingMe() != null) - { - for (PlayerContainer container : plugin.getPlayersAttackingMe()) - { - if (plugin.getPlayersAttackingMe() != null && plugin.getPlayersAttackingMe().size() == 1 && - plugin.isDrawTargetPrayAgainstPrayerTab()) - { - renderPrayerToClick(graphics, container.getPlayer()); - } - } - } + continue; } - catch (ConcurrentModificationException ignored) + + final Widget widget = client.getWidget(player.getAttackStyle().getPrayer().getWidgetInfo()); + + if (widget == null) { + continue; + } + + if (client.getVar(VarClientInt.INTERFACE_TAB) == InterfaceTab.PRAYER.getId() && + !client.isPrayerActive(player.getAttackStyle().getPrayer())) + { + OverlayUtil.renderPolygon(graphics, rectangleToPolygon(widget.getBounds()), Color.RED); + break; } } return null; } - private void renderPrayerToClick(Graphics2D graphics, Player player) - { - Widget PROTECT_FROM_MAGIC = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC); - Widget PROTECT_FROM_RANGED = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES); - Widget PROTECT_FROM_MELEE = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MELEE); - Color color = Color.RED; - if (PROTECT_FROM_MELEE.isHidden()) - { - return; - } - switch (WeaponType.checkWeaponOnPlayer(client, player)) - { - case WEAPON_MAGIC: - OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MAGIC.getBounds()), color); - break; - case WEAPON_MELEE: - OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MELEE.getBounds()), color); - break; - case WEAPON_RANGED: - OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_RANGED.getBounds()), color); - break; - default: - break; - } - } - private static Polygon rectangleToPolygon(Rectangle rect) { int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; @@ -121,5 +99,4 @@ class PrayAgainstPlayerOverlayPrayerTab extends Overlay return new Polygon(xpoints, ypoints, 4); } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java index 22f86db83c..3a1bf874e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java @@ -25,28 +25,11 @@ package net.runelite.client.plugins.prayagainstplayer; import com.google.inject.Provides; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.WritableRaster; -import java.util.ArrayList; -import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; -import net.runelite.api.AnimationID; import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.Player; -import net.runelite.api.SpriteID; -import net.runelite.api.events.AnimationChanged; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.InteractingChanged; -import net.runelite.api.events.PlayerDespawned; -import net.runelite.api.events.PlayerSpawned; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; @@ -55,7 +38,6 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ImageUtil; @PluginDescriptor( name = "Pray Against Player", @@ -64,75 +46,26 @@ import net.runelite.client.util.ImageUtil; type = PluginType.PVP, enabledByDefault = false ) - -/** - * I am fully aware that there is plenty of overhead and is a MESS! - * If you'd like to contribute please do! - */ @Singleton +@Getter(AccessLevel.PACKAGE) public class PrayAgainstPlayerPlugin extends Plugin { - - private static final int[] PROTECTION_ICONS = { - SpriteID.PRAYER_PROTECT_FROM_MISSILES, - SpriteID.PRAYER_PROTECT_FROM_MELEE, - SpriteID.PRAYER_PROTECT_FROM_MAGIC - }; - private static final Dimension PROTECTION_ICON_DIMENSION = new Dimension(33, 33); - private static final Color PROTECTION_ICON_OUTLINE_COLOR = new Color(33, 33, 33); - private final BufferedImage[] ProtectionIcons = new BufferedImage[PROTECTION_ICONS.length]; - - private List potentialPlayersAttackingMe; - private List playersAttackingMe; - @Inject private Client client; - @Inject private SpriteManager spriteManager; - @Inject private OverlayManager overlayManager; - @Inject private PrayAgainstPlayerOverlay overlay; - @Inject private PrayAgainstPlayerOverlayPrayerTab overlayPrayerTab; - @Inject private PrayAgainstPlayerConfig config; - @Getter(AccessLevel.PACKAGE) - private Color attackerPlayerColor; - @Getter(AccessLevel.PACKAGE) - private Color potentialPlayerColor; - private int attackerTargetTimeout; - private int potentialTargetTimeout; - private int newSpawnTimeout; private boolean ignoreFriends; private boolean ignoreClanMates; - private boolean markNewPlayer; - @Getter(AccessLevel.PACKAGE) - private boolean drawTargetPrayAgainst; - @Getter(AccessLevel.PACKAGE) - private boolean drawPotentialTargetPrayAgainst; - @Getter(AccessLevel.PACKAGE) private boolean drawTargetPrayAgainstPrayerTab; - @Getter(AccessLevel.PACKAGE) - private boolean drawTargetsName; - @Getter(AccessLevel.PACKAGE) - private boolean drawPotentialTargetsName; - @Getter(AccessLevel.PACKAGE) - private boolean drawTargetHighlight; - @Getter(AccessLevel.PACKAGE) - private boolean drawPotentialTargetHighlight; - @Getter(AccessLevel.PACKAGE) - private boolean drawTargetTile; - @Getter(AccessLevel.PACKAGE) - private boolean drawPotentialTargetTile; - @Getter(AccessLevel.PACKAGE) - private boolean drawUnknownWeapons; @Provides PrayAgainstPlayerConfig provideConfig(ConfigManager configManager) @@ -140,22 +73,10 @@ public class PrayAgainstPlayerPlugin extends Plugin return configManager.getConfig(PrayAgainstPlayerConfig.class); } - @Subscribe - private void onGameStateChanged(GameStateChanged gameStateChanged) - { - if (gameStateChanged.getGameState() == GameState.LOGGED_IN) - { - loadProtectionIcons(); - } - } - @Override protected void startUp() { updateConfig(); - - potentialPlayersAttackingMe = new ArrayList<>(); - playersAttackingMe = new ArrayList<>(); overlayManager.add(overlay); overlayManager.add(overlayPrayerTab); } @@ -167,253 +88,6 @@ public class PrayAgainstPlayerPlugin extends Plugin overlayManager.remove(overlayPrayerTab); } - @Subscribe - private void onAnimationChanged(AnimationChanged animationChanged) - { - if ((animationChanged.getActor() instanceof Player) && (animationChanged.getActor().getInteracting() instanceof Player) && (animationChanged.getActor().getInteracting() == client.getLocalPlayer())) - { - Player sourcePlayer = (Player) animationChanged.getActor(); - - // is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list - if (client.isFriended(sourcePlayer.getName(), true) && this.ignoreFriends) - { - return; - } - if (client.isClanMember(sourcePlayer.getName()) && this.ignoreClanMates) - { - return; - } - - if ((sourcePlayer.getAnimation() != -1) && (!isBlockAnimation(sourcePlayer.getAnimation()))) - { - // if attacker attacks again, reset his timer so overlay doesn't go away - if (findPlayerInAttackerList(sourcePlayer) != null) - { - resetPlayerFromAttackerContainerTimer(findPlayerInAttackerList(sourcePlayer)); - } - // if he attacks and he was in the potential attackers list, remove him - if (!potentialPlayersAttackingMe.isEmpty() && potentialPlayersAttackingMe.contains(findPlayerInPotentialList(sourcePlayer))) - { - removePlayerFromPotentialContainer(findPlayerInPotentialList(sourcePlayer)); - } - // if he's not in the attackers list, add him - if (findPlayerInAttackerList(sourcePlayer) == null) - { - PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (this.attackerTargetTimeout * 1000)); - playersAttackingMe.add(container); - } - } - } - } - - @Subscribe - private void onInteractingChanged(InteractingChanged interactingChanged) - { - // if someone interacts with you, add them to the potential attackers list - if ((interactingChanged.getSource() instanceof Player) && (interactingChanged.getTarget() instanceof Player)) - { - Player sourcePlayer = (Player) interactingChanged.getSource(); - Player targetPlayer = (Player) interactingChanged.getTarget(); - if ((targetPlayer == client.getLocalPlayer()) && (findPlayerInPotentialList(sourcePlayer) == null)) - { //we're being interacted with - - // is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list - if (client.isFriended(sourcePlayer.getName(), true) && this.ignoreFriends) - { - return; - } - if (client.isClanMember(sourcePlayer.getName()) && this.ignoreClanMates) - { - return; - } - - PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (this.potentialTargetTimeout * 1000)); - potentialPlayersAttackingMe.add(container); - } - } - } - - @Subscribe - private void onPlayerDespawned(PlayerDespawned playerDespawned) - { - PlayerContainer container = findPlayerInAttackerList(playerDespawned.getPlayer()); - PlayerContainer container2 = findPlayerInPotentialList(playerDespawned.getPlayer()); - if (container != null) - { - playersAttackingMe.remove(container); - } - if (container2 != null) - { - potentialPlayersAttackingMe.remove(container2); - } - } - - @Subscribe - private void onPlayerSpawned(PlayerSpawned playerSpawned) - { - if (this.markNewPlayer) - { - Player p = playerSpawned.getPlayer(); - - if (client.isFriended(p.getName(), true) && this.ignoreFriends) - { - return; - } - if (client.isClanMember(p.getName()) && this.ignoreClanMates) - { - return; - } - - PlayerContainer container = findPlayerInPotentialList(p); - if (container == null) - { - container = new PlayerContainer(p, System.currentTimeMillis(), (this.newSpawnTimeout * 1000)); - potentialPlayersAttackingMe.add(container); - } - } - } - - private PlayerContainer findPlayerInAttackerList(Player player) - { - if (playersAttackingMe.isEmpty()) - { - return null; - } - for (PlayerContainer container : playersAttackingMe) - { - if (container.getPlayer() == player) - { - return container; - } - } - return null; - } - - private PlayerContainer findPlayerInPotentialList(Player player) - { - if (potentialPlayersAttackingMe.isEmpty()) - { - return null; - } - for (PlayerContainer container : potentialPlayersAttackingMe) - { - if (container.getPlayer() == player) - { - return container; - } - } - return null; - } - - /** - * Resets player timer in case he attacks again, so his highlight doesn't go away so easily - * - * @param container - */ - private void resetPlayerFromAttackerContainerTimer(PlayerContainer container) - { - removePlayerFromAttackerContainer(container); - PlayerContainer newContainer = new PlayerContainer(container.getPlayer(), System.currentTimeMillis(), (this.attackerTargetTimeout * 1000)); - playersAttackingMe.add(newContainer); - } - - void removePlayerFromPotentialContainer(PlayerContainer container) - { - if ((potentialPlayersAttackingMe != null) && (!potentialPlayersAttackingMe.isEmpty())) - { - potentialPlayersAttackingMe.remove(container); - } - } - - void removePlayerFromAttackerContainer(PlayerContainer container) - { - if ((playersAttackingMe != null) && (!playersAttackingMe.isEmpty())) - { - playersAttackingMe.remove(container); - } - } - - private boolean isBlockAnimation(int anim) - { - switch (anim) - { - case AnimationID.BLOCK_DEFENDER: - case AnimationID.BLOCK_NO_SHIELD: - case AnimationID.BLOCK_SHIELD: - case AnimationID.BLOCK_SWORD: - case AnimationID.BLOCK_UNARMED: - return true; - default: - return false; - } - } - - List getPotentialPlayersAttackingMe() - { - return potentialPlayersAttackingMe; - } - - List getPlayersAttackingMe() - { - return playersAttackingMe; - } - - //All of the methods below are from the Zulrah plugin!!! Credits to it's respective owner - private void loadProtectionIcons() - { - for (int i = 0; i < PROTECTION_ICONS.length; i++) - { - final int resource = PROTECTION_ICONS[i]; - ProtectionIcons[i] = rgbaToIndexedBufferedImage(ProtectionIconFromSprite(spriteManager.getSprite(resource, 0))); - } - } - - private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) - { - final BufferedImage indexedImage = new BufferedImage( - sourceBufferedImage.getWidth(), - sourceBufferedImage.getHeight(), - BufferedImage.TYPE_BYTE_INDEXED); - - final ColorModel cm = indexedImage.getColorModel(); - final IndexColorModel icm = (IndexColorModel) cm; - - final int size = icm.getMapSize(); - final byte[] reds = new byte[size]; - final byte[] greens = new byte[size]; - final byte[] blues = new byte[size]; - icm.getReds(reds); - icm.getGreens(greens); - icm.getBlues(blues); - - final WritableRaster raster = indexedImage.getRaster(); - final int pixel = raster.getSample(0, 0, 0); - final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); - final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); - resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); - return resultIndexedImage; - } - - private static BufferedImage ProtectionIconFromSprite(final BufferedImage freezeSprite) - { - final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, PROTECTION_ICON_DIMENSION.width, PROTECTION_ICON_DIMENSION.height); - return ImageUtil.outlineImage(freezeCanvas, PROTECTION_ICON_OUTLINE_COLOR); - } - - BufferedImage getProtectionIcon(WeaponType weaponType) - { - switch (weaponType) - { - case WEAPON_RANGED: - return ProtectionIcons[0]; - case WEAPON_MELEE: - return ProtectionIcons[1]; - case WEAPON_MAGIC: - return ProtectionIcons[2]; - } - return null; - } - @Subscribe private void onConfigChanged(ConfigChanged event) { @@ -427,23 +101,17 @@ public class PrayAgainstPlayerPlugin extends Plugin private void updateConfig() { - this.attackerPlayerColor = config.attackerPlayerColor(); - this.potentialPlayerColor = config.potentialPlayerColor(); - this.attackerTargetTimeout = config.attackerTargetTimeout(); - this.potentialTargetTimeout = config.potentialTargetTimeout(); - this.newSpawnTimeout = config.newSpawnTimeout(); this.ignoreFriends = config.ignoreFriends(); this.ignoreClanMates = config.ignoreClanMates(); - this.markNewPlayer = config.markNewPlayer(); - this.drawTargetPrayAgainst = config.drawTargetPrayAgainst(); - this.drawPotentialTargetPrayAgainst = config.drawPotentialTargetPrayAgainst(); this.drawTargetPrayAgainstPrayerTab = config.drawTargetPrayAgainstPrayerTab(); - this.drawTargetsName = config.drawTargetsName(); - this.drawPotentialTargetsName = config.drawPotentialTargetsName(); - this.drawTargetHighlight = config.drawTargetHighlight(); - this.drawPotentialTargetHighlight = config.drawPotentialTargetHighlight(); - this.drawTargetTile = config.drawTargetTile(); - this.drawPotentialTargetTile = config.drawPotentialTargetTile(); - this.drawUnknownWeapons = config.drawUnknownWeapons(); + + if (this.drawTargetPrayAgainstPrayerTab) + { + overlayManager.add(overlayPrayerTab); + } + else + { + overlayManager.remove(overlayPrayerTab); + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java deleted file mode 100644 index d6078e556e..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/WeaponType.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2019, gazivodag - * 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.prayagainstplayer; - -import net.runelite.api.Client; -import net.runelite.api.ItemDefinition; -import net.runelite.api.Player; -import net.runelite.api.kit.KitType; - -enum WeaponType -{ - - WEAPON_MELEE, - WEAPON_RANGED, - WEAPON_MAGIC, - WEAPON_UNKNOWN; - - /** - * im fully aware this could of been done better!!! - * - * @param client - * @param attacker - * @return - */ - public static WeaponType checkWeaponOnPlayer(Client client, Player attacker) - { - int itemId = attacker.getPlayerAppearance().getEquipmentId(KitType.WEAPON); - ItemDefinition itemComposition = client.getItemDefinition(itemId); - String weaponNameGivenLowerCase = itemComposition.getName().toLowerCase(); - - if (itemId == -1) - { - return WEAPON_MELEE; - } - if (weaponNameGivenLowerCase.toLowerCase().contains("null")) - { - return WEAPON_MELEE; - } - - for (String meleeWeaponName : meleeWeaponNames) - { - if (weaponNameGivenLowerCase.contains(meleeWeaponName) && !weaponNameGivenLowerCase.contains("thrownaxe")) - { - return WEAPON_MELEE; - } - } - - for (String rangedWeaponName : rangedWeaponNames) - { - if (weaponNameGivenLowerCase.contains(rangedWeaponName)) - { - return WEAPON_RANGED; - } - } - - for (String magicWeaponName : magicWeaponNames) - { - if (weaponNameGivenLowerCase.contains(magicWeaponName)) - { - return WEAPON_MAGIC; - } - } - - return WEAPON_UNKNOWN; - - } - - private static final String[] meleeWeaponNames = { - "sword", - "scimitar", - "dagger", - "spear", - "mace", - "axe", - "whip", - "tentacle", - "-ket-", - "-xil-", - "warhammer", - "halberd", - "claws", - "hasta", - "scythe", - "maul", - "anchor", - "sabre", - "excalibur", - "machete", - "dragon hunter lance", - "event rpg", - "silverlight", - "darklight", - "arclight", - "flail", - "granite hammer", - "rapier", - "bulwark" - }; - - private static final String[] rangedWeaponNames = { - "bow", - "blowpipe", - "xil-ul", - "knife", - "dart", - "thrownaxe", - "chinchompa", - "ballista" - }; - - private static final String[] magicWeaponNames = { - "staff", - "trident", - "wand", - "dawnbringer" - }; - -} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java index 56fad5dd38..d36d369e89 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java @@ -45,12 +45,14 @@ import static net.runelite.api.SkullIcon.DEAD_MAN_TWO; import static net.runelite.api.SkullIcon.SKULL; import static net.runelite.api.SkullIcon.SKULL_FIGHT_PIT; import net.runelite.api.coords.LocalPoint; +import net.runelite.api.events.PlayerAppearanceChanged; import net.runelite.api.mixins.Copy; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.MethodHook; import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSBuffer; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSModel; import net.runelite.rs.api.RSPlayer; @@ -236,4 +238,20 @@ public abstract class RSPlayerMixin implements RSPlayer { friended = client.getFriendManager().isFriended(getRsName(), false); } + + @Copy("read") + public abstract void rs$read(RSBuffer buffer); + + @Replace("read") + public void rl$read(RSBuffer buffer) + { + final long appearanceHash = getPlayerAppearance() == null ? 0 : getPlayerAppearance().getHash(); + + rs$read(buffer); + + if (getPlayerAppearance().getHash() != appearanceHash) + { + client.getCallbacks().post(PlayerAppearanceChanged.class, new PlayerAppearanceChanged(this)); + } + } } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSPlayerAppearance.java b/runescape-api/src/main/java/net/runelite/rs/api/RSPlayerAppearance.java index 3f084e3114..8c9f2499be 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSPlayerAppearance.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSPlayerAppearance.java @@ -11,6 +11,9 @@ public interface RSPlayerAppearance extends PlayerAppearance @Import("bodyColors") int[] getBodyPartColours(); + @Import("hash") + long getHash(); + @Import("equipment") @Override int[] getEquipmentIds(); diff --git a/runescape-client/src/main/java/PlayerAppearance.java b/runescape-client/src/main/java/PlayerAppearance.java index f63f4d5949..dfaab89733 100644 --- a/runescape-client/src/main/java/PlayerAppearance.java +++ b/runescape-client/src/main/java/PlayerAppearance.java @@ -41,7 +41,8 @@ public class PlayerAppearance { @ObfuscatedGetter( longValue = 8570520165784208047L ) - long field2547; + @Export("hash") + long hash; @ObfuscatedName("p") @ObfuscatedGetter( longValue = -3088053679670010611L @@ -186,40 +187,47 @@ public class PlayerAppearance { garbageValue = "1306042907" ) @Export("setHash") - void setHash() { - long var1 = this.field2547; + void setHash() + { + long var1 = this.hash; int var3 = this.equipment[5]; int var4 = this.equipment[9]; this.equipment[5] = var4; this.equipment[9] = var3; - this.field2547 = 0L; + this.hash = 0L; int var5; - for (var5 = 0; var5 < 12; ++var5) { - this.field2547 <<= 4; - if (this.equipment[var5] >= 256) { - this.field2547 += (long)(this.equipment[var5] - 256); + for (var5 = 0; var5 < 12; ++var5) + { + this.hash <<= 4; + if (this.equipment[var5] >= 256) + { + this.hash += (long) (this.equipment[var5] - 256); } } - if (this.equipment[0] >= 256) { - this.field2547 += (long)(this.equipment[0] - 256 >> 4); + if (this.equipment[0] >= 256) + { + this.hash += (long) (this.equipment[0] - 256 >> 4); } - if (this.equipment[1] >= 256) { - this.field2547 += (long)(this.equipment[1] - 256 >> 8); + if (this.equipment[1] >= 256) + { + this.hash += (long) (this.equipment[1] - 256 >> 8); } - for (var5 = 0; var5 < 5; ++var5) { - this.field2547 <<= 3; - this.field2547 += (long)this.bodyColors[var5]; + for (var5 = 0; var5 < 5; ++var5) + { + this.hash <<= 3; + this.hash += (long) this.bodyColors[var5]; } - this.field2547 <<= 1; - this.field2547 += (long)(this.isFemale ? 1 : 0); + this.hash <<= 1; + this.hash += (long) (this.isFemale ? 1 : 0); this.equipment[5] = var3; this.equipment[9] = var4; - if (0L != var1 && this.field2547 != var1) { + if (0L != var1 && this.hash != var1) + { PlayerAppearance_cachedModels.remove(var1); } @@ -234,18 +242,22 @@ public class PlayerAppearance { public Model getModel(SequenceDefinition var1, int var2, SequenceDefinition var3, int var4) { if (this.npcTransformId != -1) { return VarcInt.getNpcDefinition(this.npcTransformId).getModel(var1, var2, var3, var4); - } else { - long var5 = this.field2547; + } else + { + long var5 = this.hash; int[] var7 = this.equipment; - if (var1 != null && (var1.shield >= 0 || var1.weapon >= 0)) { + if (var1 != null && (var1.shield >= 0 || var1.weapon >= 0)) + { var7 = new int[12]; - for (int var15 = 0; var15 < 12; ++var15) { + for (int var15 = 0; var15 < 12; ++var15) + { var7[var15] = this.equipment[var15]; } - if (var1.shield >= 0) { - var5 += (long)(var1.shield - this.equipment[5] << 40); + if (var1.shield >= 0) + { + var5 += (long) (var1.shield - this.equipment[5] << 40); var7[5] = var1.shield; }