LoudPacks Posted June 12, 2016 Share Posted June 12, 2016 (edited) Integrating HLJ With OSBot General Requirements: Registered HLJ Account: http://heylookjagex.xyz/index.php Your HLJ token A Registered Script With Valid Script ID *A Bot-Token and Bot-ID If Tracking Specific Bot Instances (Optional) IDE With OSBot Script HeyLookJagex Thread: http://osbot.org/forum/topic/100322-botwatch-an-osbot-exclusive/ Class File Requirements: HJLServer Class: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import org.osbot.rs07.api.model.Item; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; public class HLJServer { private final Script script; private final String token; private final int scriptID; private String botToken; private int botID; private final List<Skill> monitorSkills = new LinkedList<Skill>(); private final List<Integer> monitorSkillLinked = new LinkedList<Integer>(); private final List<Integer> monitorLoot = new LinkedList<Integer>(); private final HashMap<Skill, Integer> startSkillXP = new HashMap<Skill, Integer>(); private final HashMap<Skill, Integer> storedSkillData = new HashMap<Skill, Integer>(); private final HashMap<Integer, Integer> storedSkillLinked = new HashMap<Integer, Integer>(); private final HashMap<Integer, Integer> storedLoot = new HashMap<Integer, Integer>(); private final List<HLJEntry> listDumpSkillLinked = new LinkedList<HLJEntry>(); private InventoryMonitor inventoryMonitor; private Thread serverThread; private long lastUpdate; private boolean running = true; private final static long UPDATE_INTERVAL = 900000; private static enum RawSkill { ATTACK(1), DEFENCE(2), STRENGTH(3), HITPOINTS(4), RANGE(5), PRAYER(6), MAGIC(7), COOKING(8), WOODCUTTING( 9), FLETCHING(10), FISHING(11), FIREMAKING(12), CRAFTING(13), SMITHING(14), MINING(15), HERBLORE( 16), AGILITY(17), THIEVING(18), SLAYER(19), FARMING(20), RUNECRAFTING(21), HUNTER( 22), CONSTRUCTION(23); private final int id; RawSkill(int id) { this.id = id; } private int getID(){ return id; } } private int OSBotToHLJ(org.osbot.rs07.api.ui.Skill osbSkill){ return RawSkill.valueOf(osbSkill.name()).getID(); } public HLJServer(Script script, String token, int scriptID) { this.script = script; this.token = token; this.scriptID = scriptID; createSkillLinkedIDList(listDumpSkillLinked); lastUpdate = System.currentTimeMillis(); inventoryMonitor = new InventoryMonitor(script) { @Override public void onChange() { for (Item i : getChanges()) { if (i != null && !script.getBank().isOpen() && !script.getTrade().isCurrentlyTrading()) { int amount = Math.abs(i.getAmount()); int rsID = i.getId(); int skillLinkedID = getRawIDSkillLinkedGet(rsID); if (monitorSkillLinked.contains(skillLinkedID)) { storedSkillLinked.put(skillLinkedID, amount); } if (monitorLoot.contains(rsID) && i.getAmount() > 0) { storedLoot.put(rsID, amount); } } } } }; serverThread = new Thread(() -> { while (running && !serverThread.isInterrupted()) { inventoryMonitor.onChange(); for (Skill skill : monitorSkills) { if (script.getSkills().getExperience(skill) > startSkillXP.get(skill)) { storedSkillData.put(skill, script.getSkills().getExperience(skill) - startSkillXP.get(skill)); } } if (System.currentTimeMillis() - lastUpdate >= UPDATE_INTERVAL) { submit(createUpdateString()); resetCache(); lastUpdate = System.currentTimeMillis(); } try { Thread.sleep(500); } catch (Exception e) { script.log(e.getMessage()); } } }); serverThread.start(); } public HLJServer(Script script, String token, int scriptID, String botToken, int botID) { this.script = script; this.token = token; this.botToken = botToken; this.botID = botID; this.scriptID = scriptID; createSkillLinkedIDList(listDumpSkillLinked); lastUpdate = System.currentTimeMillis(); inventoryMonitor = new InventoryMonitor(script) { @Override public void onChange() { for (Item i : getChanges()) { if (i != null && !script.getBank().isOpen() && !script.getTrade().isCurrentlyTrading()) { int amount = Math.abs(i.getAmount()); int rsID = i.getId(); int skillLinkedID = getRawIDSkillLinkedGet(rsID); if (monitorSkillLinked.contains(skillLinkedID)) { storedSkillLinked.put(skillLinkedID, amount); } if (monitorLoot.contains(rsID)) { storedLoot.put(rsID, amount); } } } } }; serverThread = new Thread(() -> { while (running && !serverThread.isInterrupted()) { inventoryMonitor.onChange(); for (Skill skill : monitorSkills) { if (script.getSkills().getExperience(skill) > startSkillXP.get(skill)) { storedSkillData.put(skill, script.getSkills().getExperience(skill) - startSkillXP.get(skill)); } } if (System.currentTimeMillis() - lastUpdate >= UPDATE_INTERVAL) { submit(createUpdateString()); resetCache(); lastUpdate = System.currentTimeMillis(); } try { Thread.sleep(500); } catch (Exception e) { script.log(e.getMessage()); } } }); serverThread.start(); } public void logAll() { for (Skill skill : monitorSkills) { script.log(String.format("SKILL: %s : %d", skill.name(), storedSkillData.get(skill))); } for (int rawID : monitorSkillLinked) { script.log(String.format("LINKED ITEM: %d : %d", rawID, storedSkillLinked.get(rawID))); } for (int rsID : monitorLoot) { script.log(String.format("LOOT ITEM: %d : %d", rsID, storedLoot.get(rsID))); } script.log(createUpdateString()); } private int getRawIDSkillLinked(int id, int rsID) { for (HLJEntry item : listDumpSkillLinked) { if (item.getSkillID() == id && item.getRsID() == rsID) { return item.getRawID(); } } return -1; } private int getRawIDSkillLinkedGet(int rsID) { for (HLJEntry item : listDumpSkillLinked) { if (item.getRsID() == rsID) { return item.getRawID(); } } return -1; } private void resetCache() { for (int rawID : monitorSkillLinked) { storedSkillLinked.put(rawID, 0); } for (int rsID : monitorLoot) { storedLoot.put(rsID, 0); } for (Skill skill : monitorSkills) { storedSkillData.put(skill, 0); startSkillXP.put(skill, script.getSkills().getExperience(skill)); } } private void updateSkill(Skill skill, int exp) { storedSkillData.put(skill, exp); } private void updateLootItem(int rsID, int amount) { storedLoot.put(rsID, amount); } private void updateSkillLinkedItem(Skill skill, int rsID, int amount) { storedSkillLinked.put(getRawIDSkillLinked(skill.getId(), rsID), amount); } public void addSkill(Skill skill) { monitorSkills.add(skill); startSkillXP.put(skill, script.getSkills().getExperience(skill)); storedSkillData.put(skill, 0); } public void addItem(int rsID) { monitorLoot.add(rsID); storedLoot.put(rsID, 0); } public void addSkillLinkedItem(Skill skill, int rsID) { monitorSkillLinked.add(getRawIDSkillLinked(OSBotToHLJ(skill), rsID)); storedSkillLinked.put(getRawIDSkillLinked(OSBotToHLJ(skill), rsID), 0); } private void createSkillLinkedIDList(List<HLJEntry> output) { try { URL heyLookURL; heyLookURL = new URL("http://heylookjagex.xyz/api/items.php"); BufferedReader in = new BufferedReader(new InputStreamReader(heyLookURL.openStream())); String inputLine; while ((inputLine = in.readLine()) != null) { String[] entries = inputLine.replace("<br>", "\n").split("\n"); for (String line : entries) { String[] tags = line.split(":"); for (int i = 0; i < tags.length - 3; i += 3) { int rawID = Integer.parseInt(tags[i]); String name = tags[i + 1]; int rsID = Integer.parseInt(tags[i + 2]); int skillID = Integer.parseInt(tags[i + 3]); output.add(new HLJEntry(rawID, name, rsID, skillID)); } } } in.close(); script.log("Grabbing item list from server!"); } catch (IOException e) { script.log(e.getMessage()); } } private String createUpdateString() { String request = "http://heylookjagex.xyz/api/dev.php?auth=" + scriptID + "," + token; String botTrack = "&user=" + botID + "," + botToken; String xpEntry = "&xp="; String itemEntry = "&items="; String lootEntry = "&loot="; String entry = "%d,%d"; String subEntry = ":%d,%d"; if(botToken != null){ request += botTrack; } for (Skill skill : monitorSkills) { if (!request.contains(xpEntry)) { request += xpEntry; request += String.format(entry, OSBotToHLJ(skill), storedSkillData.get(skill)); } else { request += String.format(subEntry, OSBotToHLJ(skill), storedSkillData.get(skill)); } } for (int rawID : monitorSkillLinked) { if (!request.contains(itemEntry)) { request += itemEntry; request += String.format(entry, rawID, storedSkillLinked.get(rawID)); } else { request += String.format(subEntry, rawID, storedSkillLinked.get(rawID)); } } for (int rsID : monitorLoot) { if (!request.contains(lootEntry)) { request += lootEntry; request += String.format(entry, rsID, storedLoot.get(rsID)); } else { request += String.format(subEntry, rsID, storedLoot.get(rsID)); } } return request; } private boolean submit(String url) { try { URL submit = new URL(url); URLConnection con = submit.openConnection(); script.log("Submitting data to HLJ!"); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); final BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream())); rd.close(); return true; } catch (Exception e) { script.log("Failed to submit data to HLJ!"); script.log(e.getMessage()); } return false; } public void exit() { try { running = false; serverThread.join(); } catch (InterruptedException e) { script.log(e.getMessage()); } } } HJLEntry Class: package com.loudpacks.script.util; public class HLJEntry { private int rawID; private int rsID; private int skillID; private String name; public HLJEntry(int rawID, String name, int rsID, int skillID){ this.rawID = rawID; this.name = name; this.rsID = rsID; this.skillID = skillID; } public String getName(){ return name; } public int getRawID(){ return rawID; } public int getRsID(){ return rsID; } public int getSkillID(){ return skillID; } public String getSummary(){ return String.format("Name: %s RawID: %d RsID: %d SkillID: %d", getName(), getRawID(), getRsID(), getSkillID()); } } InventoryMonitor Class: package script; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.osbot.rs07.api.model.Item; import org.osbot.rs07.script.Script; public abstract class InventoryMonitor { private Item[] cache = new Item[0]; private Script ctx; public InventoryMonitor(Script ctx) { updateContext(ctx); update(); } public void updateContext(Script ctx){ this.ctx = ctx; } public abstract void onChange(); public boolean hasChanged() { return getChanges().length > 0; } public void update() { cache = new Item[(int)ctx.getInventory().getItems().length]; int i = 0; for (Item item : ctx.getInventory().getItems()) { if(item != null){ cache[i++] = item; } } } @SuppressWarnings("deprecation") public Item[] getChanges() { int count = (int)ctx.getInventory().getItems().length; List<Item> items = new ArrayList<>(count); Item[] ci = new Item[count]; int changes = 0; Collections.addAll(items, ctx.getInventory().getItems()); for (Item item : items) { if(item != null){ int id = item.getId(); int c1 = (int)ctx.getInventory().getAmount(id), c2 = cached(id); if (c1 != c2 && !contains(ci, id)) { ci[changes++] = new Item(id, c1 - c2); } } } return Arrays.copyOf(ci, changes); } private boolean contains(Item[] list, int id) { for (Item i : list) { if (i == null) continue; if (i.getId() == id) { return true; } } return false; } private int cached(int id) { int count = 0; for (Item i : cache) { if (i != null && i.getId() == id) { count += i.getAmount(); } } return count; } } Installation: 1. Create the above classes in your project with the code displayed above. 2. In your Main.java create a new HLJServer object with the parameters. Make sure you place this in Main.java, onStart() or wherever your script starts, this should NOT loop. HLJ has two constructors: one takes a Script, Token, ScriptID, another takes Script, TokenID, BotToken, and BotID. The first constructor is to be used if you're tracking stats for ALL bots running your script. The second constructor is to be used if you're only tracking stats for that specific bot instance. In order to use HLJ with your scripts, you must have a registered account as well as a registered script with a valid script id. 3. Add your desired items and skills that you would like to track below your instantiated HLJ object. In this case I add woodcutting, bones, and oak logs; note that the item IDs are used. Skill linked items must be added with their corresponding skills as seen with oak logs. 4. HLJ runs on a separate thread so you must call exit() in Main.java on your HLJ object when your script exits. Documentation: Edited July 1, 2016 by LoudPacks 2 Quote Link to comment Share on other sites More sharing options...
Xylate Posted June 12, 2016 Share Posted June 12, 2016 I hope to see SDN scripts adding this. Quote Link to comment Share on other sites More sharing options...
iroll Posted June 12, 2016 Share Posted June 12, 2016 Congrats looks well put:) 1 Quote Link to comment Share on other sites More sharing options...
Xylate Posted June 12, 2016 Share Posted June 12, 2016 Congrats looks well put:) If you have any suggestions or want new tracking features, let us know! Quote Link to comment Share on other sites More sharing options...
Botre Posted June 12, 2016 Share Posted June 12, 2016 So you ended up using PHP... ew 3 Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted June 13, 2016 Share Posted June 13, 2016 Will give this a go ^^ 4 Quote Link to comment Share on other sites More sharing options...
Xylate Posted June 26, 2016 Share Posted June 26, 2016 bump kek. Quote Link to comment Share on other sites More sharing options...
Wizard Posted June 26, 2016 Share Posted June 26, 2016 Seems to me like a promising project!! good luck and I hope to see something like this implemented into scripts Quote Link to comment Share on other sites More sharing options...