Created
April 17, 2016 06:35
-
-
Save EFox2413/ee90a20dd2cfdcd127730b3b583621d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name initium-plus | |
// @namespace https://github.com/EFox2413/initiumGrease | |
// @version 0.0.1.2 | |
// @updateURL https://raw.githubusercontent.com/EFox2413/initiumGrease/master/initium-plus.meta.js | |
// @downloadURL https://raw.githubusercontent.com/EFox2413/initiumGrease/master/initium-plus.js | |
// @supportURL https://github.com/EFox2413/initiumGrease/issues | |
// @match https://www.playinitium.com/* | |
// @match http://www.playinitium.com/* | |
// @grant none | |
// @grant GM_setValue | |
// @grant GM_listValues | |
// @grant GM_getValue | |
// @grant GM_deleteValue | |
// ==/UserScript== | |
/* jshint -W097 */ | |
'use strict'; | |
var $ = window.jQuery; | |
//-------------------------UTILITIES-----------------------\\ | |
// UTIL | |
// mkPopup(content); | |
// checkNight(); | |
// version; | |
var Util = function() { | |
// creates a popup with HTML content | |
var mkPopup = function(content) { | |
// close all other popups, increment popup counter | |
closePagePopup(); | |
currentPopupStackIndex++; | |
exitFullscreenChat(); | |
var pagePopupId = "page-popup" + currentPopupStackIndex; | |
//No elements have z-index on the combat screen, so we | |
//cant have page-popup-glass there because it relies on | |
//z-index to not cover everything | |
var structure = "<div id='"+pagePopupId+"'><div id='" + | |
pagePopupId+"-content' style='min-height:150px;' " + | |
"class='page-popup'><img id='banner-loading-icon' " + | |
"src='javascript/images/wait.gif' border=0/></div>" + | |
"<div class='page-popup-glass'></div><a class='page-popup-X' " + | |
"onclick='closePagePopup()'>X</a></div>"; | |
// checks if current page is doesn't have #page-popup-root | |
// and adds the needed div if it is | |
if ($("#page-popup-root").length == 0) { | |
$('<div id="page-popup-root"></div>').insertAfter(".chat_box"); | |
} | |
//Create popup | |
$("#page-popup-root").append(structure); | |
//If chat box doesnt have z index, remove glass box | |
if( $(".chat_box").css('z-index') != '1000100') { | |
$(".page-popup-glass").remove(); | |
} | |
//Fill popup with content | |
$("#"+pagePopupId+"-content").html(content); | |
// pressing escape will close the popup | |
if (currentPopupStackIndex === 1) { | |
$(document).bind("keydown",function(e) { | |
if ((e.keyCode == 27)) { | |
closePagePopup(); | |
} | |
}); | |
} | |
// hides previous popup if there was one | |
if (currentPopupStackIndex > 1) { | |
$("#page-popup" + (currentPopupStackIndex-1)).hide(); | |
} | |
}; | |
var version = '0.0.1.2'; | |
// checks if current in-game time is night | |
var checkNight = function() { | |
var randConstant = 318.47133757961783439490445859873; | |
var serverTime = getCurrentServerTime() / (randConstant*60*60*1.5); | |
var amount = Math.abs(Math.sin(serverTime)) * 3.0 - 1.56; | |
return amount > 1; | |
}; | |
var oPublic = { | |
mkPopup: mkPopup, | |
checkNight: checkNight, | |
version: version, | |
}; | |
return oPublic; | |
}(); | |
//-------------------------FEATURES-------------------------\\ | |
// DEBUFF | |
// init(); | |
var Debuff = function() { | |
// get the charbox div of the player | |
var charBox = $( '.character-display-box' ).first(); | |
var isRaining = getWeather() > 0.5; | |
var isNight = Util.checkNight(); | |
var isBuffed = $( '.buff-pane' ).length; | |
// returns the HTML str specific to the viariables | |
var getBuffIconHTML = function( effect, descript, expiry, img, title ) { | |
var htmlStr = "<div class='buff-detail'>" + | |
"<img style='-webkit-filter:hue-rotate(250deg)' src='" + img + "' border='0'/>" + | |
"<div class='buff-detail-header'>" + | |
"<h5>" + title + "</h5>" + | |
"<div class='buff-detail-effect'>" + effect + "</div>" + | |
"</div>" + | |
"<div class='buff-detail-description item-flavor-description'>" + descript + "</div>" + | |
"<div class='buff-detail-expiry'>" + expiry + "</div>" + | |
"</div>" + "</div>"; | |
return htmlStr; | |
}; | |
// adds the necessary buff pane and hidden tooltip divs | |
var addBuffDivs = function() { | |
// buff specific div HTML to add | |
var buffPaneHTML = "<div class='buff-pane hint' rel='#buffDetails'>" + | |
"</div>"; | |
var buffBoxHTML = "<div class='hiddenTooltip' id='buffDetails'>" + | |
"<h4 style='margin-top:0px;'> Your buffs/debuffs </h4></div>"; | |
// add the divs to the document | |
charBox.append( buffPaneHTML ); | |
charBox.append( buffBoxHTML ); | |
}; | |
// adds the rain buff to the buff pane | |
var addRainBuff = function(buffBox) { | |
// image for the buff, re-uses a normal buff icon | |
var buffImage = "https://www.playinitium.com/images/small/Pixel_Art-" + | |
"Icons-Buffs-S_Buff14.png"; | |
// Rain specific descriptions for the buff cluetip | |
var buffDetailEffect = "It's harder to find new monsters when it's raining."; | |
var buffDetailDescript = "You are having a bit of a rainy day. " + | |
"This happens when you are outside sometimes. " + | |
"The effect lasts for 30 minutes or more depending on the weather."; | |
var buffDetailExpiry = "Expires in ?? minutes. Maybe, you should " + | |
"watch the weather channel."; | |
var buffTitle = "Rainy"; | |
// add image to buff pane | |
// TODO: make cross compatible | |
$( '.buff-pane' ).append("<img style='-webkit-filter:hue-rotate(250deg)' src='" + | |
buffImage + "' border='0'>"); | |
// add hidden cluetip div | |
buffBox.append(getBuffIconHTML(buffDetailEffect, buffDetailDescript, | |
buffDetailExpiry, buffImage, buffTitle)); | |
}; | |
// adds the night buff to the buff pane | |
var addNightBuff = function(buffBox) { | |
// Image for the buff, re-uses a normal buff icon with a filter | |
var buffImage = "https://www.playinitium.com/images/small2/Pixel_Art-Armor-Icons-Moon1.png"; | |
// Night specific descriptions for the buff cluetip | |
var buffDetailEffect = "Monsters are able to find you more easily. " + | |
"It's harder to find new paths."; | |
var buffDetailDescript = "It's nighttime. This happens when the sun goes down. " + | |
"You feel something watching you. You are having trouble seeing. " + | |
"The effect lasts for 30 minutes or more."; | |
var buffDetailExpiry = "Expires in ?? minutes. You should really buy a watch."; | |
var buffTitle = "Night"; | |
// add image to buff pane | |
// TODO: make cross compatible | |
$( '.buff-pane' ).append("<img style='-webkit-filter:hue-rotate(250deg)' src='" + | |
buffImage + "' border='0'>"); | |
// add hidden cluetip div | |
buffBox.append(getBuffIconHTML(buffDetailEffect, buffDetailDescript, | |
buffDetailExpiry, buffImage, buffTitle)); | |
}; | |
// initialize module | |
var init = function() { | |
if ( isRaining || isNight ) { | |
// add buff divs if there aren't any | |
if ( !isBuffed ) { | |
addBuffDivs(); | |
} | |
// gets the player's buffBox and not the enemy's | |
var buffBox = $( '#buffDetails' ).first(); | |
if (isRaining) { | |
addRainBuff(buffBox); | |
} | |
if (isNight) { | |
addNightBuff(buffBox); | |
} | |
} | |
}; | |
// public API | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
// WEATHER FORECAST | |
// init(); | |
var WeatherForecast = function() { | |
// Weather ratio from getWeather function in server js file... | |
var weatherInt = getWeather(); | |
var lightning = processLightning(); | |
var nextWeatherInt = getNextWeather(); | |
var nextLightning = getNextLightning(); | |
function translateToString(wRatio, LRatio) { | |
if (wRatio > 0.5) { | |
if ( LRatio > 0) { | |
return "Stormy"; | |
} else { | |
return"Rain"; | |
} | |
} else if (wRatio < 0.5) { | |
// It's not sunny at night... | |
if (Util.checkNight()) { | |
return "Clear"; | |
} | |
return "Sunny"; | |
} | |
return "N/A"; | |
} | |
var init = function() { | |
$( '.header-location' ).append( '<span ' + getColor() + '> ' + | |
"Now: " + translateToString(weatherInt, processLightning) + '<//span>' ); | |
$( '.header-location' ).append( '<span ' + getColor() + '> ' + | |
"Next: " + translateToString(nextWeatherInt, getNextLightning) + '<//span>' ); | |
}; | |
// returns a color for the string based on whether it's night time or day time | |
function getColor() { | |
if (Util.checkNight()) return 'style="color:purple"'; | |
return 'style="color:yellow"'; | |
} | |
// Weather calculator | |
function getNextWeather() { | |
var serverTime = getCurrentServerTime(); | |
var date = new Date(serverTime); | |
var behindHour = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours()+1); | |
var aheadHour = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours()+2); | |
var behindMs = behindHour.getTime(); | |
var aheadMs = aheadHour.getTime(); | |
var behindHourWeather = rnd((behindMs/3600000), 0, 1); | |
var aheadHourWeather = rnd((aheadMs/3600000), 0, 1); | |
var weatherDifference = aheadHourWeather-behindHourWeather; | |
var hourProgression = (serverTime-behindHour)/3600000; | |
var interpolationDelta = weatherDifference*hourProgression; | |
return behindHourWeather+interpolationDelta; | |
} | |
function getNextLightning() { | |
var weather = getNextWeather(); | |
var serverTime = getCurrentServerTime(); | |
var lightningOdds = ((0.1+(weather-0.9))/1.5); | |
serverTime=Math.round(serverTime/(1000*1)); | |
var random = rnd(serverTime, 0, 1); | |
if (random<=lightningOdds) | |
{ | |
var lightLevel = rnd(getCurrentServerTime(), -1.5, 0.8); | |
if (lightLevel<0) lightLevel = 0; | |
return lightLevel; | |
} | |
return 0; | |
} | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
// DISPLAY STATS | |
var StatDisplay = function() { | |
var charDiv = $('.character-display-box').children(" div:nth-child(3)").children( 'a' ); | |
var statsItems; | |
var statsID = ["S", "D", "I", "W"]; | |
var href = $( '.character-display-box').children().first().attr( "rel" ); | |
var init = function() { | |
$.ajax({ | |
url: href, | |
type: "GET", | |
success: function(data) { | |
statsItems = $(data).find('.main-item-subnote'); | |
statsItems.each(function( index ) { | |
if ( index > 0 ) { | |
charDiv.append( " <span style=\"font-size:small\"> " + | |
statsID[index - 1] + ":" + $( this ).text().split(" ")[0] + " </span>"); | |
} | |
}); | |
} | |
}); | |
}; | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
// ICONS | |
var ExtraIcons = function() { | |
// links to resources | |
var mapLink = "https://imgur.com/ZuUibeV"; | |
var changelogLink = "viewChangelog()"; | |
// filters to make the icons look different | |
// TODO make more cross-compatible | |
var greenFilter = "-webkit-filter: hue-rotate(50deg)"; | |
var blueFilter = "-webkit-filter: hue-rotate(100deg)"; | |
var init = function() { | |
// html to be inserted | |
var insertHTML = "<a href=\"" + mapLink + "\"><img id=\"community-map-image\"" + | |
"src=\"images/ui/settings.gif\" style=\"max-height:18px; " + | |
greenFilter + "\"></a>"; | |
$( '.header-stats' ).append( insertHTML ); | |
insertHTML = "<a onclick=\"" + changelogLink + "\">" + | |
"<img id=\"community-map-image\" src=\"images/ui/settings.gif\"" + | |
"style=\"max-height:18px; " + blueFilter + "\"></a>"; | |
$( '.header-stats' ).append( insertHTML ); | |
}; | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
// MUTE LIST | |
// TODO Make muteList and friendList persistent between sessions | |
var ChatPlus = function() { | |
// keep track of muted people in this list | |
var muteList = []; | |
// keep track of messages and times sent by people on friendlist | |
// store friends in friendList | |
var friendList = []; | |
// name time object for friend / userlist | |
var NameTimeObj = function(name) { | |
this.name = name; | |
this.time = ''; | |
}; | |
// adds the nickname to the list if it is a new name | |
var addName = function(list, name) { | |
if( isNewName(list, name) && name ) { | |
list.push(name); | |
} | |
}; | |
// removes the nickname from the list | |
var delName = function(list, name) { | |
var i = getIndex(list, name); | |
if (i !== undefined) { | |
list[i].remove(); | |
} | |
}; | |
// checks if the name is on the list already | |
var isNewName = function(list, name) { | |
return getIndex(list, name) === undefined; | |
}; | |
// returns the index of the name in list, null if it is not found | |
// TODO: Find a cleaner way to do distinguish between mutelist and NameTimeObj | |
var getIndex = function(list, name) { | |
for (var i = 0; i < list.length; i++) { | |
if (name.name === undefined) { | |
if (list[i] === name) { | |
return i; | |
} | |
} else if (list[i].name === name.name) { | |
return i | |
} | |
} | |
}; | |
// updates the timestamp for the friend given | |
var updateTime = function(name, time) { | |
var i = getIndex(friendList, name); | |
console.log( "i is " + i); | |
if (i !== undefined) { | |
console.log(name + " time is set to " + time); | |
friendList[i].time = time; | |
} | |
}; | |
// gets the timestamp for the name | |
// if name is not on the list return "N/A" | |
var getTime = function(name) { | |
var i = getIndex(friendList, name); | |
if (i !== undefined) { | |
return friendList[i].time; | |
} | |
}; | |
// verify the sender of message is the one playing the game | |
function myMessage( id ) { | |
var relStr = $( '.character-display-box' ).children( 'a' ).attr( 'rel' ).toString(); | |
var myId = relStr.substring(relStr.search( 'Id=') + 3); | |
if ( id == myId ) { | |
return true; | |
} | |
return false; | |
} | |
// gets time difference in multiples of 5 mins from time tied to name | |
// if it is over 60 min it will round to nearest hour | |
var getTimeDiff = function(time) { | |
// time difference | |
var timeDiffStr = ""; | |
var timeDiff = (new Date()).getTime() - time; | |
// convert to minutes | |
timeDiff = timeDiff/1000/60; | |
// round to nearest 5 minutes | |
timeDiff = Math.round(timeDiff/5)*5; | |
timeDiffStr = timeDiff + ' min'; | |
if (timeDiff >= 60) { | |
timeDiff = Math.round(timeDiff/60); | |
timeDiffStr = timeDiff + ' hr'; | |
} | |
return timeDiffStr; | |
}; | |
// crafts the HTML string for friendList DOM addition | |
var getUserElement = function(nameTimeObj) { | |
var HTML = ""; | |
var plainName = nameTimeObj.name.replace(/[\s+\[\]]/g, ''); | |
// if name is blank string, return without HTML | |
if (plainName === "") { | |
return HTML | |
} | |
// class name can't have spaces in it | |
HTML += '<span class="' + plainName + | |
'">' + nameTimeObj.name.substr(0,25) + '</span><span style="float:right">' + | |
getTimeDiff(nameTimeObj.time) + '</span>'; | |
HTML += "<br>" | |
return HTML; | |
}; | |
// adds name elements to the DOM as children to the UserListDiv | |
// TODO: make the css work based off of relative and not absolute values | |
// right now it's only likely to look good on my screen | |
var updateUserListDiv = function(nameTimeObjArr) { | |
nameTimeObjArr.sort(function(a, b) { | |
if (a.name < b.name) return -1; | |
else if (a.name > b.name) return 1; | |
else return 0; | |
}); | |
var HTML = "<center><h3>User List</h3></center>"; | |
nameTimeObjArr.forEach(function(entry) { | |
if (entry !== "") { | |
HTML += getUserElement(entry); | |
} | |
}); | |
$( '.user-list' ).html(HTML); | |
}; | |
var init = function() { | |
// adds UserList div to the DOM | |
$( '.mobile-spacer' ).append( '<div class="user-list page-popup" ' + | |
'style="width:20%; margin:0; padding-top:0px; top:60px;' + | |
'bottom:auto; display:inline-block; position:absolute; ' + | |
'z-index:1111111;"></div>' ); | |
// run function 2 seconds after pageload | |
var timerID = setTimeout(function() { | |
updateUserListDiv(friendList); | |
clearTimeout(timerID); | |
}, 1000*5); | |
// every five minutes update UserList Div | |
setInterval(function() { | |
updateUserListDiv(friendList); | |
}, 1000*60*5); | |
// overrides the default onChatMessage function | |
messager.onChatMessage = function(chatMessage) { | |
// gets nickname and gets rid of HTML | |
var nName = chatMessage.nickname.replace(/<()[^<]+>/g,''); | |
var nameTimeObj = new NameTimeObj(nName); | |
// add name to userlist | |
// TODO: Remove this | |
addName(friendList, nameTimeObj); | |
// if name is on muteList, hide the message | |
if (isNewName(muteList, nName) === false) { | |
return; | |
} | |
// check if mute command is sent | |
if (chatMessage.message.startsWith('/mute ')) { | |
// Am I the sender of the message? | |
if ( myMessage(chatMessage.characterId )) { | |
var muteName = chatMessage.message.substring(6); | |
// Don't let me mute myself, while funny it prevents any mute and unmute functionality | |
if ( nName != muteName ) { | |
addName(muteList, muteName); | |
} | |
} | |
} | |
// check if unmute command is sent | |
if (chatMessage.message.startsWith('/unmute ')) { | |
if( myMessage(chatMessage.characterId )) { | |
delName(muteList, chatMessage.message.substring(8)); | |
} | |
} | |
// check if add friend command is sent | |
if (chatMessage.message.startsWith('/add ')) { | |
// Don't mute based off of other people's messages | |
if ( myMessage(chatMessage.characterId )) { | |
var friendName = new NameTimeObj(chatMessage.message.substring(5)); | |
// Don't let me add myself, because that's silly | |
if ( nName != friendName ) { | |
addName(friendList, friendName); | |
} | |
} | |
} | |
// check if unadd command is sent | |
if (chatMessage.message.startsWith('/unadd ')) { | |
if( myMessage(chatMessage.characterId )) { | |
delName(friendList, chatMessage.message.substring(7)); | |
} | |
} | |
var html = "<div class='chatMessage-main'>"; | |
if (chatMessage.createdDate !== null) { | |
var date = new Date(chatMessage.createdDate); | |
var shortTime = date.toLocaleTimeString(); | |
var cutoff = shortTime.length; | |
// updates the timestamp in our userlist | |
updateTime(nameTimeObj, date.getTime()); | |
if (shortTime.indexOf(":")>0) { | |
cutoff = shortTime.lastIndexOf(":"); | |
} else if (shortTime.indexOf(".")>0) { | |
cutoff = shortTime.lastIndexOf("."); | |
} | |
shortTime = shortTime.substring(0, cutoff); | |
var longDate = date.toLocaleDateString(); | |
html+="<span class='chatMessage-time' title='"+longDate+"'>"; | |
html+="["+shortTime+"] "; | |
html+="</span>"; | |
} | |
if (chatMessage.code=="PrivateChat") { | |
html+="<a class='chatMessage-private-nickname' onclick='setPrivateChatTo(\""+chatMessage.nickname+"\", "+chatMessage.characterId+")'>"+chatMessage.nickname+"</a>"; | |
html+="<span class='chatMessage-text'>"; | |
html+=" "; | |
html+=chatMessage.message; | |
html+="</div>"; | |
} | |
else if (chatMessage.mode==null) | |
{ | |
var meMode = chatMessage.message.startsWith("/me "); | |
html+="<span class='chatMessage-text'>"; | |
if (chatMessage.characterId!=null && chatMessage.message.startsWith('/me ')) { | |
html += "<a class='clue' style='color:" + '#'+(Math.random()*0xFFFFFF<<0).toString(16) + "' rel='viewcharactermini.jsp?characterId=" + chatMessage.characterId + "'>" + chatMessage.nickname + ":</a>"; | |
} else if (chatMessage.characterId!=null && meMode==false) { | |
html+=chatMessage.nicknameStyled; | |
} else | |
html+=chatMessage.nickname; | |
html+="</span>"; | |
html+="<span class='chatMessage-text'>"; | |
if (meMode) | |
{ | |
html+=" "; | |
chatMessage.message = chatMessage.message.substring(4); | |
} | |
else | |
html+=": "; | |
html+=chatMessage.message; | |
html+="</div>"; | |
} | |
else if (chatMessage.mode=="admin") | |
{ | |
html+="<span class='chatMessage-text-story'>"; | |
html+=chatMessage.message; | |
html+="</div>"; | |
} | |
html+="</div>"; | |
$("#chat_messages_"+chatMessage.code).prepend(html); | |
notifyNewMessage(chatMessage.code); | |
}; | |
}; | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
// NEARBY ITEMS | |
var ItemList = function() { | |
var itemButton = $( '#main-itemlist' ).children(); | |
var init = function() { | |
// Get rid of current onClick behavior | |
itemButton.attr( 'onclick', ""); | |
itemButton.attr( 'rel', "ajax_moveitems.jsp?preset=location"); | |
// Give sticky cluetip on click | |
itemButton.cluetip({ | |
cluetipClass: 'rounded', | |
activation : 'click', | |
showTitle: true, | |
height: 'auto', | |
width: 350, | |
sticky: true, | |
closePosition: 'title', | |
arrows: true, | |
ajaxCache: false, | |
mouseOutClose: false, | |
cluezIndex: 2000000, | |
onShow: function(e) { | |
$("#cluetip-waitimage").css('z-index', 2000000); | |
$("#cluetip").css('z-index', 2000000); | |
return true; | |
}, | |
ajaxProcess : function(data) { | |
var text = itemParser(data); | |
var textArray = divSeparate(text); | |
var newText = ""; | |
for( var i = 0; i < textArray.length - 2; i++) { | |
newText = newText.concat(textArray[i].pop()); | |
newText = newText.concat("<br>"); | |
} | |
// add that last div back in | |
newText = newText.concat(textArray[textArray.length - 1]); | |
return newText; | |
} | |
}); | |
}; | |
// Parse the HTML data before sending it back to ajaxProcess | |
// this will only return the items on the ground in nearby area | |
function itemParser(text) { | |
var returnText = text; | |
returnText = returnText.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm,"").replace(/<(link|meta)[^>]+>/g,""); | |
returnText = returnText.slice(returnText.indexOf("id=\'right") + 11, returnText.length); | |
return returnText; | |
} | |
// Organizes duplicate items into a stack with most valuable items being on the top of the stack | |
// cluetip will pop the stacks of duplicate items from a stack (stack of dupe item stacks) | |
// Separates divs array into arrays of unique types of items | |
function divSeparate(text) { | |
var newText = text.split("<br>"); | |
var uniqItemStack = new Array([]); | |
var uniqItemNameStack = []; | |
// save the last entry from div organization | |
var lastDiv = newText.pop(); | |
uniqItemNameStack = getNames(newText); | |
// 2D array construction | |
uniqItemNameStack.forEach(function(entry, ind) { | |
uniqItemStack.push(new Array()); | |
}); | |
// foreach | |
newText.forEach(function(entry, ind) { | |
var itemNameBegLoc = entry.search("main-item-name\'>"); | |
// exclude search string from result | |
itemNameBegLoc += "main-item-name\'>".length; | |
var itemNameEndLoc = entry.search("</div></a>"); | |
var itemName = entry.substring(itemNameBegLoc, itemNameEndLoc); | |
var index = 0; | |
// if item name is in uniqItemStackNames | |
// get index of uniqItemStackNames.equals(itemName) | |
index = getIndex(itemName); | |
// push the item onto the correct stack | |
uniqItemStack[index].push(entry); | |
}); | |
// push back on the lastDiv | |
uniqItemStack.push(lastDiv); | |
return uniqItemStack; | |
//Misc. Functions | |
// gets Index of value in array, if no value in the array returns -1 | |
function getIndex(name) { | |
var index = -1; | |
uniqItemNameStack.forEach(function(entry, ind) { | |
if (name == entry) { | |
index = ind; | |
} | |
}); | |
return index; | |
} | |
function getNames(divStack) { | |
var itemNameStack = []; | |
divStack.forEach(function(entry, ind) { | |
var itemNameBegLoc = entry.search("main-item-name\'>"); | |
// exclude search string from result | |
itemNameBegLoc += "main-item-name\'>".length; | |
var itemNameEndLoc = entry.search("</div></a>"); | |
var itemName = entry.substring(itemNameBegLoc, itemNameEndLoc); | |
var boolAdd = true; | |
if (ind === 0) { | |
itemNameStack.push(itemName); | |
} else { | |
itemNameStack.forEach(function(entry) { | |
if (itemName == entry) { | |
boolAdd = false; | |
} | |
}); | |
} | |
if (boolAdd && ind > 0) { | |
itemNameStack.push(itemName); | |
} | |
}); | |
return itemNameStack; | |
} | |
} | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
// NO REFRESH | |
var NoRefresh = function() { | |
var init = function() { | |
$( '.main-page' ).last().append( '<div class="combat-text"> </div>' ); | |
var buttonRight = $( '.main-button' ).first(); | |
var buttonLeft = $( '.main-button' ).first().next(); | |
var linkArr = []; | |
linkArr.push(buttonRight.attr( "href")); | |
linkArr.push(buttonLeft.attr( "href" )); | |
// disables href redirect for first 2 buttons | |
buttonRight.removeAttr( "href" ); | |
buttonLeft.removeAttr( "href" ); | |
// on click calls the get data function | |
buttonRight.click( function() { | |
getData(linkArr[0]); | |
}); | |
buttonLeft.click( function() { | |
getData(linkArr[1]); | |
}); | |
}; | |
// gets the data from the actionURL | |
function getData(actionURL) { | |
$.get(actionURL) | |
.done(function(data) { | |
processData(data); | |
}); | |
} | |
// Gets the hp values and the battle description from the returned data | |
function processData(data) { | |
var $data = $(data); | |
var $mainPageDiv = $data.filter( '.main-page' ).last(); | |
var $hpObj = $mainPageDiv.find( '.character-display-box' ).children( 'div' ).children( 'div' ).children( 'p' ); | |
// gets the new hps | |
var playerHP = $hpObj.first().text(); | |
var enemyHP = $hpObj.last().text(); | |
// gets the new combat text | |
var combatHTML = parseCombatHTML($mainPageDiv.html()); | |
// if either the player or the enemy is dead call for refresh | |
// because of the way the HTML works if the enemy HP div is missing | |
// it will use the same div for both objects | |
if( playerHP === enemyHP ) { fullpageRefresh(); } | |
// data is processed, now update the relevant divs | |
updateCombat(playerHP, enemyHP, combatHTML); | |
} | |
// parses HTML and gets the combat related HTML | |
function parseCombatHTML( html ){ | |
html = html.slice(html.indexOf( "<p>\n\t" )); | |
return html; | |
} | |
// updates the HTML elements on the current page with the values | |
function updateCombat(newPlayerHP, newEnemyHP, combatHTML) { | |
var $hpObj = $( '.character-display-box' ).children( 'div' ).children( 'div' ); | |
var playerHP = $hpObj.children( 'p' ).first(); | |
var enemyHP = $hpObj.children( 'p' ).last(); | |
var newPlayerHPBarWidth = parseInt(parseFloat(newPlayerHP) / parseFloat( newPlayerHP.slice(newPlayerHP.indexOf("/") + 1)) * 100); | |
var newEnemyHPBarWidth = parseInt(parseFloat(newEnemyHP) / parseFloat( newEnemyHP.slice(newEnemyHP.indexOf("/") + 1)) * 100); | |
$hpObj.children().first().width( newPlayerHPBarWidth + "px" ); | |
$hpObj.children().last().prev().width( newEnemyHPBarWidth + "px" ); | |
playerHP.text( newPlayerHP ); | |
enemyHP.text( newEnemyHP ); | |
$( '.combat-text' ).html( combatHTML ); | |
} | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
// STATS TRACKING | |
var TrackStats = function() { | |
var characterName = $( '.character-display-box' ).children( 'div' ).children('a').first().text(); | |
var enabled = false; | |
var saved = false; | |
var prevStats = JSON.parse( GM_getValue(characterName, "[]") ); | |
var dbLength = prevStats.length; | |
var href = $( '.character-display-box').children().first().attr( "rel" ); | |
var clickOnceOnly = 0; | |
//Check if character is enabled for tracking. | |
var settings = JSON.parse( GM_getValue("initium_counter_settings", "[]") ); | |
var init = function () { | |
settings.forEach(function(char) { | |
if(char.name == characterName) { | |
saved = true; | |
enabled = char.enabled; | |
} | |
}); | |
//If never seen before, character will be added as disabled. | |
if (!saved) { | |
var newSetting = { | |
"name":characterName, | |
"enabled":false | |
}; | |
settings.push(newSetting); | |
GM_setValue("initium_counter_settings", JSON.stringify(settings)); | |
saved = true; | |
} | |
//Add icon to icon bar and bind to toggle function | |
if (enabled) { | |
//Can add <div class="header-stats-caption">Counter</div> inside a tag underneath for caption. | |
var htmlString = '<div style="display:inline-block; cursor: pointer;" id="statCounter"><img style="padding: 0 0 3px;" src="https://s3.amazonaws.com/imappy/3d_bar_chart.png" border="0/"></div>'; | |
} else { | |
var htmlString = '<div style="display:inline-block; cursor: pointer;" id="statCounter"><img style="padding: 0 0 3px;" src="https://s3.amazonaws.com/imappy/3d_bar_chart_off.png" border="0/"></div>'; | |
} | |
$(".header-stats").prepend(htmlString); | |
$("#statCounter").click(showTracker); | |
addTracking(); | |
// Press | to show the stats saved for this character in a popup. | |
$(document).on("keydown", function(event) { | |
if (event.which == 220) { | |
if ($(':focus').length > 0) { | |
if (!($(':focus')[0].localName == "input")) { | |
showTracker(); | |
} | |
} else { | |
showTracker(); | |
} | |
} | |
}); | |
}; | |
//Function to toggle enabled/disabled for current character | |
function toggleCounter() { | |
enabled = !enabled; | |
var settings = JSON.parse( GM_getValue("initium_counter_settings", "[]") ); | |
settings.forEach(function(char) { | |
if(char.name == characterName) { | |
char.enabled = enabled; | |
} | |
}); | |
//Switch out picture | |
if(enabled) { | |
$("#statCounter")[0].children[0].src = "https://s3.amazonaws.com/imappy/3d_bar_chart.png"; | |
$("#statEnabler").text("Disable"); | |
} else { | |
$("#statCounter")[0].children[0].src = "https://s3.amazonaws.com/imappy/3d_bar_chart_off.png"; | |
$("#statEnabler").text("Enable"); | |
} | |
GM_setValue("initium_counter_settings", JSON.stringify(settings)); | |
} | |
//Add Stat Tracking logic | |
function addTracking() { | |
var currentURL = window.location.href; | |
// if not on combat page, do not execute | |
if ( !currentURL.includes('combat.js') ) { | |
return; | |
} | |
currentURL = currentURL.substring(0, currentURL.indexOf('combat.js')); | |
// attack buttons | |
var attackButton1 = $('.main-buttonbox a')[0]; | |
var attackButton2 = $('.main-buttonbox a')[1]; | |
// attack urls | |
var attackRightHandURL = currentURL + 'ServletCharacterControl?type=attack&hand=RightHand'; | |
var attackLeftHandURL = currentURL + 'ServletCharacterControl?type=attack&hand=LeftHand'; | |
// remove current click listener | |
$(attackButton1).removeAttr( 'shortcut'); | |
$(attackButton2).removeAttr( 'shortcut'); | |
// add click listener | |
$(attackButton1).on("click", { atkurl : attackRightHandURL }, tracking); | |
$(attackButton2).on("click", { atkurl : attackLeftHandURL }, tracking); | |
} | |
function tracking(event) { | |
//Increment clickOnce counter | |
clickOnceOnly++; | |
if ( clickOnceOnly == 1 ) { | |
if (enabled) { | |
//Add stat counter status | |
$(".main-buttonbox").append('<div style="text-align: center;" id="stat-counter-status">Status: Fetching stats..</div>'); | |
$.ajax({ | |
url: href, | |
type: "GET", | |
timeout: 2000, | |
//If successful, get stats and redirect | |
success: function(charPage) { | |
var statsDiv = $(charPage).find('.main-item-subnote'); | |
var stats = dbLength+" "; | |
statsDiv.each(function( index ) { | |
if ( index > 0 && index < 4) { | |
stats += $( this ).text().split(" ")[0] + " "; | |
} | |
}); | |
gm_store("stats", characterName, stats); | |
$(".main-buttonbox #stat-counter-status").text("Status: Success. Redirecting.."); | |
window.location.href = event.data.atkurl; | |
}, | |
//If not successful or 2s passed(assume disconnect), update status and stop | |
error: function(xhr, textStatus, errorThrown){ | |
clickOnceOnly = 0; | |
$(".main-buttonbox #stat-counter-status").text("Status: Failed fetching stats. Aborting attack. Try again."); | |
} | |
}); | |
} else { | |
window.location.href = event.data.atkurl; | |
} | |
} | |
} | |
function showTracker() { | |
var popTitle = "<center><h3>Stat Tracker for "+characterName+"</h3></center>"; | |
var popContent = ""; | |
var nextState = ""; | |
if(enabled) { | |
nextState = "Disable"; | |
} else { | |
nextState = "Enable"; | |
} | |
popContent += '<div class="main-button-half" id="statEnabler" ' + | |
'style="margin: 0 5% 0 5%; width: 40%; display: inline-block; ' + | |
'line-height: 24px" shortcut="86">' + nextState + '</div>' + | |
'<div class="main-button-half" id="statCleaner" ' + | |
'style="margin: 0 5% 0 5%; width: 40%; display: inline-block; ' + | |
'line-height: 24px" shortcut="86">Clear</div>' + | |
'\n\n<center><h3>Saved stats:</h3></center>'; | |
var savedStats = JSON.parse( GM_getValue(characterName, "[]") ); | |
$.each(savedStats.reverse(), function(index,stat) { | |
popContent += "<center>"+stat+"</center>"; | |
}); | |
Util.mkPopup(popTitle + popContent); | |
$("#statCleaner").click(clearStats); | |
$("#statEnabler").click(toggleCounter); | |
} | |
//Prints saved stats from database to console | |
function printStats(){ | |
console.log("Stats for " + characterName + ":"); | |
var savedStats = JSON.parse(GM_getValue(characterName, "[]")); | |
savedStats.forEach(function(stat) { | |
console.log(stat); | |
}); | |
} | |
//Clears stats in database for current character | |
function clearStats(){ | |
if (confirm('You sure you want to delete the stats saved for '+characterName+'?')) { | |
GM_setValue(characterName, "[]"); | |
closePagePopup(); | |
showTracker(); | |
} | |
} | |
//Inserts into database | |
function gm_store(dataname, charname, data) { | |
if (dataname === "stats") { | |
var stats = JSON.parse( GM_getValue(charname, "[]") ); | |
stats.push(data); | |
GM_setValue(charname, JSON.stringify(stats)); | |
console.log("Added "+data+" to "+charname); | |
} | |
} | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
//-----------------------CONFIG-----------------\\ | |
/* | |
displays checkboxes to enable or disable each script | |
accessed by pressing the letter c, or typing /config in chat | |
*/ | |
// CONFIG | |
// init(); | |
var Config = function() { | |
// string for database access | |
var dbConfigString = "configString"; | |
var dbConfigStringVal = ""; | |
// name of all scripts / features to be enabled | |
var scriptNames = [ "Debuff", "StatDisplay", "ExtraIcons", "ChatPlus", | |
"NoRefresh", "TrackStats", "WeatherForecast", | |
"ItemList" ]; | |
var scriptObjects = [ Debuff, StatDisplay, ExtraIcons, ChatPlus, | |
NoRefresh, TrackStats, WeatherForecast, | |
ItemList ]; | |
// changes dbConfigStringVal + updates database when there is a change | |
var addChangeListener = function( id ) { | |
// we had to use some clever str concatenation because strings are immutable | |
$( id ).change( function() { | |
var boxId = $( this ).attr( "id" ); | |
var index = parseInt(boxId[boxId.length - 1]); | |
if ( this.checked ) { | |
dbConfigStringVal = dbConfigStringVal.substr(0, index) + 'y' + dbConfigStringVal.substr(index + 1); | |
} else { | |
dbConfigStringVal = dbConfigStringVal.substr(0, index) + 'n' + dbConfigStringVal.substr(index + 1); | |
} | |
GM_setValue(dbConfigString, dbConfigStringVal); | |
}); | |
}; | |
// adds a checkbox to popContent string which will be used to make menu | |
// name should begin with capital letter for style purposes | |
var makeCheckboxHTML = function(name, isEnabled) { | |
var nameWithoutNumber = name.substring(0, name.length - 1); | |
var HTML = '<div class="setting-entry setting-entry-checkbox">' + | |
'<input type="checkbox" id="checkbox' + name + '" '; | |
if (isEnabled) { | |
HTML += 'checked'; | |
} | |
HTML += '>' + 'Enable' + nameWithoutNumber + '</div>'; | |
return HTML; | |
}; | |
// true if the character at index of configString is a y | |
// meaning the user enabled that script in config popup | |
var checkEnabled = function(index) { | |
return dbConfigStringVal[index] === 'y'; | |
}; | |
// sets database string to enable the default scripts | |
var setToDefault = function() { | |
dbConfigStringVal = "yynynyyn"; | |
GM_setValue(dbConfigString, dbConfigStringVal); | |
}; | |
// enables scripts based on dbConfigStringVal | |
var enableScripts = function() { | |
scriptObjects.forEach( function( entry, index) { | |
if (checkEnabled(index)) { | |
entry.init(); | |
} | |
}); | |
}; | |
// makes the config Popup | |
var showConfigMenu = function() { | |
var popTitle = "<center><h2>Initium+ Configuration</h3></center>" + | |
"<center><h5>v" + Util.version + "</h5></center>"; | |
var popSubText = "<center><h5>You will need to refresh the webpage " + | |
"for the changes to take effect. Press C to bring up this menu.</h5></center>"; | |
var popContent = ""; | |
// add checkboxes for all main features, index keeps track | |
// of place of scripts in array and in dbConfigStringVal | |
scriptNames.forEach( function(entry, index) { | |
popContent += makeCheckboxHTML(entry + index, checkEnabled(index)); | |
}); | |
// add content to the popup and show it | |
Util.mkPopup( popTitle + popSubText + popContent ); | |
for (var i = 0; i < scriptNames.length; i++) { | |
addChangeListener( "#checkbox" + scriptNames[i] + i); | |
} | |
// reset popContent | |
popContent = ""; | |
}; | |
var init = function() { | |
// get the value of db string, if empty set to default | |
dbConfigStringVal = GM_getValue(dbConfigString); | |
if ( !dbConfigStringVal || dbConfigStringVal.length !== 8 ) { | |
setToDefault(); | |
showConfigMenu(); | |
} | |
enableScripts(); | |
// Press | to show the stats saved for this character in a popup. | |
$(document).on("keydown", function(event) { | |
if (event.which == 99 || event.which == 67) { | |
if ($(':focus').length > 0) { | |
if (!($(':focus')[0].localName == "input")) { | |
showConfigMenu(); | |
} | |
} else { | |
showConfigMenu(); | |
} | |
} | |
}); | |
}; | |
var oPublic = { | |
init: init, | |
}; | |
return oPublic; | |
}(); | |
Config.init(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment