Runescape Calculator

By Sam 1 Last update Aug 2, 2008 — Installed 1,236 times. Daily Installs: 0, 1, 3, 0, 2, 1, 2, 3, 0, 2, 1, 2, 2, 2, 0, 0, 3, 1, 2, 1, 2, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1

There are 1 previous version of this script.

// ==UserScript==
// @name rsexpcalc
// @namespace ubergeeky.org
// @include http://advert.runescape.com/banner.ws?size=729*
// @include http://world*.runescape.com/p*
// @require http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js
// ==/UserScript==

var statCount = 25;
var statsArray = new Array(statCount+1);
var levelEXP = new Array(-1,0,83,174,276,388,512,650,801,969,1154,1358,1584,1833,2107,2411,2746,3115,3523,3973,4470,5018,5624,6291,7028,7842,8740,9730,10824,12031,13363,14833,16456,18247,20224,22406,24815,27473,30408,33648,37224,41171,45529,50339,55649,61512,67983,75127,83014,91721,101333,111945,123660,136594,150872,166636,184040,203254,224466,247886,273742,302288,333804,368599,407015,449428,496254,547953,605032,668051,737627,814445,899257,992895,1096278,1210421,1336443,1475581,1629200,1798808,1986068,2192818,2421087,2673114,2951373,3258594,3597792,3972294,4385776,4842295,5346332,5902831,6517253,7195629,7944614,8771558,9684577,10692629,11805606,13034431);

//Activate in the parent window only if the advert frame doesn't exist...
window.setTimeout(function(){ if (!document.getElementById('tb')) showCalc(); }, 50);

function showCalc() {
  document.body.style.fontSize = "18px"; //override the default 0 size font

  var dynDiv = document.createElement('DIV');
  dynDiv.innerHTML = "<table width='766px' style='background: url(http://www.runescape.com/img/main/layout/bg_scroll.jpg) repeat-y center 83px; font-family: Arial, Helvetica, FreeSans, sans-serif; text-align: center; font-size:0.8em'><tr><td><b>Username:</b></td><td colspan='4'><b>Runescape Levelling Calculator</b></td><td rowspan='4' align='right' valign='top'><div class='qm' id='hideCalc'>X</div></td></tr><tr align='left'><td><input id='username' style='border: 0px;'/></td><td width='150px' align='right'>Current EXP:</td><td><input id='curexp' style='border: 0px'/></td><td align='right' id='gainlabel'>Unit Gain:</td><td><input id='unitgain' style='border: 0px'/></td></tr><tr align='left'><td align='center'><input id='getstats' value='Load High Scores' type='button'></td><td align='right'>Required Level:</td><td><input id='reqlev' style='border: 0px'/></td><td width='150px' align='right'>Multiplier:</td><td><input type='checkbox' id='multi'/><input id='multiplier' style='border: 0px; width: 50px'/></td></tr><tr align='left'><td align='center'><select id='stats'><option value='-1' id='defaultStatsOption'>- No Data -</option></select></td><td align='right'>Required EXP:</td><td align='left' id='reqexp'>&nbsp;</td><td align='right'>Required Units:</td><td align='left' id='requnit'>&nbsp;</td></tr><tr><td colspan='6'>&nbsp;</td></tr></table>"
  dynDiv.style.backgroundColor = "#000";
  dynDiv.style.width = "100%";
  dynDiv.style.height = "95px";
  dynDiv.style.display = "none"; //don't set this to "block" or else you wont get to see the adverts by default
  dynDiv.align = "center";
  dynDiv.id = "calcDiv";
  
  document.body.insertBefore(dynDiv,document.body.firstChild);
  
  if (document.domain != "advert.runescape.com") {
    //Members world, always show the calc...
    dynDiv.style.display = "block";
    document.getElementById('hideCalc').style.display = "none";
  } else {
    //F2P, calc is optional...
    var buttonContainer = evalXPath(document, "/html/body/table[@id='t']/tbody/tr/td/table/tbody/tr/td[3]")[0];
    buttonContainer.innerHTML = "<div class='qm' id='toggleCalc' style='position: relative; top: -15px; left: 3px;'>C</div>" + buttonContainer.innerHTML;
    document.getElementById('toggleCalc').addEventListener("click", toggleCalc, true);
    document.getElementById('hideCalc').addEventListener("click", toggleCalc, true);
  }
  
  document.getElementById('username').value = GM_getValue('username', 'Noobtardio');
  document.getElementById('stats').addEventListener("change", populateCurrentEXP, true);
  document.getElementById('getstats').addEventListener("click", getPlayerStats, true);
  document.getElementById('curexp').addEventListener("change", recalculate, true);
  document.getElementById('curexp').value = GM_getValue('curexp', '');
  document.getElementById('multi').addEventListener("change", recalculate, true);
  document.getElementById('multi').checked = GM_getValue('multi', 'false');
  document.getElementById('multiplier').addEventListener("change", recalculate, true);
  document.getElementById('multiplier').value = GM_getValue('multiplier', '4');
  document.getElementById('reqlev').addEventListener("change", recalculate, true);
  document.getElementById('reqlev').value = GM_getValue('reqlev', '');
  document.getElementById('unitgain').addEventListener("change", recalculate, true);
  document.getElementById('unitgain').value = GM_getValue('unitgain', '');
  if (!document.getElementById('multi').checked) document.getElementById('multiplier').disabled = true;
  
  recalculate();
}

function getPlayerStats(){
  player = document.getElementById('username').value;
  if (player != ''){  
    getStats(player);
  }else{
    alert("Enter the username");
  }
}

function populateCurrentEXP(){
  selectList = document.getElementById('stats');
  GM_setValue('username', document.getElementById('username').value);
  if (selectList.value > -1) {
    document.getElementById('curexp').value = statsArray[selectList.value].exp;
    recalculate();
  }
}

function toggleCalc(){
  if (document.getElementById("calcDiv").style.display == "none")
    document.getElementById("calcDiv").style.display = "block";
  else
    document.getElementById("calcDiv").style.display = "none";
}

function recalculate(){
  var curexp = document.getElementById('curexp').value;
  var multi = document.getElementById('multi').checked;
  var multiplier = document.getElementById('multiplier').value;
  var reqlev = document.getElementById('reqlev').value;
  var unitgain = document.getElementById('unitgain').value;
  
  GM_setValue('curexp', curexp);
  GM_setValue('multi', multi);
  GM_setValue('multiplier', multiplier);
  GM_setValue('reqlev', reqlev);
  GM_setValue('unitgain', unitgain);
  if (multi) {
    unitgain *= multiplier;
    document.getElementById('gainlabel').innerHTML = 'Base Gain:';
    document.getElementById('multiplier').disabled = false;
  } else {
    document.getElementById('gainlabel').innerHTML = 'Unit Gain:';
    document.getElementById('multiplier').disabled = true;
  }
  
  var reqexpNode = document.getElementById('reqexp');
  var requnitNode = document.getElementById('requnit');

  var reqexp = levelEXP[reqlev] - curexp;
  reqexpNode.innerHTML = reqexp;
  requnitNode.innerHTML = Math.ceil(reqexp / unitgain);
}

function getStats(player){
  var parameters = "user1="+player.toLowerCase()+"&submit=Search"
  var anything = '[\\S\\s]*'; //This regex seems to work best to include newline characters aswell
  
  selectList = document.getElementById('stats');
  selectList.innerHTML = "<option value='-1' id='defaultStatsOption'>Loading...</option>";
  
  GM_xmlhttpRequest({
      method: 'POST',
      url: "http://hiscore.runescape.com/hiscorepersonal.ws",
      headers: {
          'Content-type': 'application/x-www-form-urlencoded',
          'Content-length': parameters.length,
          'Connection': 'close',
      },
      data:parameters,
      onload: function(responseDetails) {
          try {
            docu = responseDetails.responseText;
            var rankedStats = 0;
            for(var i = 1; i <= statCount; i++){
              //Regular expression to return the row's innerHTML...
              var re = new RegExp('^(?:'+anything+'?)<tr\\sclass="row\\srowp'+i+'">('+anything+'?)<\\/tr>(?:'+anything+'?)$');
              rowInnerHTML = docu.replace(re, '$1');
              //Fix a glitch in the Hiscore XML where the img tag isn't closed...
              rowInnerHTML = rowInnerHTML.replace(/\.gif">/, '.gif"></img>');
              
              jQry = jQuery(rowInnerHTML);
              statsArray[i] = new Object();
              //Extract all the <td class=a1L> text into an array, trimming any whitespace and commas...
              rowDataArray = jQry.filter('.alL').map(function(){ return $(this).text().replace(/[\n\s\t,]/g,""); });
              
              if (rowDataArray.length == 4){
                //Ranked stat
                statsArray[i].label = rowDataArray[0];
                statsArray[i].rank = rowDataArray[1];
                statsArray[i].level = rowDataArray[2];
                statsArray[i].exp = rowDataArray[3];
                var option = document.createElement('OPTION');
                option.value = i;
                option.innerHTML = statsArray[i].label;
                selectList.appendChild(option);
                rankedStats++;
              } else {
                //Not ranked
                statsArray[i].label = rowDataArray[0];
                statsArray[i].rank = "Not Ranked";
                statsArray[i].level = "Not Ranked";
                statsArray[i].exp = "Not Ranked";
              }
            }
            
            defaultStatsOption = document.getElementById('defaultStatsOption');
            if (rankedStats > 0) {
              defaultStatsOption.innerHTML = '- Choose Stat -';
            } else {
              defaultStatsOption.innerHTML = '- Not Ranked -';
            }
            
            //~ summaryString = 'Stats for '+player+':\n';
            //~ for(var i = 1; i <= statCount; i++){
              //~ summaryString += statsArray[i].label + "\t" + statsArray[i].rank + "\t" + statsArray[i].level + "\t" + statsArray[i].exp + "\t\n"
            //~ }
            //~ alert(summaryString)
          }
          catch(e){
              //Set the error information...
              alert(e);
          }
      }
  });
}

function evalXPath(aNode, aExpr) {
  var xpe = new XPathEvaluator();
  var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
    aNode.documentElement : aNode.ownerDocument.documentElement);
  var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
  var found = [];
  var res;
  while (res = result.iterateNext())
    found.push(res);
  return found;
}