styxa Posted February 4, 2019 Share Posted February 4, 2019 (edited) This script gets the display names of all nearby players periodically and saves them to a local text file. Nearby players are scanned every 5 seconds and duplicate names are skipped. The script hops to a random world every 25-35 seconds. The created name list text file is located in OSBot data folder: C:\Users\USERNAME\OSBot\Data\NameHarvester_names.txt Download: NameHarvester.jar v1.01 Put the jar file to C:\Users\USERNAME\OSBot\Scripts and the script should appear on your script list in the client. Screenshot: Script source: Spoiler import java.awt.Color; import java.awt.Graphics2D; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.HashSet; import java.util.List; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.api.model.Player; @ScriptManifest(author = "styxa", name = "NameHarvester", version = 1.01, info = "Collect nearby display names, save to local text file, idle.", logo = "https://i.imgur.com/hy1WyE8.png") public class NameHarvester extends Script { private String scriptName; private String scriptAuthor; private String scriptStatus; private double scriptVersion; private long startTime; private long scanTimer; private int scanInterval; private long hopTimer; private int hopInterval; private int timesHopped; private int savedNameCount; public int namesInFile; private HashSet<String> dupeList; private String myFileName; private String myFileStr; private String fileSize; private File myFile; private boolean playerIsMember; public void onStart() { scriptName = getName(); scriptAuthor = getAuthor(); scriptVersion = getVersion(); log("Welcome to " + scriptName + " v" + scriptVersion + "! Script author: " + scriptAuthor); startTime = System.currentTimeMillis(); scanTimer = System.currentTimeMillis(); hopTimer = System.currentTimeMillis(); timesHopped = 0; hopInterval = random(25000, 35000); //25-35 sec scanInterval = 5000; dupeList = new HashSet<String>(); savedNameCount = 0; namesInFile = 0; myFileName = "NameHarvester_names.txt"; myFileStr = getDirectoryData() + File.separator + myFileName; myFile = new File(myFileStr); if (!myFile.isFile()) { //if the text file doesn't exist, create it try { myFile.createNewFile(); } catch (IOException ioex) { ioex.printStackTrace(); } } //read username file line by line, add names to dupeList, increment namesInFile variable try (BufferedReader br = new BufferedReader(new FileReader(myFile))) { String line; while ((line = br.readLine()) != null) { if (!checkForDupe(line)) dupeList.add(line); namesInFile++; } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } playerIsMember = getWorlds().isMembersWorld() ? true : false; scanPlayers(); } public void pause() { scriptStatus = "paused"; } public enum State { SCAN_PLAYERS, HOP_WORLDS, WAIT }; private State getState() { if (System.currentTimeMillis() - scanTimer >= scanInterval) return State.SCAN_PLAYERS; if (System.currentTimeMillis() - hopTimer >= hopInterval) return State.HOP_WORLDS; return State.WAIT; } public int onLoop() throws InterruptedException { switch (getState()) { case WAIT: scriptStatus = "waiting"; sleep(random(500, 700)); break; case SCAN_PLAYERS: scriptStatus = "scanning players"; scanTimer = System.currentTimeMillis(); scanPlayers(); break; case HOP_WORLDS: scriptStatus = "hopping worlds"; hopTimer = System.currentTimeMillis(); hopInterval = random(25000, 35000); hopWorlds(); timesHopped++; break; } return random(400, 600); } public final String formatTime(final long ms, final boolean hour) { long s = ms / 1000, m = s / 60, h = m / 60; s %= 60; m %= 60; h %= 24; if (hour == true) return String.format("%02d:%02d:%02d", h, m, s); else return String.format("%02d:%02d", m, s); } public static String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes + " B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } private synchronized void writeNewName(String myStr) { PrintWriter printWriter = null; try { printWriter = new PrintWriter(new FileOutputStream(myFile, true)); printWriter.write(myStr + "\r\n"); } catch (IOException ioex) { ioex.printStackTrace(); } finally { if (printWriter != null) { printWriter.flush(); printWriter.close(); } } } public boolean checkForDupe(String str) { if (dupeList.contains(str)) return true; else return false; } public String cleanName(String name) { return name.replaceAll("<.*?>", "").trim(); //remove <tags> and trim } public void scanPlayers() { List<Player> nearbyPlayers = players.getAll(); nearbyPlayers.remove(myPlayer()); int saved = 0, skipped = 0; for (Player player : nearbyPlayers) { String name = cleanName(player.getName()); if (!checkForDupe(name)) { writeNewName(name); dupeList.add(name); savedNameCount++; namesInFile++; saved++; } else { skipped++; } } fileSize = humanReadableByteCount(myFile.length(), true); log("names saved: [" + saved + "], duplicates skipped: [" + skipped + "] - " + scriptName); } public void hopWorlds() { //visit world 1/2 regularly (the most populated worlds) if ((timesHopped != 0 && timesHopped % 8 == 0) || (timesHopped == 0 && getWorlds().getCurrentWorld() > 302)) { if (playerIsMember == true && random(1, 2) == 1) getWorlds().hop(302); else getWorlds().hop(301); } else { if (playerIsMember == true && random(1, 2) == 1) getWorlds().hopToP2PWorld(); else getWorlds().hopToF2PWorld(); log("hopped worlds (total hopped: [" + timesHopped + "]) - " + scriptName); } } public void onPaint(Graphics2D g) { //background box g.setColor(new Color(0, 0, 0, 200)); g.fillRect(4, 120, 250, 198); g.setFont(g.getFont().deriveFont(14.0f)); //script name g.setColor(Color.decode("#806000")); g.drawString(scriptName + " v" + scriptVersion + " \uD83D\uDC4D\uD83D\uDC4D", 11, 141); g.setColor(Color.decode("#e6ac00")); g.drawString(scriptName + " v" + scriptVersion + " \uD83D\uDC4D\uD83D\uDC4D", 10, 140); //file name g.setColor(Color.decode("#0f3a57")); g.drawString("\ud83d\udcbe file: " + myFileName, 11, 181); g.setColor(Color.decode("#3c9cdd")); g.drawString("\ud83d\udcbe file: " + myFileName, 10, 180); //file size g.setColor(Color.decode("#0f3a57")); g.drawString("\ud83d\udcbe file size: " + fileSize, 11, 201); g.setColor(Color.decode("#3c9cdd")); g.drawString("\ud83d\udcbe file size: " + fileSize, 10, 200); //total names in text file g.setColor(Color.decode("#0f3a57")); g.drawString("\u263b Names in file: " + namesInFile, 11, 221); g.setColor(Color.decode("#0fbd3b")); g.drawString("\u263b Names in file: " + namesInFile, 10, 220); //saved names count g.setColor(Color.decode("#064716")); g.drawString("\uD83D\uDC40 Names saved: " + savedNameCount, 11, 241); g.setColor(Color.decode("#0fbd3b")); g.drawString("\uD83D\uDC40 Names saved: " + savedNameCount, 10, 240); //time ran final long runTime = System.currentTimeMillis() - startTime; g.setColor(Color.decode("#004d00")); g.drawString("\uD83D\uDD52 Time ran: " + formatTime(runTime, true), 11, 261); g.setColor(Color.decode("#0fbd3b")); g.drawString("\uD83D\uDD52 Time ran: " + formatTime(runTime, true), 10, 260); //next hop label g.setColor(Color.decode("#4d0066")); g.drawString("\ud83d\udd03 Next hop:", 11, 281); g.setColor(Color.decode("#bd2bee")); g.drawString("\ud83d\udd03 Next hop:", 10, 280); //next hop countdown //final long timeToHop = (System.currentTimeMillis() - hopInterval - hopTimer) * -1; final long timeToHop = (System.currentTimeMillis() - hopInterval - hopTimer) * -1; g.setColor(Color.decode("#4c2601")); g.drawString(formatTime(timeToHop, false), 101, 281); g.setColor(Color.decode("#d86c02")); g.drawString(formatTime(timeToHop, false), 100, 280); //script status label g.setColor(Color.decode("#4d0066")); g.drawString("\u2615 Status:", 11, 301); g.setColor(Color.decode("#bd2bee")); g.drawString("\u2615 Status:", 10, 300); //dynamic script status g.setColor(Color.decode("#4c2601")); g.drawString(scriptStatus, 101, 301); g.setColor(Color.decode("#d86c02")); g.drawString(scriptStatus, 100, 300); } } Credits: formatTime method by Explv: Explv's Dank Paint Tutorial humanReadableByteCount method by aioobem, copied from Stack Overflow answer: https://stackoverflow.com/a/3758880 changelog: Spoiler v1.01 - 2019-02-06 -added world hopping: -hop in 25-35 second intervals (any faster results is logout) -include p2p worlds if script started on p2p world -hop to world 301/302 first hop if not there already, visit world 301/302 every 8 hops -removed camera movement anti-afk behaviour -modified paint (added "next hop" countdown, tweaked colors) v1.0 - 2019-02-04 -initial release post edit history: edit1 - 2019-02-06 -uploaded v1.01, updated post text accordingly, new screenshot Edited February 6, 2019 by styxa updated script (v1.01) Quote Link to comment Share on other sites More sharing options...
silentra1n Posted February 4, 2019 Share Posted February 4, 2019 What is the purpose of collecting names? Quote Link to comment Share on other sites More sharing options...
Idfix Posted February 4, 2019 Share Posted February 4, 2019 Personally I'd rather see a available name harvester but gz on the release 1 Quote Link to comment Share on other sites More sharing options...
gearing Posted February 4, 2019 Share Posted February 4, 2019 19 minutes ago, silentra1n said: What is the purpose of collecting names? marketing Quote Link to comment Share on other sites More sharing options...
defil3d Posted February 4, 2019 Share Posted February 4, 2019 weird but gl Quote Link to comment Share on other sites More sharing options...
Somebody Posted February 4, 2019 Share Posted February 4, 2019 Would probably be more effective to just hop worlds instead of waiting 5 seconds to scan again. Quote Link to comment Share on other sites More sharing options...
styxa Posted February 4, 2019 Author Share Posted February 4, 2019 1 hour ago, silentra1n said: What is the purpose of collecting names? As @gearing mentioned above, private messaging comes to mind. A spammer script with a custom name list would be an interesting project (and a quite dubious one at that!) One could also want username style random seed for purposes unknown. 41 minutes ago, Somebody said: Would probably be more effective to just hop worlds instead of waiting 5 seconds to scan again. That is an excellent idea! I did think about world hopping feature, I'll try to implement it to the script in the future. 1 hour ago, bankerkrak said: Personally I'd rather see a available name harvester but gz on the release Thanks! 58 minutes ago, defil3d said: weird but gl ty ty Quote Link to comment Share on other sites More sharing options...
JScout Posted August 16, 2020 Share Posted August 16, 2020 Any way to make it not auto hop, and also make it only add players names if wearing x items? Could the accohnt add names to friends list? Maybe add in option to delete Rsn off friends list if player appears offline (private chat off) I would use for for tracking pure clans RSNs so if player is wearing cream hat = add to friends list, then hops to find more . Before you know it you got all the members to FOE added on 1 account and if they do rsn name changes you still are able to track them. Quote Link to comment Share on other sites More sharing options...