Equips skin, gear, and abilities in configurable sets
目前為
// ==UserScript== // @name Eternity Tower Quick Sets // @icon https://www.eternitytower.net/favicon.png // @namespace http://mean.cloud/ // @version 1.11 // @description Equips skin, gear, and abilities in configurable sets // @match http*://*.eternitytower.net/* // @author [email protected] // @copyright 2017-2018, MeanCloud // @run-at document-end // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // ==/UserScript== //////////////////////////////////////////////////////////////// ////////////// ** SCRIPT GLOBAL INITIALIZATION ** ////////////// function startup() { ET_QuickSetsMod(); } PETQS_EquippedItems = []; PETQS_EquippedAbilities = []; PETQS_AllItems = []; PETQS_PageOn = 1; PETQS_PageMax = 10; PETQS_SetsPerPage = 8; //////////////////////////////////////////////////////////////// ET_QuickSetsMod = function() { //ET.MCMF.WantDebug = true; ET.MCMF.Ready(function() { Package.meteor.Meteor.connection._stream.on('message', function(sMeteorRawData) { try { var oMeteorData = JSON.parse(sMeteorRawData); //todo: use Package.meteor.global.Accounts.connection._stores.abilities._getCollection()._collection try { if (oMeteorData.collection == "abilities") { if (oMeteorData.fields && oMeteorData.fields.learntAbilities) { PETQS_EquippedAbilities = []; jQ.makeArray(oMeteorData.fields.learntAbilities).forEach(function(oAbility, index, array) { try { if (oAbility.equipped) PETQS_EquippedAbilities.push(oAbility); } catch (err) { console.log("Error with PETQS/ability: " + err); } }); } } } catch (err) { console.log("Error with PETQS/abilities: " + err); } //todo: Package.meteor.global.Accounts.connection._stores.items._getCollection()._collection try { if (oMeteorData.collection == "items") { if (oMeteorData.msg == "added") if (oMeteorData.fields && oMeteorData.fields.itemId && oMeteorData.fields.name && oMeteorData.fields.category) PETQS_AllItems.push(oMeteorData); if (oMeteorData.fields && oMeteorData.fields.equipped) { PETQS_EquippedItems.push(oMeteorData); } else { if (PETQS_EquippedItems.length > 0) { for (i = 0; i < PETQS_EquippedItems.length; i++) { if (PETQS_EquippedItems[i].id == oMeteorData.id) { PETQS_EquippedItems.splice(i, 1); break; } } } } } } catch (err) { console.log("Error with PETQS/items: " + err); } } catch (err) { console.log("Error with PETQS/meteor: " + err); } }); }); ET.MCMF.Loaded(function() { PETQS_PageOn = CInt(GM_getValue("PETQS_Page")); if (PETQS_PageOn === 0) PETQS_PageOn = 1; PETQS_TestUI(); }, "ETQS"); }; PETQS_TestUI = function() { try { if (jQ("div#PETQS_UI").length === 0) if (jQ("div.hidden-lg-down").length > 0) PETQS_CreateUI(); } catch (err) { } setTimeout(PETQS_TestUI, 1000); }; PETQS_CreateUI = function() { jQ("div#PETQS_UI").remove(); jQ(jQ("div.hidden-lg-down").children("div").get(0)).append ( "<div style=\"margin-top: 20px; border: 1px solid #dde; background-color: #fafbfd; padding: 5px; width: 280px; font-size: 14px;\" id=\"PETQS_UI\">" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer;\" id=\"PETQS_Slotbar" + pad(1 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (1 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer;\" id=\"PETQS_Slotbar" + pad(2 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (2 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer;\" id=\"PETQS_Slotbar" + pad(3 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (3 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer; margin-bottom: 4px;\" id=\"PETQS_Slotbar" + pad(4 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (4 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer; border-top: 1px solid #dde;\" id=\"PETQS_Slotbar" + pad(5 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (5 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer;\" id=\"PETQS_Slotbar" + pad(6 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (6 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer;\" id=\"PETQS_Slotbar" + pad(7 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (7 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; height: 22px; cursor: pointer;\" id=\"PETQS_Slotbar" + pad(8 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage), 2) + "\" onclick=\"javascript:PETQS_ClickedSet(" + (8 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ",event);\">[empty set]</div>" + "<div style=\"width: 270px; max-width: 270px; padding-top: 10px;\">" + "<input type=\"button\" value=\"Save #" + (1 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (1 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /> " + "<input type=\"button\" value=\"Save #" + (2 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (2 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /> " + "<input type=\"button\" value=\"Save #" + (3 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (3 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /> " + "<input type=\"button\" value=\"Save #" + (4 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (4 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /><br />" + "<input type=\"button\" value=\"Save #" + (5 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (5 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /> " + "<input type=\"button\" value=\"Save #" + (6 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (6 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /> " + "<input type=\"button\" value=\"Save #" + (7 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (7 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /> " + "<input type=\"button\" value=\"Save #" + (8 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + "\" onclick=\"javascript:PETQS_SaveSet(" + (8 + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)).toFixed(0) + ");\" style=\"display: inline-block; width: 64px; font-size: 12px;\" /><br />" + "<input type=\"button\" value=\"< Prev Page\" onclick=\"javascript:PETQS_PageChange(-1);\" style=\"display: inline-block; width: 132px; font-size: 12px;\" /> " + "<input type=\"button\" value=\"Next Page >\" onclick=\"javascript:PETQS_PageChange(1);\" style=\"display: inline-block; width: 132px; font-size: 12px;\" /><br />" + "</div>" + "</div>" ); for (iSlot = 1; iSlot <= PETQS_SetsPerPage; iSlot++) PETQS_LoadSet(iSlot + ((PETQS_PageOn - 1) * PETQS_SetsPerPage)); }; PETQS_PageChange = function(iAmt) { PETQS_PageOn += iAmt; if (PETQS_PageOn <= 0) PETQS_PageOn = PETQS_PageMax; if (PETQS_PageOn > PETQS_PageMax) PETQS_PageOn = 1; GM_setValue("PETQS_Page", PETQS_PageOn.toString()); PETQS_CreateUI(); }; PETQS_UpdateSetTooltip = function(iSlot, bEmpty) { oEl = jQ("#PETQS_Slotbar" + pad(iSlot, 2)).get(0); if (!oEl) return; if (oEl._tippy) oEl._tippy.destroy(); jQ("#tooltip-PETQS_Slotbar" + pad(iSlot, 2)).remove(); jQ("body").append("<div class=\"item-tooltip-content my-tooltip-inner\" id=\"tooltip-PETQS_Slotbar" + pad(iSlot, 2) + "\"></div>"); if (bEmpty) { jQ("#tooltip-PETQS_Slotbar" + pad(iSlot, 2)).html ( " <h3 class=\"popover-title\">" + " " + (GM_getValue("PETQS_Name" + pad(iSlot, 2)) || "Quick Set #" + iSlot.toFixed(0)) + " </h3>" + " <div class=\"popover-content\">" + " set #" + iSlot.toFixed(0) + "<br />" + " this set is empty" + " </div>" ); } else { jQ("#tooltip-PETQS_Slotbar" + pad(iSlot, 2)).html ( " <h3 class=\"popover-title\">" + " " + (GM_getValue("PETQS_Name" + pad(iSlot, 2)) || "Quick Set #" + iSlot.toFixed(0)) + " </h3>" + " <div class=\"popover-content\">" + " set #" + iSlot.toFixed(0) + "<br />" + " <b>Left Click</b> to equip this set<br />" + " <b>Shift Click</b> to rename this set<br />" + " <b>Control Click</b> to delete this set" + " </div>" ); } tippy("#PETQS_Slotbar" + pad(iSlot, 2), { html: jQ("#tooltip-PETQS_Slotbar" + pad(iSlot, 2))[0], performance: !0, animateFill: !1, distance: 5 }); }; PETQS_ClickedSet = function(iSlot, e) { var bShiftPressed = false; var bCtrlPressed = false; try { if (e !== null) { if (e.shiftKey) bShiftPressed = true; if (e.ctrlKey) bCtrlPressed = true; } } catch (err) { } if (bShiftPressed) { var sSetName = prompt("Enter a new name for this set:", GM_getValue("PETQS_Name" + pad(iSlot, 2)) || "Quick Set #" + iSlot.toFixed(0)); if (sSetName !== null) { GM_setValue("PETQS_Name" + pad(iSlot, 2), sSetName.trim()); PETQS_LoadSet(iSlot); } } else if (bCtrlPressed) { if (confirm("Really delete set #" + iSlot.toFixed(0) + " (\"" + (GM_getValue("PETQS_Name" + pad(iSlot, 2)) || "Quick Set #" + iSlot.toFixed(0)) + "\")?")) { GM_deleteValue("PETQS_Name" + pad(iSlot, 2)); GM_deleteValue("PETQS_QS" + pad(iSlot, 2)); jQ("div#PETQS_Slotbar" + pad(iSlot, 2)).html("[empty set]"); PETQS_UpdateSetTooltip(iSlot, true); } } else PETQS_LoadSet(iSlot, true); }; PETQS_SkinEquipped = function() { return Package.meteor.global.Accounts.connection._stores.combat._getCollection()._collection._docs._map[ET.MCMF.CombatID].characterIcon; }; PETQS_SaveSet = function(iSlot) { var sSetting = ""; sSetting += "skin&&" + PETQS_SkinEquipped() + "||"; try { jQ.makeArray(PETQS_EquippedItems).forEach(function(oEquippedItem, index, array) { //console.log(oEquippedItem); try { var oEquippedItemToUse = oEquippedItem; if (!oEquippedItem.fields.category) { jQ.makeArray(PETQS_AllItems).forEach(function(oThisItem, index2, array2) { if ((oThisItem.id === oEquippedItem.id) && (oThisItem.fields.category)) { oEquippedItemToUse = oThisItem; //console.log("--> ", oEquippedItemToUse); } }); } sSetting += "item&&" + oEquippedItemToUse.id + "&&" + oEquippedItemToUse.fields.itemId + "&&" + oEquippedItemToUse.fields.name + "&&" + (oEquippedItem.fields.slot ? oEquippedItem.fields.slot : oEquippedItemToUse.fields.slot) + "&&" + oEquippedItemToUse.fields.icon + "&&" + (oEquippedItemToUse.fields.quality ? oEquippedItemToUse.fields.quality.toFixed(0) : "-1") + "&&" + (oEquippedItemToUse.fields.enhanced ? "E" : "X") + "||"; } catch (err) { console.log("Error with PETQS/saveItem: " + err); } }); } catch (err) { console.log("Error with PETQS/saveItems: " + err); } try { jQ.makeArray(PETQS_EquippedAbilities).forEach(function(oEquippedAbility, index, array) { //console.log(oEquippedAbility); try { sSetting += "ability&&" + oEquippedAbility.abilityId + "&&" + oEquippedAbility.name + "&&" + oEquippedAbility.slot + "&&" + oEquippedAbility.icon + "||"; } catch (err) { console.log("Error with PETQS/saveAbility: " + err); } }); } catch (err) { console.log("Error with PETQS/saveAbilities: " + err); } //console.log("Save: PETQS_QS" + pad(iSlot, 2) + " = " + sSetting); GM_setValue("PETQS_QS" + pad(iSlot, 2), sSetting); PETQS_LoadSet(iSlot); }; PETQS_LoadSet = function(iSlot, bEquip = false) { var sRawSetting = GM_getValue("PETQS_QS" + pad(iSlot, 2)) || ""; //console.log("Load: " + sRawSetting); if (sRawSetting === "") { PETQS_UpdateSetTooltip(iSlot, true); return; } var sSettingLines = jQ.makeArray(sRawSetting.split("||")); var sHotbarHTML = ""; const sImageSize = "22px"; if (bEquip) { Package.meteor.Meteor.connection._send({"msg":"method","method":"abilities.unequip","params":["head"],"id":"-1"}); Package.meteor.Meteor.connection._send({"msg":"method","method":"abilities.unequip","params":["chest"],"id":"-1"}); Package.meteor.Meteor.connection._send({"msg":"method","method":"abilities.unequip","params":["offHand"],"id":"-1"}); Package.meteor.Meteor.connection._send({"msg":"method","method":"abilities.unequip","params":["mainHand"],"id":"-1"}); Package.meteor.Meteor.connection._send({"msg":"method","method":"abilities.unequip","params":["legs"],"id":"-1"}); var equipmentCopy = PETQS_EquippedItems.slice(); if (equipmentCopy.length > 0) for (i = 0; i < equipmentCopy.length; i++) if (equipmentCopy[i].fields.category != "mining") Package.meteor.Meteor.connection._send({"msg":"method","method":"items.unequip","params":[equipmentCopy[i].id,equipmentCopy[i].fields.itemId],"id":"-1"}); } // look for skins first sSettingLines.forEach(function(sSettingLine, index, array) { try { var sSettingVals = jQ.makeArray(sSettingLine.split("&&")); if (sSettingVals[0] == "skin") { //console.log("skin: " + sSettingVals[1]); sHotbarHTML += "<img src=\"/icons/" + sSettingVals[1] + "\" class=\"extra-small-icon\" style=\"width: " + sImageSize + "; height: " + sImageSize + "; padding: 0px; margin: 0px; border: none;\" />"; if (bEquip) { //todo: use Package.meteor.global.Accounts.connection._stores.skins._getCollection()._collection if (sSettingVals[1] == "mageT1HD.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["mage_t1"],"id":"-1"}); if (sSettingVals[1] == "mageT2HD.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["mage_t2"],"id":"-1"}); if (sSettingVals[1] == "damageT1HD.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["damage_t1"],"id":"-1"}); if (sSettingVals[1] == "damageT2HD.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["damage_t2"],"id":"-1"}); if (sSettingVals[1] == "tankT1HD.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["tank_t1"],"id":"-1"}); if (sSettingVals[1] == "tankT2HD.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["tank_t2"],"id":"-1"}); if (sSettingVals[1] == "phoenixT1.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["phoenix_t1"],"id":"-1"}); if (sSettingVals[1] == "phoenixT2.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["phoenix_t2"],"id":"-1"}); if (sSettingVals[1] == "crowT1.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["crow_t1"],"id":"-1"}); if (sSettingVals[1] == "crowT2.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["crow_t2"],"id":"-1"}); if (sSettingVals[1] == "vallaT1.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["valla_t1"],"id":"-1"}); if (sSettingVals[1] == "adalgarT1.png") Package.meteor.Meteor.connection._send({"msg":"method","method":"combat.updateCharacterIcon","params":["adalgar_t1"],"id":"-1"}); } } } catch (err) { } }); // look for gear for (i = 1; i <= 6; i++) { sSettingLines.forEach(function(sSettingLine, index, array) { try { var sSettingVals = jQ.makeArray(sSettingLine.split("&&")); if (sSettingVals[0] == "item") { if ((i == 1) && (sSettingVals[4] != "mainHand")) return; if ((i == 2) && (sSettingVals[4] != "offHand")) return; if ((i == 3) && (sSettingVals[4] != "head")) return; if ((i == 4) && (sSettingVals[4] != "neck")) return; if ((i == 5) && (sSettingVals[4] != "chest")) return; if ((i == 6) && (sSettingVals[4] != "legs")) return; //console.log("item: " + sSettingVals[3]); sHotbarHTML += "<img src=\"/icons/" + sSettingVals[5] + "\" class=\"extra-small-icon\" style=\"width: " + sImageSize + "; height: " + sImageSize + "; padding: 0px; margin: 0px; border: none;\" />"; if (bEquip) Package.meteor.Meteor.connection._send({"msg":"method","method":"items.equip","params":[sSettingVals[1],sSettingVals[2]],"id":"-1"}); } } catch (err) { } }); } // look for abilities for (i = 1; i <= 5; i++) { sSettingLines.forEach(function(sSettingLine, index, array) { try { var sSettingVals = jQ.makeArray(sSettingLine.split("&&")); if (sSettingVals[0] == "ability") { if ((i == 1) && (sSettingVals[3] != "mainHand")) return; if ((i == 2) && (sSettingVals[3] != "offHand")) return; if ((i == 3) && (sSettingVals[3] != "head")) return; if ((i == 4) && (sSettingVals[3] != "chest")) return; if ((i == 5) && (sSettingVals[3] != "legs")) return; //console.log("ability: " + sSettingVals[2]); sHotbarHTML += "<img src=\"/icons/" + sSettingVals[4] + "\" class=\"extra-small-icon\" style=\"width: " + sImageSize + "; height: " + sImageSize + "; padding: 0px; margin: 0px; border: none;\" />"; if (bEquip) Package.meteor.Meteor.connection._send({"msg":"method","method":"abilities.equip","params":[sSettingVals[1]],"id":"-1"}); } } catch (err) { } }); } jQ("div#PETQS_Slotbar" + pad(iSlot, 2)).html(sHotbarHTML); PETQS_UpdateSetTooltip(iSlot, false); }; //////////////////////////////////////////////////////////////// /////////////// ** common.js -- DO NOT MODIFY ** /////////////// time_val = function() { return CDbl(Math.floor(Date.now() / 1000)); }; IsValid = function(oObject) { if (oObject === undefined) return false; if (oObject === null) return false; return true; }; Random = function(iMin, iMax) { return parseInt(iMin + Math.floor(Math.random() * iMax)); }; ShiftClick = function(oEl) { if (oEl === undefined) { var shiftclick = jQ.Event("click"); shiftclick.shiftKey = true; var shiftclickOrig = jQ.Event("click"); shiftclickOrig.shiftKey = true; shiftclick.originalEvent = shiftclick; return shiftclick; } jQ(oEl).trigger(ShiftClick()); }; if (!String.prototype.replaceAll) String.prototype.replaceAll = function(search, replace) { return ((replace === undefined) ? this.toString() : this.replace(new RegExp('[' + search + ']', 'g'), replace)); }; if (!String.prototype.startsWith) String.prototype.startsWith = function(search, pos) { return this.substr(((!pos) || (pos < 0)) ? 0 : +pos, search.length) === search; }; CInt = function(v) { try { if (!isNaN(v)) return Math.floor(v); if (typeof v === 'undefined') return parseInt(0); if (v === null) return parseInt(0); var t = parseInt(v); if (isNaN(t)) return parseInt(0); return Math.floor(t); } catch (err) { } return parseInt(0); }; CDbl = function(v) { try { if (!isNaN(v)) return parseFloat(v); if (typeof v === 'undefined') return parseFloat(0.0); if (v === null) return parseFloat(0.0); var t = parseFloat(v); if (isNaN(t)) return parseFloat(0.0); return t; } catch (err) { } return parseFloat(0.0); }; // dup of String.prototype.startsWith, but uses indexOf() instead of substr() startsWith = function (haystack, needle) { return (needle === "") || (haystack.indexOf(needle) === 0); }; endsWith = function (haystack, needle) { return (needle === "") || (haystack.substring(haystack.length - needle.length) === needle); }; ChopperBlank = function (sText, sSearch, sEnd) { var sIntermediate = ""; if (sSearch === "") sIntermediate = sText.substring(0, sText.length); else { var iIndexStart = sText.indexOf(sSearch); if (iIndexStart === -1) return ""; sIntermediate = sText.substring(iIndexStart + sSearch.length); } if (sEnd === "") return sIntermediate; var iIndexEnd = sIntermediate.indexOf(sEnd); return (iIndexEnd === -1) ? sIntermediate : sIntermediate.substring(0, iIndexEnd); }; CondenseSpacing = function(text) { while (text.indexOf(" ") !== -1) text = text.replace(" ", " "); return text; }; pad = function(sText, iWidth, sChar) { sChar = ((sChar !== undefined) ? sChar : ('0')); sText = sText.toString(); return ((sText.length >= iWidth) ? (sText) : (new Array(iWidth - sText.length + 1).join(sChar) + sText)); }; is_visible = (function () { var x = window.pageXOffset ? window.pageXOffset + window.innerWidth - 1 : 0, y = window.pageYOffset ? window.pageYOffset + window.innerHeight - 1 : 0, relative = !!((!x && !y) || !elementFromPoint(x, y)); function inside(child, parent) { while(child){ if (child === parent) return true; child = child.parentNode; } return false; }; return function (elem) { if ( hidden || elem.offsetWidth==0 || elem.offsetHeight==0 || elem.style.visibility=='hidden' || elem.style.display=='none' || elem.style.opacity===0 ) return false; var rect = elem.getBoundingClientRect(); if (relative) { if (!inside(elementFromPoint(rect.left + elem.offsetWidth/2, rect.top + elem.offsetHeight/2),elem)) return false; } else if ( !inside(elementFromPoint(rect.left + elem.offsetWidth/2 + window.pageXOffset, rect.top + elem.offsetHeight/2 + window.pageYOffset), elem) || ( rect.top + elem.offsetHeight/2 < 0 || rect.left + elem.offsetWidth/2 < 0 || rect.bottom - elem.offsetHeight/2 > (window.innerHeight || documentElement.clientHeight) || rect.right - elem.offsetWidth/2 > (window.innerWidth || documentElement.clientWidth) ) ) return false; if (window.getComputedStyle || elem.currentStyle) { var el = elem, comp = null; while (el) { if (el === document) {break;} else if(!el.parentNode) return false; comp = window.getComputedStyle ? window.getComputedStyle(el, null) : el.currentStyle; if (comp && (comp.visibility=='hidden' || comp.display == 'none' || (typeof comp.opacity !=='undefined' && comp.opacity != 1))) return false; el = el.parentNode; } } return true; }; })(); //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// ////////////// ** common_ET.js -- DO NOT MODIFY ** ///////////// if (window.ET === undefined) window.ET = { }; if (window.ET.MCMF === undefined) // MeanCloud mod framework { window.ET.MCMF = { TryingToLoad: false, WantDebug: false, WantFasterAbilityCDs: false, InBattle: false, FinishedLoading: false, Initialized: false, AbilitiesReady: false, InitialAbilityCheck: true, TimeLeftOnCD: 9999, TimeLastFight: 0, CombatID: undefined, // technically not required ToastMessageSuccess: function(msg) { toastr.success(msg); }, ToastMessageWarning: function(msg) { toastr.warning(msg); }, EventSubscribe: function(sEventName, fnCallback, sNote) { if (window.ET.MCMF.EventSubscribe_events === undefined) window.ET.MCMF.EventSubscribe_events = []; var newEvtData = {}; newEvtData.name = ((!sEventName.startsWith("ET:")) ? ("ET:" + sEventName) : (sEventName)); newEvtData.callback = fnCallback; newEvtData.note = sNote; window.ET.MCMF.EventSubscribe_events.push(newEvtData); /* jQ("div#ET_meancloud_bootstrap").off("ET:" + sEventName.trim()).on("ET:" + sEventName.trim(), function() { window.ET.MCMF.EventSubscribe_events.forEach(function(oThisEvent, index, array) { if (sEventName === oThisEvent.name) { if (window.ET.MCMF.WantDebug) console.log("FIRING '" + oThisEvent.name + "'!" + ((oThisEvent.note === undefined) ? "" : " (" + oThisEvent.note + ")")); oThisEvent.callback(); } }); }); */ if (window.ET.MCMF.WantDebug) console.log("Added event subscription '" + sEventName + "'!" + ((sNote === undefined) ? "" : " (" + sNote + ")")); }, EventTrigger: function(sEventName) { //jQ("div#ET_meancloud_bootstrap").trigger(sEventName); if (window.ET.MCMF.EventSubscribe_events === undefined) return; window.ET.MCMF.EventSubscribe_events.forEach(function(oThisEvent, index, array) { if (sEventName === oThisEvent.name) { if (window.ET.MCMF.WantDebug) console.log("FIRING '" + oThisEvent.name + "'!" + ((oThisEvent.note === undefined) ? "" : " (" + oThisEvent.note + ")")); try { oThisEvent.callback(); } catch (err) { if (window.ET.MCMF.WantDebug) console.log("Exception: " + err); } } }); }, MeteorCall: function(sMethod, oParam1, oParam2, sMsgSuccess, sMsgFailure) { Package.meteor.Meteor.call("crafting.craftItem", sRecipeID, iBatchAmt, function(errResp) { if (errResp) window.ET.MCMF.ToastMessageWarning(sMsgFailure); else window.ET.MCMF.ToastMessageSuccess(sMsgSuccess); }); }, FasterAbilityUpdates: function() { try { if ((window.ET.MCMF.WantFasterAbilityCDs) && (window.ET.MCMF.FinishedLoading) && (!window.ET.MCMF.InBattle) && (!window.ET.MCMF.AbilitiesReady)) Meteor.call("abilities.gameUpdate", function(e, t) { }); } catch (err) { } setTimeout(window.ET.MCMF.FasterAbilityUpdates, 2000); }, AbilityCDTrigger: function() { try { bStillInCombat = window.ET.MCMF.InBattle || ((time_val() - window.ET.MCMF.TimeLastFight) < 3); if ((window.ET.MCMF.FinishedLoading) && (!bStillInCombat)) { iTotalCD = 0; iTotalCDTest = 0; iHighestCD = 0; window.ET.MCMF.GetAbilities().forEach(function(oThisAbility, index, array) { if (oThisAbility.equipped) { if (parseInt(oThisAbility.currentCooldown) > 0) { iTotalCD += parseInt(oThisAbility.currentCooldown); if (iHighestCD < parseInt(oThisAbility.currentCooldown)) iHighestCD = parseInt(oThisAbility.currentCooldown); } } iTotalCDTest += parseInt(oThisAbility.cooldown); }); if ((iTotalCDTest > 0) && (iTotalCD === 0)) { if (!window.ET.MCMF.AbilitiesReady) { if (!window.ET.MCMF.InitialAbilityCheck) { if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:abilitiesReady -->"); window.ET.MCMF.EventTrigger("ET:abilitiesReady"); //jQ("div#ET_meancloud_bootstrap").trigger("ET:abilitiesReady"); } } window.ET.MCMF.AbilitiesReady = true; window.ET.MCMF.TimeLeftOnCD = 0; } else { window.ET.MCMF.AbilitiesReady = false; window.ET.MCMF.TimeLeftOnCD = iHighestCD; } window.ET.MCMF.InitialAbilityCheck = false; } else { window.ET.MCMF.AbilitiesReady = false; window.ET.MCMF.TimeLeftOnCD = 9999; } } catch (err) { } setTimeout(window.ET.MCMF.AbilityCDTrigger, 500); }, InitMeteorTriggers: function() { if ((Package.meteor.Meteor === undefined) || (Package.meteor.Meteor.connection === undefined) || (Package.meteor.Meteor.connection._stream === undefined)) { setTimeout(window.ET.MCMF.InitMeteorTriggers, 100); return; } Package.meteor.Meteor.connection._stream.on('message', function(sMeteorRawData) { if (window.ET.MCMF.CombatID === undefined) { try { oDataTemp = Package.meteor.global.Accounts.connection._stores.combat._getCollection()._collection._docs._map; window.ET.MCMF.CombatID = oDataTemp[Object.keys(oDataTemp)[0]]._id; } catch (err) { } } try { oMeteorData = JSON.parse(sMeteorRawData); ///////////////////////////////////////////////////////////////////////////////////////////////////////// // // BACKUP TO RETRIEVE USER AND COMBAT IDS // if (oMeteorData.collection === "users") if ((window.ET.MCMF.UserID === undefined) || (window.ET.MCMF.UserID.length !== 17)) window.ET.MCMF.UserID = oMeteorData.id; if (oMeteorData.collection === "combat") if ((window.ET.MCMF.T_CombatID === undefined) || (window.ET.MCMF.CombatID.length !== 17)) if (oMeteorData.fields.owner === window.ET.MCMF.UserID) window.ET.MCMF.CombatID = oMeteorData.id; // ///////////////////////////////////////////////////////////////////////////////////////////////////////// if (window.ET.MCMF.FinishedLoading) { if (oMeteorData.collection === "battlesList") { window.ET.MCMF.IsDemon = false; window.ET.MCMF.AbilitiesReady = false; if ((oMeteorData.msg === "added") || (oMeteorData.msg === "removed")) { window.ET.MCMF.InBattle = (oMeteorData.msg === "added"); if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End")) + " -->"); window.ET.MCMF.EventTrigger("ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End"))); //jQ("div#ET_meancloud_bootstrap").trigger("ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End"))); } } if ((oMeteorData.collection === "battles") && (oMeteorData.msg === "added")) { if (oMeteorData.fields.finished) { window.ET.MCMF.WonLast = oMeteorData.fields.win; window.ET.MCMF.TimeLastFight = time_val(); if (!oMeteorData.fields.win) window.ET.MCMF.HP = 0; if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost")) + " -->"); window.ET.MCMF.EventTrigger("ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost"))); //jQ("div#ET_meancloud_bootstrap").trigger("ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost"))); } } } try { if (window.ET.MCMF.FinishedLoading) { if (oMeteorData.id) { if (oMeteorData.id.startsWith("battles-")) { if (oMeteorData.msg !== "removed") { battleID = oMeteorData.id; battleData = JSON.parse(oMeteorData.fields.value); jQ.makeArray(battleData.units).forEach(function(currentPlayer, index, array) { try { if (currentPlayer.name === window.ET.MCMF.UserName) { jQ.makeArray(currentPlayer.buffs).forEach(function(currentBuff, index2, array2) { try { if (currentBuff.id === "demons_heart") { if (currentBuff.data.active) { if (!window.ET.MCMF.IsDemon) { window.ET.MCMF.IsDemon = true; if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:combat:buffDemon -->"); window.ET.MCMF.EventTrigger("ET:combat:buffDemon"); //jQ("div#ET_meancloud_bootstrap").trigger("ET:combat:buffDemon"); } } } } catch (err) { } }); return true; // break out of forEach() } } catch (err) { } }); } } } } } catch (err) { } } catch (err) { } try { //todo: use life data from Meteor vs captured meteor response data oMeteorData = JSON.parse(sMeteorRawData); if (oMeteorData.collection === "combat") { if ((oMeteorData.fields.owner === window.ET.MCMF.UserID) || (oMeteorData.id === window.ET.MCMF.CombatID)) { window.ET.MCMF.HP = oMeteorData.fields.stats.health; window.ET.MCMF.NRG = oMeteorData.fields.stats.energy; } } } catch (err) { } }); }, AbilityCDCalc: function() { iTotalCD = 0; iTotalCDTest = 0; iHighestCD = 0; window.ET.MCMF.GetAbilities().forEach(function(oThisAbility, index, array) { if (oThisAbility.equipped) { if (parseInt(oThisAbility.currentCooldown) > 0) { iTotalCD += parseInt(oThisAbility.currentCooldown); if (iHighestCD < parseInt(oThisAbility.currentCooldown)) iHighestCD = parseInt(oThisAbility.currentCooldown); } } iTotalCDTest += parseInt(oThisAbility.cooldown); }); if ((iTotalCDTest > 0) && (iTotalCD === 0)) { if (!window.ET.MCMF.AbilitiesReady) { if (!window.ET.MCMF.InitialAbilityCheck) { if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:abilitiesReady -->"); window.ET.MCMF.EventTrigger("ET:abilitiesReady"); //jQ("div#ET_meancloud_bootstrap").trigger("ET:abilitiesReady"); } } window.ET.MCMF.AbilitiesReady = true; window.ET.MCMF.TimeLeftOnCD = 0; } else { window.ET.MCMF.AbilitiesReady = false; window.ET.MCMF.TimeLeftOnCD = iHighestCD; } window.ET.MCMF.InitialAbilityCheck = false; }, GetAbilities: function() { return Object.keys(window.ET.MCMF.AbilityManager._collection._docs._map).map(key => window.ET.MCMF.AbilityManager._collection._docs._map[key])[0].learntAbilities; }, GetAdventures: function() { return Object.keys(window.ET.MCMF.AdventureManager._collection._docs._map).map(key => window.ET.MCMF.AdventureManager._collection._docs._map[key])[0].adventures; }, GetChats: function() { return Object.keys(window.ET.MCMF.ChatManager._collection._docs._map).map(key => window.ET.MCMF.ChatManager._collection._docs._map[key]); }, GetItems: function() { return Object.keys(window.ET.MCMF.ItemManager._collection._docs._map).map(key => window.ET.MCMF.ItemManager._collection._docs._map[key]); }, // need a better way to check if the game has loaded basic data, but this is fine for now Setup: function() { if ((!window.ET.MCMF.TryingToLoad) && (!window.ET.MCMF.FinishedLoading)) { // use whatever version of jQuery available to us $("body").append("<div id=\"ET_meancloud_bootstrap\" style=\"visibility: hidden; display: none;\"></div>"); window.ET.MCMF.TryingToLoad = true; window.ET.MCMF.Setup_Initializer(); } }, Setup_Initializer: function() { // wait for Meteor availability if ((Package === undefined) || (Package.meteor === undefined) || (Package.meteor.Meteor === undefined) || (Package.meteor.Meteor.connection === undefined) || (Package.meteor.Meteor.connection._stream === undefined)) { setTimeout(window.ET.MCMF.Setup_Initializer, 10); return; } if (!window.ET.MCMF.Initialized) { window.ET.MCMF.Initialized = true; window.ET.MCMF.Setup_SendDelayedInitializer(); window.ET.MCMF.InitMeteorTriggers(); window.ET.MCMF.Setup_remaining(); } }, Setup_SendDelayedInitializer: function() { try { jQ("div#ET_meancloud_bootstrap").trigger("ET:initialized"); window.ET.MCMF.EventTrigger("ET:initialized"); //if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:initialized -->"); } catch (err) { setTimeout(window.ET.MCMF.Setup_SendDelayedInitializer, 100); } }, Setup_remaining: function() { try { window.ET.MCMF.UserID = Package.meteor.global.Accounts.connection._userId; window.ET.MCMF.UserName = Package.meteor.global.Accounts.connection._stores.users._getCollection()._collection._docs._map[Package.meteor.global.Accounts.connection._userId].username; try { oDataTemp = Package.meteor.global.Accounts.connection._stores.combat._getCollection()._collection._docs._map; Object.keys(oDataTemp).forEach(function(oDataTempItem, index, array) { if (oDataTempItem.owner === window.ET.MCMF.UserID) window.ET.MCMF.CombatID = oDataTempItem._id; }); } catch (err) { } window.ET.MCMF.AbilityManager = Package.meteor.global.Accounts.connection._stores.abilities._getCollection(); window.ET.MCMF.AdventureManager = Package.meteor.global.Accounts.connection._stores.adventures._getCollection(); window.ET.MCMF.ChatManager = Package.meteor.global.Accounts.connection._stores.simpleChats._getCollection(); window.ET.MCMF.ItemManager = Package.meteor.global.Accounts.connection._stores.items._getCollection(); if (window.ET.MCMF.GetAbilities().length < 0) throw "Not loaded yet: no abilities"; if (window.ET.MCMF.GetItems().length < 0) throw "Not loaded yet: no items"; if (window.ET.MCMF.GetChats().length < 0) throw "Not loaded yet: no chats"; // if the above is all good, then this should be no problem: window.ET.MCMF.AbilityCDTrigger(); // set up ability CD trigger window.ET.MCMF.AbilityCDCalc(); window.ET.MCMF.FasterAbilityUpdates(); // set up faster ability updates (do not disable, this is controlled via configurable setting) // trigger finished-loading event if (!window.ET.MCMF.FinishedLoading) { if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:loaded -->"); window.ET.MCMF.EventTrigger("ET:loaded"); //jQ("div#ET_meancloud_bootstrap").trigger("ET:loaded"); window.ET.MCMF.FinishedLoading = true; } document.ET = window.ET; } catch (err) { // any errors and we retry setup setTimeout(window.ET.MCMF.Setup_remaining, 500); } }, Loaded: function(fnCallback, sNote) { if (!window.ET.MCMF.FinishedLoading) window.ET.MCMF.EventSubscribe("loaded", fnCallback, sNote); else fnCallback(); }, Ready: function(fnCallback, sNote) { if (!window.ET.MCMF.Initialized) window.ET.MCMF.EventSubscribe("initialized", fnCallback, sNote); else fnCallback(); } }; window.ET.MCMF.Setup(); } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// ////////// ** CORE SCRIPT STARTUP -- DO NOT MODIFY ** ////////// function LoadJQ(callback) { if (window.jQ === undefined) { var script=document.createElement("script");script.setAttribute("src","//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js");script.addEventListener('load',function() { var subscript=document.createElement("script");subscript.textContent="window.jQ=jQuery.noConflict(true);("+callback.toString()+")();";document.body.appendChild(subscript); }, !1);document.body.appendChild(script); } else callback(); } LoadJQ(startup); ////////////////////////////////////////////////////////////////