Crystal Check

Combine dropped crystals after hunting

当前为 2014-08-19 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name            Crystal Check
// @match           http://dev.legacy-game.net/hunting3.php
// @version         1.0
// @namespace       https://greasyfork.org/users/4585
// @description     Combine dropped crystals after hunting
// @grant           none
/*global $ */
// ==/UserScript==


/*****************************************************
                    General Methods                    
/****************************************************/
//Method to create elements on the fly without injecting html
function create(type,attr,text,parent){
    var ele = document.createElement(type);
    for(var x in attr){
        if(x.hasOwnProperty){
            ele.setAttribute(x,attr[x]);
        }
    }
    if(text){ele.innerHTML = text;}
    if(parent){parent.appendChild(ele);}
    return ele;
}
//Return user cookies as object
function getCookies(){
    return document.cookie
        .split(/[;\s]+/g)
        .reduce(function(a,b){
            a[b.split('=')[0]] = b.split('=')[1];
            return a;
        },{});
}
/*****************************************************
                    Inventory                    
/****************************************************/

//Inventory API to manipulate inventory items
function Inventory(html){
    this.items = getItems();
    var key = $(html).find('form').attr('action').match(/[a-zA-Z]+$/g).pop();
    //Inventory items encapsulated to organise data
    function Item(name,slot,trades,id){
        this.name = name;
        this.slot = slot;
        this.trades = trades;
        this.id = id;

        //Crystal merging method
        this.merge = function(that,callback){
            var slot1 = this.slot;
            var slot2 = that.slot;
            $.ajax({
                type:"POST",
                url:"inventory10.php?i="+slot1+"&key="+key,
                async:false,
                data:{item:slot2},
                success:function(data){
                    //If method available, use on response data to check for further crystal merging
                    //Response from merging should be the redirected inventory page, which can be used to
                    //refresh inventory data
                    if(callback)
                        callback(data);
                }
            });
        };
    }
    //captures all item data for the inventory & encapsulates as an object
    function getItems(){
        //Match javascript lines on inventory.php for item id & trades
        //Each resulting index corresponds to the slot in inventory
        var itemPreviews = html.match(/(itemPreviews\[)((.|\n)*?)(Default|table>');/g);
        var tempItems = [];
        $(html).find('img.item').each(function(){
            var slot = parseInt($(this).attr('name'));
            var dat = itemPreviews[slot].replace("Un-tradable","0 Trades").match(/(\d+)(?=(&c=|\sTrades))/g);
            tempItems.push(new Item($(this).attr('title'),slot,dat[0],dat[1]));
        });
        return tempItems;
    }

    //Returns all crystals in the inventory, sorted by item id (newest first)
    this.getCrystals = function(){
        return this.items
            //check if item is a crystal (must be have some word before crystal Crystal to avoid Crstal Rings)
            .filter(function(a){
                return a.name.match(/.+Crystal/)!==null;
            })
            //order from newest to oldest (item id descending)
            .sort(function(a,b){return b.id-a.id;});
    };
    //Searches for best match of given crystal within the inventory
    this.matchCrystal = function(crystal){
        var matches = this.getCrystals().filter(function(a){return a.id !== crystal.id && a.name == crystal.name;});
        return matches.length > 0 ? 
            [crystal,matches.reduce(function(a,b){return a.trades === crystal.trades?a:a.trades>b.trades?a:b;})]:
            null;
    };
}

/*****************************************************
                    Hunting Setup                    
/****************************************************/

//Once a crystal drop has been detected
function checkDrop(){
    //Display 'found match' message on single line row
    function singleRow(crystal){
        var r = create('tr',{},false,$('tbody:contains("Item Found")')[0]);
        create('td',
            {width:"100%",class:"standardrow",align:"center",colspan:"2"},
            'You have a matching '+crystal.name+' ('+crystal.trades+'t) in your inventory. <span class="merge" style="cursor:pointer;">[Merge]</span>',
            r);
    }

    //create 'item drop' row displaying merged crystal image + result message
    function doubleRow(crystal){
        var r = create('tr',{},false,$('tbody:contains("Item Found")')[0]);
        create('td',{width:"10%",class:"standardrow",align:"center"},"<img src='img-bin/items/"+crystal.name.toLowerCase()+".png'/>",r);
        create('td',{width:"90%",class:"standardrow",align:"center"},crystal.name+" added to inventory.",r);
    }
    $.ajax({
        url:'inventory.php',
        async:false,
        success:function(data){
            var inv = new Inventory(data);
            var drop = inv.getCrystals()[0];
            console.log(inv.matchCrystal(drop));
            option(inv.matchCrystal(drop));
            //recursive method - if crystal match, display option to merge - if merged, display result
            //if crystal match with previous result, offer to match again, etc
            function option(match){
                if(match){
                    singleRow(match[1]);
                    $('span.merge').click(function(){
                        $(this).remove();
                        //merge newest crystal [0] with best matching crystal [1]
                        match[0].merge(match[1],
                            //anonymous function as input for merge callback to display merge option on previously merged crystal
                            function(data){
                                var nextInv = new Inventory(data);
                                var newCrystal = nextInv.getCrystals()[0];
                                doubleRow(newCrystal);
                                option(nextInv.matchCrystal(newCrystal));
                            }
                        );
                    });
                }
            }
        }
    });
}


/*****************************************************
                    Hunt Again Button                    
/****************************************************/

//Build a clickable button which allows the user to attack 
//the same hunt group again without visiting the hunt page again
//If there are buttons present, the fight is ongoing
//If there is a page title, user is on error or multiattack screen
if(!($('.button').length || $('.pagetitle').length)){
    //Create Hunt Again button & position next to Back to Hunting page url, change row to fit
    var td = $('td:has("#back-to-hunting")');
    td.prop("width","50%");
    var newCell = create("td",{class:"standardrow",width:"50%",align:"center"},false,td.parent()[0]),
        newButt = create("input",{type:"button",class:"button",value:"Hunt Again"},false,newCell);
    td.before(newCell);

    //Gather attack string from hunting.php && cookie info for next hunt form
    var form = create("form",{action:"hunting3.php",method:'post',style:"display:none;"},false,document.body),
        attackString,
        cookies = getCookies();
    create("input",{type:"hidden",name:"group",value:cookies.hunting_group},false,form);
    create("input",{type:"hidden",name:"level",value:cookies.hunting_level},false,form);
    create("input",{type:"submit",value:"Attack Target",class:"button",id:"hunt-"+cookies.hunting_group+"-"+cookies.hunting_level},false,form);

    $.ajax({
        url:'hunting.php',
        async:false,
        success:function(data){
            attackString = data.match(/([a-zA-Z]{20})(?=">')/g).pop();
            create("input",{type:"hidden",name:"attackstring",value:attackString},false,form);
        }
    });
    //Button method - disable to prevent multi-attack & submit to proceed
    $(newButt).click(function(){
        $(this).attr("disabled", true);
        form.submit();
    });
    //Hunt Group 18 - Crystal Entities and crystal drop
    if(cookies.hunting_group == "18" && $('tbody:contains("Item Found")').length){
        checkDrop();
    }
}