chore: init
This commit is contained in:
@@ -0,0 +1,709 @@
|
||||
package com.example.livedashboard;
|
||||
|
||||
import com.example.livedashboard.overlay.GpsPathOverlay;
|
||||
import com.example.livedashboard.pathfinding.Pathfinder;
|
||||
import com.example.livedashboard.pathfinding.ShortcutData;
|
||||
import com.example.livedashboard.ui.LiveDashboardPanel;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
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.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Slf4j
|
||||
@PluginDescriptor(
|
||||
name = "Live Web Dashboard",
|
||||
description = "Zeigt Echtzeit-Koordinaten, Vitals, Map, Hindernis-GPS-Navigation, Ausruestung, Inventar und Bank an",
|
||||
tags = {"telemetry", "web", "dashboard", "live", "coordinates", "coords", "map", "bank", "inventory", "equipment", "ge", "gps"}
|
||||
)
|
||||
public class LiveDashboardPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private GpsPathOverlay gpsPathOverlay;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private LiveDashboardConfig config;
|
||||
|
||||
private LiveDashboardServer server;
|
||||
private LiveDashboardPanel panel;
|
||||
private NavigationButton navButton;
|
||||
private int tickCounter = 0;
|
||||
|
||||
@Getter
|
||||
private volatile WorldPoint gpsTarget = null;
|
||||
|
||||
@Getter
|
||||
private volatile List<WorldPoint> gpsPath = Collections.emptyList();
|
||||
|
||||
@Getter
|
||||
private volatile List<ShortcutData> nearbyShortcuts = Collections.emptyList();
|
||||
|
||||
private WorldPoint lastCalculatedPlayerPos = null;
|
||||
private WorldPoint lastCalculatedTargetPos = null;
|
||||
|
||||
// Cached containers (Bank persists once opened during session)
|
||||
private List<Map<String, Object>> cachedInventory = new ArrayList<>();
|
||||
private List<Map<String, Object>> cachedEquipment = new ArrayList<>();
|
||||
private List<Map<String, Object>> cachedBank = new ArrayList<>();
|
||||
|
||||
// Total item count index (Item ID -> total qty across inv, equip, bank)
|
||||
private Map<Integer, Map<String, Integer>> cachedItemSummary = new HashMap<>();
|
||||
|
||||
// Natural regeneration trackers
|
||||
private int hpRegenTicksLeft = 100;
|
||||
private int lastHp = -1;
|
||||
|
||||
private int energyRegenTicksLeft = 10;
|
||||
private int lastEnergy = -1;
|
||||
|
||||
private WorldPoint lastWorldPoint = null;
|
||||
|
||||
@Provides
|
||||
LiveDashboardConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(LiveDashboardConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
log.info("Live Dashboard Plugin startet...");
|
||||
server = new LiveDashboardServer(this);
|
||||
panel = new LiveDashboardPanel(this);
|
||||
|
||||
BufferedImage icon = null;
|
||||
try
|
||||
{
|
||||
icon = ImageUtil.loadImageResource(getClass(), "/com/example/livedashboard/icon.png");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
icon = ImageUtil.loadImageResource(getClass(), "/com/example/icon.png");
|
||||
}
|
||||
catch (Exception ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
navButton = NavigationButton.builder()
|
||||
.tooltip("Live Web Dashboard")
|
||||
.icon(icon)
|
||||
.priority(6)
|
||||
.panel(panel)
|
||||
.build();
|
||||
|
||||
clientToolbar.addNavigation(navButton);
|
||||
overlayManager.add(gpsPathOverlay);
|
||||
|
||||
startServer(config.port());
|
||||
|
||||
clientThread.invokeLater(this::collectAndSendTelemetry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
log.info("Live Dashboard Plugin stoppt...");
|
||||
overlayManager.remove(gpsPathOverlay);
|
||||
|
||||
if (server != null)
|
||||
{
|
||||
server.stop();
|
||||
server = null;
|
||||
}
|
||||
|
||||
if (navButton != null)
|
||||
{
|
||||
clientToolbar.removeNavigation(navButton);
|
||||
navButton = null;
|
||||
}
|
||||
panel = null;
|
||||
setGpsTarget(null);
|
||||
cachedInventory.clear();
|
||||
cachedEquipment.clear();
|
||||
cachedBank.clear();
|
||||
cachedItemSummary.clear();
|
||||
}
|
||||
|
||||
public void setGpsTarget(WorldPoint target)
|
||||
{
|
||||
this.gpsTarget = target;
|
||||
if (target == null)
|
||||
{
|
||||
this.gpsPath = Collections.emptyList();
|
||||
this.nearbyShortcuts = Collections.emptyList();
|
||||
this.lastCalculatedPlayerPos = null;
|
||||
this.lastCalculatedTargetPos = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
clientThread.invokeLater(this::recalculatePath);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleServer()
|
||||
{
|
||||
if (server != null && server.isRunning())
|
||||
{
|
||||
server.stop();
|
||||
if (panel != null)
|
||||
{
|
||||
panel.updateServerState(false, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
startServer(config.port());
|
||||
}
|
||||
}
|
||||
|
||||
private void startServer(int port)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (server == null)
|
||||
{
|
||||
server = new LiveDashboardServer(this);
|
||||
}
|
||||
server.start(port);
|
||||
if (panel != null)
|
||||
{
|
||||
panel.updateServerState(true, server.getPort());
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Fehler beim Starten des Dashboard Webservers auf Port {}", port, e);
|
||||
if (panel != null)
|
||||
{
|
||||
panel.updateServerState(false, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getServerUrl()
|
||||
{
|
||||
return server != null ? server.getUrl() : "";
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
tickCounter++;
|
||||
|
||||
updateRegenTickers();
|
||||
recalculatePath();
|
||||
collectAndSendTelemetry();
|
||||
}
|
||||
|
||||
private void recalculatePath()
|
||||
{
|
||||
if (gpsTarget == null || client.getGameState() != GameState.LOGGED_IN || client.getLocalPlayer() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPoint playerPos = client.getLocalPlayer().getWorldLocation();
|
||||
if (playerPos == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (playerPos.equals(gpsTarget))
|
||||
{
|
||||
setGpsTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Dynamically recompute whenever the player moves or target changes
|
||||
if (!playerPos.equals(lastCalculatedPlayerPos) || !gpsTarget.equals(lastCalculatedTargetPos))
|
||||
{
|
||||
lastCalculatedPlayerPos = playerPos;
|
||||
lastCalculatedTargetPos = gpsTarget;
|
||||
gpsPath = Pathfinder.findPath(client, playerPos, gpsTarget);
|
||||
nearbyShortcuts = Pathfinder.findNearbyShortcuts(client, gpsPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRegenTickers()
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int currentHp = client.getBoostedSkillLevel(Skill.HITPOINTS);
|
||||
boolean rapidHeal = client.isPrayerActive(net.runelite.api.Prayer.RAPID_HEAL);
|
||||
int hpMaxPeriod = rapidHeal ? 50 : 100;
|
||||
|
||||
if (lastHp != -1 && currentHp != lastHp)
|
||||
{
|
||||
hpRegenTicksLeft = hpMaxPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
hpRegenTicksLeft--;
|
||||
if (hpRegenTicksLeft <= 0)
|
||||
{
|
||||
hpRegenTicksLeft = hpMaxPeriod;
|
||||
}
|
||||
}
|
||||
lastHp = currentHp;
|
||||
|
||||
int currentEnergy = client.getEnergy() / 100;
|
||||
if (currentEnergy >= 100)
|
||||
{
|
||||
energyRegenTicksLeft = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastEnergy != -1 && currentEnergy > lastEnergy)
|
||||
{
|
||||
int agility = client.getRealSkillLevel(Skill.AGILITY);
|
||||
energyRegenTicksLeft = Math.max(2, (int) Math.round((100.0 - (agility * 0.6)) / 10.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (energyRegenTicksLeft > 0)
|
||||
{
|
||||
energyRegenTicksLeft--;
|
||||
}
|
||||
else
|
||||
{
|
||||
int agility = client.getRealSkillLevel(Skill.AGILITY);
|
||||
energyRegenTicksLeft = Math.max(2, (int) Math.round((100.0 - (agility * 0.6)) / 10.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
lastEnergy = currentEnergy;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemContainerChanged(ItemContainerChanged event)
|
||||
{
|
||||
int containerId = event.getContainerId();
|
||||
if (containerId == InventoryID.INVENTORY.getId())
|
||||
{
|
||||
cachedInventory = serializeContainer(event.getItemContainer(), false);
|
||||
rebuildItemSummary();
|
||||
}
|
||||
else if (containerId == InventoryID.EQUIPMENT.getId())
|
||||
{
|
||||
cachedEquipment = serializeEquipmentContainer(event.getItemContainer());
|
||||
rebuildItemSummary();
|
||||
}
|
||||
else if (containerId == InventoryID.BANK.getId())
|
||||
{
|
||||
cachedBank = serializeContainer(event.getItemContainer(), true);
|
||||
rebuildItemSummary();
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildItemSummary()
|
||||
{
|
||||
Map<Integer, Map<String, Integer>> map = new HashMap<>();
|
||||
|
||||
for (Map<String, Object> item : cachedInventory)
|
||||
{
|
||||
if (item == null) continue;
|
||||
Object idObj = item.get("id");
|
||||
Object qtyObj = item.get("qty");
|
||||
if (idObj == null) continue;
|
||||
int id = (int) idObj;
|
||||
int qty = qtyObj instanceof Number ? ((Number) qtyObj).intValue() : 1;
|
||||
Map<String, Integer> counts = map.computeIfAbsent(id, k -> new HashMap<>());
|
||||
counts.put("inv", counts.getOrDefault("inv", 0) + qty);
|
||||
}
|
||||
|
||||
for (Map<String, Object> item : cachedEquipment)
|
||||
{
|
||||
if (item == null) continue;
|
||||
Object idObj = item.get("id");
|
||||
Object qtyObj = item.get("qty");
|
||||
if (idObj == null) continue;
|
||||
int id = (int) idObj;
|
||||
int qty = qtyObj instanceof Number ? ((Number) qtyObj).intValue() : 1;
|
||||
Map<String, Integer> counts = map.computeIfAbsent(id, k -> new HashMap<>());
|
||||
counts.put("equip", counts.getOrDefault("equip", 0) + qty);
|
||||
}
|
||||
|
||||
for (Map<String, Object> item : cachedBank)
|
||||
{
|
||||
if (item == null) continue;
|
||||
Object idObj = item.get("id");
|
||||
Object qtyObj = item.get("qty");
|
||||
if (idObj == null) continue;
|
||||
int id = (int) idObj;
|
||||
int qty = qtyObj instanceof Number ? ((Number) qtyObj).intValue() : 1;
|
||||
Map<String, Integer> counts = map.computeIfAbsent(id, k -> new HashMap<>());
|
||||
counts.put("bank", counts.getOrDefault("bank", 0) + qty);
|
||||
}
|
||||
|
||||
cachedItemSummary = map;
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> serializeContainer(ItemContainer container, boolean isBank)
|
||||
{
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
if (container == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
Item[] items = container.getItems();
|
||||
for (int i = 0; i < items.length; i++)
|
||||
{
|
||||
Item item = items[i];
|
||||
if (item == null || item.getId() <= 0)
|
||||
{
|
||||
if (!isBank)
|
||||
{
|
||||
Map<String, Object> emptyMap = new LinkedHashMap<>();
|
||||
emptyMap.put("slot", i);
|
||||
emptyMap.put("id", 0);
|
||||
emptyMap.put("qty", 0);
|
||||
list.add(emptyMap);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, Object> itemMap = new LinkedHashMap<>();
|
||||
itemMap.put("slot", i);
|
||||
itemMap.put("id", item.getId());
|
||||
itemMap.put("qty", item.getQuantity());
|
||||
|
||||
ItemComposition comp = itemManager.getItemComposition(item.getId());
|
||||
if (comp != null)
|
||||
{
|
||||
itemMap.put("name", comp.getName());
|
||||
itemMap.put("members", comp.isMembers());
|
||||
itemMap.put("haPrice", comp.getHaPrice());
|
||||
}
|
||||
else
|
||||
{
|
||||
itemMap.put("name", "Item #" + item.getId());
|
||||
}
|
||||
|
||||
int gePrice = itemManager.getItemPrice(item.getId());
|
||||
itemMap.put("price", gePrice);
|
||||
|
||||
list.add(itemMap);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> serializeEquipmentContainer(ItemContainer container)
|
||||
{
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
if (container == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
EquipmentInventorySlot[] slots = {
|
||||
EquipmentInventorySlot.HEAD,
|
||||
EquipmentInventorySlot.CAPE,
|
||||
EquipmentInventorySlot.AMULET,
|
||||
EquipmentInventorySlot.AMMO,
|
||||
EquipmentInventorySlot.WEAPON,
|
||||
EquipmentInventorySlot.BODY,
|
||||
EquipmentInventorySlot.SHIELD,
|
||||
EquipmentInventorySlot.LEGS,
|
||||
EquipmentInventorySlot.GLOVES,
|
||||
EquipmentInventorySlot.BOOTS,
|
||||
EquipmentInventorySlot.RING
|
||||
};
|
||||
|
||||
for (EquipmentInventorySlot slot : slots)
|
||||
{
|
||||
int slotIdx = slot.getSlotIdx();
|
||||
Item item = container.getItem(slotIdx);
|
||||
Map<String, Object> slotMap = new LinkedHashMap<>();
|
||||
slotMap.put("slotName", slot.name());
|
||||
slotMap.put("slotIdx", slotIdx);
|
||||
|
||||
if (item != null && item.getId() > 0)
|
||||
{
|
||||
slotMap.put("id", item.getId());
|
||||
slotMap.put("qty", item.getQuantity());
|
||||
ItemComposition comp = itemManager.getItemComposition(item.getId());
|
||||
if (comp != null)
|
||||
{
|
||||
slotMap.put("name", comp.getName());
|
||||
slotMap.put("members", comp.isMembers());
|
||||
slotMap.put("haPrice", comp.getHaPrice());
|
||||
}
|
||||
else
|
||||
{
|
||||
slotMap.put("name", "Item #" + item.getId());
|
||||
}
|
||||
slotMap.put("price", itemManager.getItemPrice(item.getId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
slotMap.put("id", 0);
|
||||
}
|
||||
|
||||
list.add(slotMap);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
cachedInventory.clear();
|
||||
cachedEquipment.clear();
|
||||
cachedBank.clear();
|
||||
cachedItemSummary.clear();
|
||||
setGpsTarget(null);
|
||||
}
|
||||
collectAndSendTelemetry();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!LiveDashboardConfig.GROUP.equals(event.getGroup()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ("port".equals(event.getKey()))
|
||||
{
|
||||
if (server != null && server.isRunning())
|
||||
{
|
||||
startServer(config.port());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void collectAndSendTelemetry()
|
||||
{
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
GameState gs = client.getGameState();
|
||||
data.put("gameState", gs != null ? gs.name() : "UNKNOWN");
|
||||
data.put("gameTick", tickCounter);
|
||||
|
||||
if (gs == GameState.LOGGED_IN)
|
||||
{
|
||||
Player player = client.getLocalPlayer();
|
||||
boolean isMoving = false;
|
||||
if (player != null)
|
||||
{
|
||||
data.put("player", player.getName());
|
||||
WorldPoint wp = player.getWorldLocation();
|
||||
if (wp != null)
|
||||
{
|
||||
data.put("worldX", wp.getX());
|
||||
data.put("worldY", wp.getY());
|
||||
data.put("plane", wp.getPlane());
|
||||
data.put("regionId", wp.getRegionID());
|
||||
data.put("regionX", wp.getRegionX());
|
||||
data.put("regionY", wp.getRegionY());
|
||||
|
||||
if (lastWorldPoint != null && !lastWorldPoint.equals(wp))
|
||||
{
|
||||
isMoving = true;
|
||||
}
|
||||
lastWorldPoint = wp;
|
||||
}
|
||||
|
||||
LocalPoint lp = player.getLocalLocation();
|
||||
if (lp != null)
|
||||
{
|
||||
data.put("sceneX", lp.getSceneX());
|
||||
data.put("sceneY", lp.getSceneY());
|
||||
}
|
||||
|
||||
data.put("orientation", player.getOrientation());
|
||||
data.put("animation", player.getAnimation());
|
||||
data.put("poseAnimation", player.getPoseAnimation());
|
||||
if (player.getPoseAnimation() != player.getIdlePoseAnimation())
|
||||
{
|
||||
isMoving = true;
|
||||
}
|
||||
}
|
||||
data.put("isMoving", isMoving);
|
||||
|
||||
data.put("world", client.getWorld());
|
||||
data.put("cameraYaw", client.getCameraYaw());
|
||||
data.put("cameraPitch", client.getCameraPitch());
|
||||
data.put("weight", client.getWeight());
|
||||
|
||||
// Vitals
|
||||
int hp = client.getBoostedSkillLevel(Skill.HITPOINTS);
|
||||
int maxHp = client.getRealSkillLevel(Skill.HITPOINTS);
|
||||
data.put("hp", hp);
|
||||
data.put("maxHp", maxHp);
|
||||
data.put("hpRegenSeconds", (int) Math.ceil(hpRegenTicksLeft * 0.6));
|
||||
data.put("hpRegenTicks", hpRegenTicksLeft);
|
||||
|
||||
data.put("prayer", client.getBoostedSkillLevel(Skill.PRAYER));
|
||||
data.put("maxPrayer", client.getRealSkillLevel(Skill.PRAYER));
|
||||
|
||||
int energy = client.getEnergy() / 100;
|
||||
data.put("energy", energy);
|
||||
data.put("energyRegenSeconds", energy >= 100 ? 0 : (int) Math.ceil(energyRegenTicksLeft * 0.6));
|
||||
data.put("energyRegenTicks", energy >= 100 ? 0 : energyRegenTicksLeft);
|
||||
|
||||
int agility = client.getRealSkillLevel(Skill.AGILITY);
|
||||
data.put("agilityLevel", agility);
|
||||
|
||||
// Containers
|
||||
if (cachedInventory.isEmpty())
|
||||
{
|
||||
ItemContainer inv = client.getItemContainer(InventoryID.INVENTORY);
|
||||
if (inv != null)
|
||||
{
|
||||
cachedInventory = serializeContainer(inv, false);
|
||||
}
|
||||
}
|
||||
if (cachedEquipment.isEmpty())
|
||||
{
|
||||
ItemContainer equip = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||
if (equip != null)
|
||||
{
|
||||
cachedEquipment = serializeEquipmentContainer(equip);
|
||||
}
|
||||
}
|
||||
if (cachedBank.isEmpty())
|
||||
{
|
||||
ItemContainer bank = client.getItemContainer(InventoryID.BANK);
|
||||
if (bank != null)
|
||||
{
|
||||
cachedBank = serializeContainer(bank, true);
|
||||
}
|
||||
}
|
||||
if (cachedItemSummary.isEmpty() && (!cachedInventory.isEmpty() || !cachedEquipment.isEmpty() || !cachedBank.isEmpty()))
|
||||
{
|
||||
rebuildItemSummary();
|
||||
}
|
||||
|
||||
long invCount = cachedInventory.stream().filter(m -> ((Number) m.getOrDefault("id", 0)).intValue() > 0).count();
|
||||
data.put("inventory", cachedInventory);
|
||||
data.put("invCount", invCount);
|
||||
|
||||
long equipCount = cachedEquipment.stream().filter(m -> ((Number) m.getOrDefault("id", 0)).intValue() > 0).count();
|
||||
data.put("equipment", cachedEquipment);
|
||||
data.put("equipCount", equipCount);
|
||||
|
||||
data.put("bank", cachedBank);
|
||||
data.put("bankCount", cachedBank.size());
|
||||
data.put("itemSummary", cachedItemSummary);
|
||||
|
||||
// Active GPS target & obstacle-free path & ETA estimation
|
||||
if (gpsTarget != null)
|
||||
{
|
||||
Map<String, Object> gpsMap = new LinkedHashMap<>();
|
||||
gpsMap.put("x", gpsTarget.getX());
|
||||
gpsMap.put("y", gpsTarget.getY());
|
||||
gpsMap.put("plane", gpsTarget.getPlane());
|
||||
|
||||
List<Map<String, Integer>> pathList = new ArrayList<>();
|
||||
if (gpsPath != null)
|
||||
{
|
||||
for (WorldPoint p : gpsPath)
|
||||
{
|
||||
Map<String, Integer> pMap = new LinkedHashMap<>();
|
||||
pMap.put("x", p.getX());
|
||||
pMap.put("y", p.getY());
|
||||
pathList.add(pMap);
|
||||
}
|
||||
}
|
||||
gpsMap.put("path", pathList);
|
||||
|
||||
int totalTiles = (gpsPath != null && !gpsPath.isEmpty())
|
||||
? gpsPath.size()
|
||||
: (player != null && player.getWorldLocation() != null ? player.getWorldLocation().distanceTo(gpsTarget) : 0);
|
||||
gpsMap.put("totalTiles", totalTiles);
|
||||
|
||||
// Running = 2 tiles/tick (1.2s per 2 tiles = 0.6s per tile average)
|
||||
// Walking = 1 tile/tick (0.6s per tile)
|
||||
int runSeconds = (int) Math.ceil((totalTiles / 2.0) * 0.6);
|
||||
int walkSeconds = (int) Math.ceil(totalTiles * 0.6);
|
||||
gpsMap.put("runEtaSeconds", runSeconds);
|
||||
gpsMap.put("walkEtaSeconds", walkSeconds);
|
||||
|
||||
// Nearby Agility Shortcuts along route
|
||||
List<Map<String, Object>> scList = new ArrayList<>();
|
||||
if (nearbyShortcuts != null)
|
||||
{
|
||||
for (ShortcutData sc : nearbyShortcuts)
|
||||
{
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("name", sc.getName());
|
||||
m.put("level", sc.getRequiredLevel());
|
||||
m.put("desc", sc.getDescription());
|
||||
m.put("canUse", agility >= sc.getRequiredLevel());
|
||||
scList.add(m);
|
||||
}
|
||||
}
|
||||
gpsMap.put("shortcuts", scList);
|
||||
|
||||
data.put("gpsTarget", gpsMap);
|
||||
}
|
||||
}
|
||||
|
||||
if (server != null)
|
||||
{
|
||||
server.updateTelemetry(data);
|
||||
}
|
||||
if (panel != null)
|
||||
{
|
||||
panel.updateTelemetry(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user