LoudPacks Posted January 26, 2016 Share Posted January 26, 2016 (edited) Don't know if anyone will use but I needed something with this functionality and came up with this. Any feedback is appreciated, I'm always trying to learn new things. GroundMonitor.java: import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.osbot.rs07.api.model.GroundItem; import org.osbot.rs07.script.Script; public abstract class GroundMonitor { //My implementation filters out items less than price x, but I removed because it was specific to my needs private ArrayList<GroundItem> cache = new ArrayList<GroundItem>(); private Script ctx; public GroundMonitorRelease(Script ctx, int valueThreshold) { 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() { for (GroundItem item : ctx.getGroundItems().getAll()) { if (item != null) { cache.add(item); } } } public GroundItem[] getChanges() { List<GroundItem> items = new ArrayList<GroundItem>(); ArrayList<GroundItem> ci = new ArrayList<GroundItem>(); int changes = 0; for(GroundItem q : ctx.getGroundItems().getAll()){ if(q != null){ items.add(q); } } for (GroundItem item : items) { if (item != null) { int id = item.getId(); if (!contains(ci, id) && !cached(item)) { ci.add(item); changes++; } } } Collections.sort(ci, new Comparator<GroundItem>(){ @Override public int compare(GroundItem o1, GroundItem o2) { int d0 = CheckPrice.get(o1.getId()); //Use distance instead of price int d1 = CheckPrice.get(o2.getId()); //Use distance instead of price return (d0 < d1 ? -1 : //It will return the closer one first (d0 == d1 ? 0 : 1)); } }); return Arrays.copyOf(ci.toArray(new GroundItem[ci.size()]), changes); } private boolean cached(GroundItem item){ return cache.contains(item); } private boolean contains(ArrayList<GroundItem> list, int id) { for (GroundItem i : list) { if (i == null) continue; if (i.getId() == id) { return true; } } return false; } } Main.java (onStart): groundMonitor = new GroundMonitor(getScript()) { @Override public void onChange() { for (GroundItem i : getChanges()) { if(i != null){ log(i.getName() + " : " + CheckPrice.get(i.getId())); } } } }; Main.java (onPaint): if (groundMonitor != null && groundMonitor.hasChanged()) { groundMonitor.onChange(); groundMonitor.update(); } Edited January 26, 2016 by LoudPacks 4 Quote Link to comment Share on other sites More sharing options...
Token Posted January 26, 2016 Share Posted January 26, 2016 (edited) Looks good, you might want to consider using a proper thread instead of the paint thread though. As far as I know the paint thread is executed like 60 times a second, so that's literally every ~16 ms which is not really necessary. If you want to go with the optimisations to the maximum then you can detect the changes every tick instead since we have the possibilities to do so with the current API which would be about 40 times more efficient CPU wise. Edited January 26, 2016 by Token 1 Quote Link to comment Share on other sites More sharing options...
Vilius Posted January 26, 2016 Share Posted January 26, 2016 (edited) Dank EDT errors u have there Edited January 26, 2016 by Vilius Quote Link to comment Share on other sites More sharing options...
LoudPacks Posted January 26, 2016 Author Share Posted January 26, 2016 (edited) Dank EDT errors u have there what Looks good, you might want to consider using a proper thread instead of the paint thread though. As far as I know the paint thread is executed like 60 times a second, so that's literally every ~16 ms which is not really necessary. If you want to go with the optimisations to the maximum then you can detect the changes every tick instead since we have the possibilities to do so with the current API which would be about 40 times more efficient CPU wise. Will something like this suffice? monitorThread = new Thread(){ public void run() { inventoryMonitor = new InventoryMonitor(getScript()) { @Override public void onChange() { for (Item i : getChanges()) { if(i != null){ lootCount += i.getAmount(); lootValue += CheckPrice.get(i.getId()); } } } }; groundMonitor = new GroundMonitor(getScript(), Settings.lootThresh, Settings.zoneArea) { @Override public void onChange() { for (org.osbot.rs07.api.model.GroundItem i : getChanges()) { if(i != null){ log(i.getName() + " : " + CheckPrice.get(i.getId())); } } } }; while(!monitorThread.isInterrupted()){ if (inventoryMonitor != null && !getBank().isOpen() && inventoryMonitor.hasChanged()) { inventoryMonitor.onChange(); inventoryMonitor.update(); } if (groundMonitor != null && !getBank().isOpen() && groundMonitor.hasChanged()) { groundMonitor.onChange(); groundMonitor.update(); } } } }; monitorThread.start(); Edited January 26, 2016 by LoudPacks Quote Link to comment Share on other sites More sharing options...
Token Posted January 26, 2016 Share Posted January 26, 2016 what Will something like this suffice? monitorThread = new Thread(){ public void run() { inventoryMonitor = new InventoryMonitor(getScript()) { @Override public void onChange() { for (Item i : getChanges()) { if(i != null){ lootCount += i.getAmount(); lootValue += CheckPrice.get(i.getId()); } } } }; groundMonitor = new GroundMonitor(getScript(), Settings.lootThresh, Settings.zoneArea) { @Override public void onChange() { for (org.osbot.rs07.api.model.GroundItem i : getChanges()) { if(i != null){ log(i.getName() + " : " + CheckPrice.get(i.getId())); } } } }; while(!monitorThread.isInterrupted()){ if (inventoryMonitor != null && !getBank().isOpen() && inventoryMonitor.hasChanged()) { inventoryMonitor.onChange(); inventoryMonitor.update(); } if (groundMonitor != null && !getBank().isOpen() && groundMonitor.hasChanged()) { groundMonitor.onChange(); groundMonitor.update(); } } } }; monitorThread.start(); That should freeze your client because it has no sleeps so the new thread will attempt to use the whole CPU execution cap. Quote Link to comment Share on other sites More sharing options...