Xerion Posted November 24, 2014 Share Posted November 24, 2014 Because Jagex is going to release trading posts in the near future, I decided to dump the source code form my zybez mercher. I used java because I wanted to implement it into a merching script. //Main.java package aiomercher.util.zybez; import aiomercher.util.zybez.stages.Login; import aiomercher.util.zybez.stages.Offer; import aiomercher.util.zybez.utils.ZybezOffer; /** * Created by Xerion on 19-8-2014. */ public class Main { static Login login; public static void main(String args[]) throws Exception{ long time = System.currentTimeMillis(); login = new Login("***","****"); System.out.println("Logged-in in " + (System.currentTimeMillis() - time + 1) + " ms"); //You can add extra stuff here. For example adding an offer. } } Stages//Login.java package aiomercher.util.zybez.stages; import aiomercher.util.zybez.utils.Requests; import aiomercher.util.zybez.utils.Character; import aiomercher.util.zybez.utils.ZybezOffer; import aiomercher.util.zybez.utils.OfferType; import java.net.*; import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by Xerion on 19-8-2014. */ public class Login { public static boolean debug = false; private String username,password; /*Zybez Cookies*/ private String __cfduid,z_session_id,network_cookie,z_rteStatus,z_member_id,z_pass_hash; public Login(String Username, String Password){ try { /*Set Cookie manager*/ CookieManager manager = new CookieManager(); manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); CookieHandler.setDefault(manager); /*Login - Change this to post request for safety*/ Requests.sendGet("http://forums.zybez.net/index.php?app=curseauth&module=global§ion=login&do=process?auth_key=" + getAuth() + "&rememberMe=1&ips_username=" + URLEncoder.encode(Username, "UTF-8") + "&ips_password=" + URLEncoder.encode(Password, "UTF-8") + "&submit=Login"); //Requests.sendPost("http://forums.zybez.net/index.php?app=curseauth&module=global§ion=login&do=process","auth_key=" + getAuth() +"&rememberMe=1&ips_username=" + URLEncoder.encode(username, "UTF-8") + "&ips_password=" + URLEncoder.encode(password, "UTF-8") + "&submit=Login"); /*Fake this cookie*/ this.z_rteStatus = "rte"; /*Set all the variables*/ CookieStore cookieJar = manager.getCookieStore(); List<HttpCookie> cookies = cookieJar.getCookies(); for (HttpCookie cookie: cookies) { if (cookie.getDomain().contains((".zybez.net"))) { if(cookie.getName().equals("__cfduid")){ __cfduid = cookie.getValue(); }else if(cookie.getName().equals("z_session_id")){ z_session_id = cookie.getValue(); }else if(cookie.getName().equals("network_cookie")){ network_cookie = cookie.getValue(); }else if(cookie.getName().equals("z_member_id")) { z_member_id = cookie.getValue(); }else if(cookie.getName().equals("z_pass_hash")){ z_pass_hash = cookie.getValue(); }else{ if(debug) System.out.println("Unknown cookie : " + cookie.getName() + "\t" + cookie.getDomain()); } }else{ if(debug) System.out.println("Unknown website : " + cookie.getName() + "\t" + cookie.getDomain()); } } }catch (Exception ex){ ex.printStackTrace(); } if(z_member_id == null || z_pass_hash == null){ throw new RuntimeException("Failed to login!"); } } private String getAuth() throws Exception{ String pattern = "<input type='hidden' name='auth_key' value='"; String response = Requests.sendGet("http://forums.zybez.net/index.php?app=curseauth&module=global§ion=login"); int beginIndex = response.indexOf(pattern) + pattern.length(); int endIndex = response.indexOf("' />", beginIndex); return response.substring(beginIndex, endIndex); } public String getCookie(){ StringBuilder sb = new StringBuilder(); sb.append("__cfduid=" + __cfduid + "; "); sb.append("network_cookie=" + network_cookie + "; "); sb.append("z_rteStatus=" + z_rteStatus + "; "); sb.append("z_member_id=" + z_member_id + "; "); sb.append("z_pass_hash=" + z_pass_hash + "; "); sb.append("z_session_id" + z_session_id + "; "); return sb.toString(); } public Character[] getCharacters(){ List<Character> character = new LinkedList<>(); try { String response = Requests.sendGet("http://forums.zybez.net/runescape-2007-prices/274-water-rune", getCookie()); Matcher matcher = Pattern.compile("<option value=\"(.+?)\">(.+?)</option>$",Pattern.MULTILINE).matcher(response); while (matcher.find()) { if(debug) System.out.println("Found character : " + matcher.group(1) + " " + matcher.group(2)); character.add(new Character(Integer.parseInt(matcher.group(1)),matcher.group(2))); } return character.toArray(new Character[character.size()]); }catch (Exception e){ e.printStackTrace(); } return null; } public ZybezOffer[] getCurrentOffers(){ List<ZybezOffer> zybezOffers = new LinkedList<>(); try { String response = Requests.sendGet("http://forums.zybez.net/runescape-2007-prices", getCookie()); int beginIndex = response.indexOf("My Offers"); int endIndex = response.indexOf("</table>", beginIndex); //System.out.println(response.substring(beginIndex,endIndex)); Matcher matcher = Pattern.compile("<tr>\\s*<td class=\"nowrap\"><h3><a href=\"(.*?)\">(.*?)<.*?$\\s*.*\\s*.*title=\"(.*?)\" class.*?\\s*.*?>(.*?)<\\/.*$\\s*(.*?) for (.*?) GP\\s*.*\\s*.*\\s*.*?title=\"(.*?)\">(.*?)<\\/span><\\/td>\\s*.*?\">(.*?) GP<\\/td>\\s*<td>\\s*<a href=\"(.*?)\"><img src=\"(.*?)\" title=\"Delete\" \\/><\\/a>\\s*<a href=\"(.*?)\"><img src=\"(.*?)\" title=\"Mark this offer complete\" \\/><\\/a>\\s*<\\/td>\\s*<\\/tr>",Pattern.MULTILINE).matcher(response.substring(beginIndex,endIndex)); while (matcher.find()) { if(debug) System.out.println("Found offer : " + matcher.group(1) + " " + matcher.group(2) + " " + matcher.group(3) + " for " + matcher.group(4) + "GP\t" + matcher.group(5) + "\t" + matcher.group(6)); zybezOffers.add(new ZybezOffer(matcher.group(2),matcher.group(3),matcher.group(1),matcher.group(3).equals("Selling") ? OfferType.SELL : OfferType.BUY,Integer.parseInt(matcher.group(5).replaceAll(",", "")),Integer.parseInt(matcher.group(6).replaceAll(",", "")),matcher.group(7),1,matcher.group(8),matcher.group(12))); } return zybezOffers.toArray(new ZybezOffer[zybezOffers.size()]); }catch (Exception e){ e.printStackTrace(); } return null; } public ZybezOffer[] getCompleteOffers(){ List<ZybezOffer> zybezOffers = new LinkedList<>(); try { String response = Requests.sendGet("http://forums.zybez.net/runescape-2007-prices", getCookie()); int beginIndex = response.indexOf("My Offers"); int endIndex = response.indexOf("</table>", beginIndex); Matcher matcher = Pattern.compile("<tr class=\"done\">\\s*<td class=\\\"nowrap\\\"><h3><a href=\"(.*?)\">(.*?)<.*?$\\s*.*\\s*.*title=\"(.*?)\" class.*?\\s*.*?>(.*?)<\\/.*$\\s*(.*?) for (.*?) GP\\s*.*\\s*.*\\s*.*?title=\\\"(.*?)\\\">(.*?)<\\/span><\\/td>\\s*.*?\\\">(.*?) GP<\\/td>\\s*<td>\\s*<a href=\\\"(.*?)\\\"><img src=\\\"(.*?)\\\" title=\\\"Delete\\\" \\/><\\/a>\\s*<a href=\\\"(.*?)\\\"><img src=\\\"(.*?)\\\" title=\\\"Mark this offer complete\\\" \\/><\\/a>\\s*<\\/td>\\s*<\\/tr>",Pattern.MULTILINE).matcher(response.substring(beginIndex,endIndex)); while (matcher.find()) { if(debug) System.out.println("Found offer : " + matcher.group(1) + " " + matcher.group(2) + " " + matcher.group(3) + " for " + matcher.group(4) + "GP\t" + matcher.group(5) + "\t" + matcher.group(6)); zybezOffers.add(new ZybezOffer(matcher.group(2),matcher.group(3),matcher.group(1),matcher.group(3).equals("Selling") ? OfferType.SELL : OfferType.BUY,Integer.parseInt(matcher.group(5).replaceAll(",", "")),Integer.parseInt(matcher.group(6).replaceAll(",", "")),matcher.group(7),1,matcher.group(10),matcher.group(12))); } return zybezOffers.toArray(new ZybezOffer[zybezOffers.size()]); }catch (Exception e){ e.printStackTrace(); } return null; } } //Stages//Offer.java package aiomercher.util.zybez.stages; import aiomercher.util.zybez.utils.*; import aiomercher.util.zybez.utils.Character; import java.net.URLEncoder; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by Xerion on 19-8-2014. */ public class Offer { Login login; public Offer(Login login){ this.login = login; } /** * Add an offer to Zybez * * @param id Item ID * @param offerType The Offer type (buy or sell) * @param quantity The amount you want to buy/sell * @param price The price you want to buy/sell the item for * @param character The character you want to appear in the offer * @param contactMode The contact mode you want to specify (PM or CC) * @return True if the offer is placed on Zybez */ public boolean createOffer(int id,OfferType offerType,int quantity, int price, Character character, ContactMode contactMode){ return createOffer(getAuth(id),id,offerType.getValue(),quantity,price,character.getId(),contactMode.getValue(),"",login.getCookie()); } /** * Add an offer to Zybez * * @param id Item ID * @param offerType The Offer type (buy or sell) * @param quantity The amount you want to buy/sell * @param price The price you want to buy/sell the item for * @param character The character you want to appear in the offer * @param contactMode The contact mode you want to specify (PM or CC) * @param notes The Notes you want to add in the offer * @return True if the offer is placed on Zybez */ public boolean createOffer(int id,OfferType offerType,int quantity, int price, Character character, ContactMode contactMode, String notes){ return createOffer(getAuth(id),id,offerType.getValue(),quantity,price,character.getId(),contactMode.getValue(),notes,login.getCookie()); } private boolean createOffer(String auth, int id, int type, int quantity, int price, int characterId, int contact, String notes, String Cookie){ String url = "http://forums.zybez.net/index.php?app=priceguide&module=public§ion=action&do=trade-add"; System.out.println("auth: "+(auth!=null?auth:"null")+", id: "+id+", type: "+type+", price: "+price+", charId: "+characterId+", contact: "+contact+", note: "+notes+", cookie: "+(Cookie!=null?Cookie.toString():"null")); try{ String urlParameters = "auth=" + URLEncoder.encode(auth, "UTF-8") + "&id=" + URLEncoder.encode(Integer.toString(id), "UTF-8") +"&type=" + URLEncoder.encode(Integer.toString(type), "UTF-8") + "&qty=" + URLEncoder.encode(Integer.toString(quantity), "UTF-8") +"&price=" + URLEncoder.encode(Integer.toString(price), "UTF-8") + "&character_id=" + URLEncoder.encode(Integer.toString(characterId), "UTF-8") +"&contact=" + URLEncoder.encode(Integer.toString(contact), "UTF-8")+ "¬es=" + URLEncoder.encode(notes, "UTF-8"); if(Requests.sendGet(url + "?" + urlParameters,Cookie).contains("Your trade has been added to the system.")){ return true; } return false; }catch (Exception ex){ ex.printStackTrace(); return false; } } public String getAuth(int id){ try{ String response = Requests.sendGet(getSite(id),login.getCookie()); Matcher matcher = Pattern.compile("<input type=\"hidden\" name=\"auth\" value=\"(.+?)\" />").matcher(response); if (matcher.find()){ return (matcher.group(1)); }else{ throw new RuntimeException("Failed to find the auth"); } }catch (Exception e){ e.printStackTrace(); } return null; } private String getSite(int id){ try{ String response = Requests.sendGet("http://forums.zybez.net/index.php?app=priceguide&module=public§ion=list"); Matcher matcher = Pattern.compile("<a href=\"(http://forums.zybez.net/runescape-2007-prices/" + id + "-.*?)\">").matcher(response); if (matcher.find()){ return matcher.group(1); }else{ throw new RuntimeException("ID is invalid!"); } }catch (Exception e){ e.printStackTrace(); } return null; } /* public static String getItemName(int id){ try{ String response = Requests.sendGet("http://forums.zybez.net/runescape-2007-prices/api/item/" + id); Matcher matcher = Pattern.compile("name\":\"(.+?)\",\"type").matcher(response); if (matcher.find()){ String result = matcher.group(1); //System.out.println(result); //result = result.replace(' ', '-'); //result = result.replace("(", "").replace(")", ""); //System.out.println(result); return result; }else{ throw new RuntimeException("Cannot find item name!"); } }catch (Exception e){ e.printStackTrace(); } return null; } */ public static enum OfferType { BUY(0), SELL(1); private final int value; private OfferType(int value) { this.value = value; } public int getValue() { return value; } } public static enum ContactMode { PM(1), CC(3); private final int value; private ContactMode(int value) { this.value = value; } public int getValue() { return value; } } } //utils/Character.java package aiomercher.util.zybez.utils; /** * Created by Xerion on 19-8-2014. */ public class Character { private int id; private String accountName; /** * * @param id ZYbez account id * @param accountName Runescape account name */ public Character(int id, String accountName){ this.id = id; this.accountName = accountName; } public int getId() { return id; } public String getAccountName() { return accountName; } @Override public String toString(){ return this.accountName; } } //utils//OfferType.java package aiomercher.util.zybez.utils; /** * Created by Xerion on 25-8-2014. */ public enum OfferType { BUY(0), SELL(1); private final int value; private OfferType(int value) { this.value = value; } public int getValue() { return value; } @Override public String toString() { return this.name().substring(0, 1).toUpperCase() + this.name().substring(1).toLowerCase(); } } //utils//Requests.java package aiomercher.util.zybez.utils; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; /** * Created by Xerion on 19-8-2014. */ public class Requests { public static boolean debug = false; public static String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36"; public static String sendGet(String targetURL) throws Exception { return sendGet(targetURL,null); } public static String sendGet(String targetURL, String cookie) throws Exception { String url = targetURL; URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); // optional default is GET con.setRequestMethod("GET"); //add request header con.setRequestProperty("User-Agent", USER_AGENT); //add cookie if(cookie != null) con.setRequestProperty("Cookie" , cookie); int responseCode = con.getResponseCode(); if(debug) { System.out.println("\nSending 'GET' request to URL : " + url); System.out.println("Follow redirects: " + con.getInstanceFollowRedirects()); System.out.println("Response Code : " + responseCode); } BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); response.append("\n"); } in.close(); if(debug) { for (String s : con.getHeaderFields().get("Set-Cookie")) { System.out.println(s); } } //return result return response.toString(); } } //utils//ZybezOffer.java package aiomercher.util.zybez.utils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by Xerion on 25-8-2014. */ public class ZybezOffer { private int amount, price; private String itemName, itemLink, itemOwner; private long epoch; private OfferType offerType; private String completeUrl, deleteUrl; private int place; public ZybezOffer(String ItemName,String owner, String Link , OfferType OfferType, int Amount, int Price, String Time, int place) throws ParseException { this.itemName = ItemName; this.itemLink = Link; this.itemOwner = owner.replace("Verified owner of ", ""); this.offerType = OfferType; this.amount = Amount; this.price = Price; this.place = place; this.epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz").parse(Time).getTime(); } public ZybezOffer(String ItemName,String owner, String Link , OfferType OfferType, int Amount, int Price, String Time, int place, String CompleteUrl, String DeleteUrl) throws ParseException { this.itemName = ItemName; this.offerType = OfferType; this.itemLink = Link; this.itemOwner = owner.replace("Verified owner of ", "");; this.amount = Amount; this.price = Price; this.place = place; this.epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz").parse(Time).getTime(); this.completeUrl = CompleteUrl; this.deleteUrl = DeleteUrl; } public int getPrice() { return price; } //public int getPlace(){ return place; } public int getAmount() { return amount; } public String getItemName() { return itemName; } public long getEpoch() { return epoch; } public OfferType getOfferType() { return offerType; } public Date getDate(){ return new Date(epoch); } public void completeOffer(String Cookie){ try { System.out.println(completeUrl); System.out.println(Cookie); Requests.sendGet(completeUrl, Cookie); }catch (Exception e){ e.printStackTrace(); } } public void deleteOffer(String Cookie){ try { System.out.println(deleteUrl); System.out.println(Cookie); Requests.sendGet(deleteUrl, Cookie); }catch (Exception e){ e.printStackTrace(); } } public int getPlace(){ try { String response = Requests.sendGet(this.itemLink); int beginIndex = response.indexOf("<table class=\"ipb_table topic_list\">"); int endIndex = response.indexOf("</table>", beginIndex); //System.out.println(response.substring(beginIndex,endIndex)); Matcher matcher = Pattern.compile("<tr>\\s*<td class=\"nowrap\">\\s*.*?title=\"(.*?)\" class.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*?<span title=\"(.*?)\">", Pattern.MULTILINE).matcher(response.substring(beginIndex,endIndex)); int place = 1; while (matcher.find()) { if(this.itemOwner.equals(matcher.group(1).replace("Verified owner of ", "")) && new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz").parse(matcher.group(2)).getTime() == this.epoch){ return place; }else{ place++; } //System.out.println(matcher.group(1) + "\t" + matcher.group(2)); } }catch (Exception e){ e.printStackTrace(); } return -1; } @Override public String toString() { return offerType + "ing " + getAmount() + " × "+ itemName + " for " + getPrice() + "ea"; } } You are free to use the source code in anyway you like if you give credits to me. Constructive feedback is welcome. However I'm probably not going to change it. 5 Link to comment Share on other sites More sharing options...
Fantabulous Posted November 24, 2014 Share Posted November 24, 2014 GF @thepecher ? 3 Link to comment Share on other sites More sharing options...
Krulvis Posted November 24, 2014 Share Posted November 24, 2014 This code is hella sexy Link to comment Share on other sites More sharing options...
Xerion Posted November 24, 2014 Author Share Posted November 24, 2014 GF @thepecher ? 90% probably doesn't even know how to use this. Also zybez merching will become useless in the near future anyway. Link to comment Share on other sites More sharing options...
Articron Posted November 24, 2014 Share Posted November 24, 2014 Good use of regex, thanks for the read ;) Link to comment Share on other sites More sharing options...
Jack Posted November 24, 2014 Share Posted November 24, 2014 Nice. I didn't know HttpURLConnection had such a versatile use. Link to comment Share on other sites More sharing options...
Mikasa Posted November 24, 2014 Share Posted November 24, 2014 how would a basic pleeb like me use this? Link to comment Share on other sites More sharing options...
thepecher Posted November 25, 2014 Share Posted November 25, 2014 GF @thepecher ? Maybe, maybe not. (95% of people don't know how to use this) Nice contribution Xerion! 90% probably doesn't even know how to use this. Also zybez merching will become useless in the near future anyway. Not sure, from a mercher way of looking the trading post is bs. You can't add comments (like "Come dont PM)and people will always sort offers by cheapest. Also a seller can't select how many items he wishes to sell in the trade screen, just the offer he wants to trade. IMO the trading post is just a lesser zybez but then again it's in-game. Only time will tell what will happen Link to comment Share on other sites More sharing options...
Jaydz Posted November 25, 2014 Share Posted November 25, 2014 Is it confirmed that that trade post thing actually comes?If yes, where can i read about it thanks Link to comment Share on other sites More sharing options...
Xerion Posted November 25, 2014 Author Share Posted November 25, 2014 Is it confirmed that that trade post thing actually comes? If yes, where can i read about it thanks You should watch their streams more often. Link to comment Share on other sites More sharing options...
BotRS123 Posted November 25, 2014 Share Posted November 25, 2014 Any chance you have this on github? Much easier to navigate. Link to comment Share on other sites More sharing options...
Extreme Scripts Posted November 25, 2014 Share Posted November 25, 2014 That marcher dedication tho. Link to comment Share on other sites More sharing options...
liverare Posted November 25, 2014 Share Posted November 25, 2014 (edited) My ways of interacting with Zybez was via Selenium, so I had no idea there were light-weight alternatives. Cheers for this! And you're probably right about the trading post. I might release my 'back end' stuff for Zybez (the only completed stuff), too. Edited November 25, 2014 by liverare Link to comment Share on other sites More sharing options...
Dog_ Posted December 5, 2014 Share Posted December 5, 2014 That marcher dedication tho.nice marcher 1 Link to comment Share on other sites More sharing options...
Extreme Scripts Posted December 5, 2014 Share Posted December 5, 2014 nice marcher #Auto-correct ftw Link to comment Share on other sites More sharing options...