Jump to content

[Source]Zybez mercher


Xerion

Recommended Posts

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&section=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&section=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&section=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&section=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")+ "&notes=" + 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&section=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.

  • Like 5
Link to comment
Share on other sites

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

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 by liverare
Link to comment
Share on other sites

  • 2 weeks later...
Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...