您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically selects professions for empty slots
// ==UserScript== // @name NWPb // @description Automatically selects professions for empty slots // @include https://gateway.playneverwinter.com // @include https://gateway.playneverwinter.com/* // @include https://gatewaysitedown.playneverwinter.com // @include https://gatewaysitedown.playneverwinter.com/* // @include http://gateway.playneverwinter.com // @include http://gateway.playneverwinter.com/* // @include http://gatewaysitedown.playneverwinter.com // @include http://gatewaysitedown.playneverwinter.com/* // @version 0.2.2 // @grant GM_getValue // @grant GM_setValue // @grant GM_listValues // @grant GM_deleteValue // @namespace https://greasyfork.org/users/2365 // ==/UserScript== /* RELEASE NOTES 0.2.1 - Added BlackIce proffession - Added wont waste assets on all professions 0.1.0 - Initial release */ // Make sure it's running on the main page, no frames if (window.self !== window.top) { throw ""; } (function () { var image_pause = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAY" + "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" + "BNp57TyT3+MAAAAASUVORK5CYII=", image_play = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYA" + "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", image_prefs = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQC" + "AMAAAAoLQ9TAAAAllBMVEUAGQASEhIfHx8fJy8pKSk2NjZBQUFJR0ZQUE9RUVFSUlJNX3No" + "aGhsaWdramlycG1meY98fHx+fn5wgpV0iqKKh4R4jaR9jJx8kad9kad/mbONmaWEnrmEnrq" + "koZy3t7fIx8bKyMHT0c3S0dDU09DV1NPP1t3W1dXY2Njb2tfe29bf3tzj4uHr6+js6+r39/" + "f5+PgAAABrL3yvAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTA" + "QCanBgAAAAHdElNRQfWBRoFKh31UQ8DAAAAgUlEQVQY022OxxLCMAwFRSc4BEIPJZQQ08v+" + "/8+RsTExDDpIe3ijfSJ/hx9g62Dt4GaAI+8YT0t27+BxxvvE/no5pYT10lGFrE34Ja40W3g" + "1oMGmW7YZ6hnCYexKTPVkXivuvWe1Cz1aKqPNI3N0slI2TNYZiARJX30qERc7wBPKC4WRDz" + "WdWHfmAAAAAElFTkSuQmCC", image_close = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQC" + "AQAAAC1+jfqAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfW" + "BRkTNhxuPxLkAAAAHXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBUaGUgR0lNUO9kJW4AAAE" + "KSURBVCjPhdGxSgNBFAXQMzpgYWwsLEQUDBJBQgqFIChZEPR7/DA/QCGQTgQtJE1ENoWohY" + "UgbGKQyFjErNv52nObe19wqGWg7z0l5YVgVdOu+wUt507tqIVQ4Zodp861ooELe15M5KFI6" + "Zfr9u25MIj6Jl4cmSIPBWrq2o5cufO4aOJDYSozNTa2pK4t03PtwUdMKRRykAmW0dTRcyNX" + "pBQpI8GJDTR050zkNzK0bMMZLvUNZ8yCfy6Wvbc1NVyi4dloXjqWvds6uvp41pFmpVOKJWd" + "6bgwxkmTMIotWKpwrfBkZl7uMonUHf5wSlV2+fUZrjnXdzrmyy7djD8GWTW9e51z557o1Tz" + "85FH/WkOkaHQAAAABJRU5ErkJggg=="; // Setup global closure variables var $ = unsafeWindow.jQuery; var dfdNextRun = $.Deferred(); var timeoutHandle; // handle for setTimeouted dfdNextRun.reject(); var delay = { SHORT: 1000, MEDIUM: 5000, LONG: 30000, DEFAULT: 6000, // default delay TIMEOUT: 60000, // delay for cycle processing timeout }; /* * Tasklist can be modified to configure the training you want to perform. * The configurable options window sets how many profession slots you want to use for each profession. * The level array below for each professions specifies the tasks you want to learn at each crafting level. * Each craft slot will pick the first task that meets requirements. */ var taskList = [{ // Leadership taskName: "Leadership", level: { 0:["Leadership_Tier0_Intro_1"], 1:["Leadership_Tier0_Intro_5", "Leadership_Tier0_Intro_4","Leadership_Tier0_Intro_3", "Leadership_Tier0_Intro_2"], 2:["Leadership_Tier1_2_Guardduty"], 3:["Leadership_Tier1_2_Guardduty"], 4:["Leadership_Tier1_4_Protect"], 5:["Leadership_Tier1_4_Protect","Leadership_Tier1_5_Explore"], 6:["Leadership_Tier1_4_Protect","Leadership_Tier1_5_Explore"], 7:["Leadership_Tier1_4_Protect","Leadership_Tier1_5_Explore"], 8:["Leadership_Tier1_4_Protect","Leadership_Tier1_5_Explore"], 9:["Leadership_Tier1_4_Protect","Leadership_Tier2_9_Chart","Leadership_Tier1_5_Explore"], 10:["Leadership_Tier1_4_Protect","Leadership_Tier2_9_Chart","Leadership_Tier1_5_Explore","Leadership_Tier2_10_Battle"], 11:["Leadership_Tier1_4_Protect","Leadership_Tier2_9_Chart","Leadership_Tier1_5_Explore","Leadership_Tier2_10_Battle"], 12:["Leadership_Tier1_4_Protect","Leadership_Tier2_9_Chart","Leadership_Tier1_5_Explore","Leadership_Tier2_10_Battle"], // Current model 13:["Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier1_4_Protect","Leadership_Tier1_5_Explore","Leadership_Tier2_10_Battle"], 14:["Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier1_4_Protect","Leadership_Tier1_5_Explore","Leadership_Tier2_10_Battle"], 15:["Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier1_4_Protect","Leadership_Tier1_5_Explore","Leadership_Tier2_10_Battle"], 16:["Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier3_16_Fight","Leadership_Tier1_5_Explore","Leadership_Tier2_10_Battle"], 17:["Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier3_17_Deliver","Leadership_Tier3_16_Fight","Leadership_Tier1_5_Explore","Leadership_Tier2_12_Taxes","Leadership_Tier2_10_Battle"], 18:["Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier3_17_Deliver","Leadership_Tier3_16_Fight","Leadership_Tier1_5_Explore","Leadership_Tier2_12_Taxes","Leadership_Tier2_10_Battle"], 19:["Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier3_17_Deliver","Leadership_Tier3_16_Fight","Leadership_Tier1_5_Explore","Leadership_Tier2_12_Taxes","Leadership_Tier2_10_Battle"], 20:["Leadership_Tier3_20r_Master2","Leadership_Tier3_20r_Master1","Leadership_Tier3_20r_Master3","Leadership_Tier3_20_Destroy","Leadership_Tier3_17_Deliver","Leadership_Tier3_13r_Protectdiamonds","Leadership_Tier2_12_Taxes","Leadership_Tier3_16_Fight","Leadership_Tier3_13_Patrol","Leadership_Tier2_9_Chart","Leadership_Tier1_5_Explore"], //19:["Patrol the Mines","Chart Region","Deliver Metals","Fight Off Spellplagued","Explore Local Area","Collect Taxes","Train a Guard","Battle Undead","Hire a Mercenary"], //20:["Assault Enemy Stronghold","Follow Map to an Unknown Location","Recover Large Mineral Claim","Destroy Enemy Camp","Deliver Metals","Protect Diamond Shipment","Collect Taxes","Fight Off Spellplagued","Patrol the Mines","Chart Region","Explore Local Area"], // Training Mode /* 13:["Leadership_Tier3_13_Recruit","Leadership_Tier2_7_Recruit","Leadership_Tier1_2_Recruit"], 14:["Leadership_Tier3_13_Recruit","Leadership_Tier2_7_Recruit","Leadership_Tier1_2_Recruit"], 15:["Leadership_Tier3_13_Recruit","Leadership_Tier2_7_Recruit","Leadership_Tier1_2_Recruit"], 16:["Leadership_Tier3_13_Recruit","Leadership_Tier2_7_Recruit","Leadership_Tier1_2_Recruit"], 17:["Leadership_Tier3_13_Recruit","Leadership_Tier2_7_Recruit","Leadership_Tier1_2_Recruit"], */ }, }, { // Mailsmithing taskName:"Armorsmithing_Med", level: { 0:["Med_Armorsmithing_Tier0_Intro"], 1:["Med_Armorsmithing_Tier1_Chain_Boots_1","Med_Armorsmithing_Tier1_Chain_Shirt_1"], 2:["Med_Armorsmithing_Tier1_Chain_Armor_1","Med_Armorsmithing_Tier1_Chain_Pants_1"], 3:["Med_Armorsmithing_Tier1_Chain_Armor_1","Med_Armorsmithing_Tier1_Chain_Boots_Set_1"], 4:["Med_Armorsmithing_Tier1_Chain_Armor_1","Med_Armorsmithing_Tier1_Chain_Boots_Set_1"], 5:["Med_Armorsmithing_Tier1_Chain_Armor_Set_1","Med_Armorsmithing_Tier1_Chain_Boots_Set_1"], 6:["Med_Armorsmithing_Tier1_Chain_Armor_Set_1","Med_Armorsmithing_Tier1_Chain_Boots_Set_1"], 7:["Med_Armorsmithing_Tier1_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Boots_Set_1","Med_Armorsmithing_Tier2_Chain_Shirt"], 8:["Med_Armorsmithing_Tier2_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Pants_1","Med_Armorsmithing_Tier2_Chain_Boots_Set_1","Med_Armorsmithing_Tier2_Chain_Shirt"], 9:["Med_Armorsmithing_Tier2_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Pants_1","Med_Armorsmithing_Tier2_Chain_Boots_Set_1","Med_Armorsmithing_Tier2_Chain_Shirt"], 10:["Med_Armorsmithing_Tier2_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Pants_1","Med_Armorsmithing_Tier2_Chain_Boots_Set_1","Med_Armorsmithing_Tier2_Chain_Shirt_2"], 11:["Med_Armorsmithing_Tier2_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Pants_2","Med_Armorsmithing_Tier2_Chain_Boots_Set_1","Med_Armorsmithing_Tier2_Chain_Shirt_2","Med_Armorsmithing_Tier2_Chain_Pants_1"], 12:["Med_Armorsmithing_Tier2_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Pants_2","Med_Armorsmithing_Tier2_Chain_Boots_Set_1","Med_Armorsmithing_Tier2_Chain_Shirt_2","Med_Armorsmithing_Tier2_Chain_Pants_1"], 13:["Med_Armorsmithing_Tier2_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Pants_2","Med_Armorsmithing_Tier2_Chain_Boots_Set_1","Med_Armorsmithing_Tier2_Chain_Shirt_2","Med_Armorsmithing_Tier2_Chain_Pants_1"], 14:["Med_Armorsmithing_Tier2_Chain_Armor_Set_1","Med_Armorsmithing_Tier2_Chain_Pants_2","Med_Armorsmithing_Tier3_Chain_Shirt","Med_Armorsmithing_Tier3_Chain_Boots_Set_1"], 15:["Med_Armorsmithing_Tier3_Chain_Armor_Set_1","Med_Armorsmithing_Tier3_Chain_Pants","Med_Armorsmithing_Tier3_Chain_Shirt2","Med_Armorsmithing_Tier3_Chain_Boots_Set_1"], 16:["Med_Armorsmithing_Tier3_Chain_Armor_Set_1","Med_Armorsmithing_Tier3_Chain_Pants2","Med_Armorsmithing_Tier3_Chain_Shirt2","Med_Armorsmithing_Tier3_Chain_Helm_Set_1","Med_Armorsmithing_Tier3_Chain_Pants"], 17:["Med_Armorsmithing_Tier3_Chain_Armor_Set_1","Med_Armorsmithing_Tier3_Chain_Pants2","Med_Armorsmithing_Tier3_Chain_Shirt2","Med_Armorsmithing_Tier3_Chain_Helm_Set_1","Med_Armorsmithing_Tier3_Chain_Pants"], 18:["Med_Armorsmithing_Tier3_Chain_Armor_Set_1","Med_Armorsmithing_Tier3_Chain_Pants2","Med_Armorsmithing_Tier3_Chain_Shirt2","Med_Armorsmithing_Tier3_Chain_Helm_Set_1","Med_Armorsmithing_Tier3_Chain_Pants"], 19:["Med_Armorsmithing_Tier3_Chain_Armor_Set_1","Med_Armorsmithing_Tier3_Chain_Pants2","Med_Armorsmithing_Tier3_Chain_Shirt2","Med_Armorsmithing_Tier3_Chain_Helm_Set_1","Med_Armorsmithing_Tier3_Chain_Pants"], 20:["Med_Armorsmithing_Tier2_Refine_Basic"], //19:["Chain Armor +4","Fancy Chain Pants","Fancy Chain Shirt","Chain Helm +4","Ornate Chain Pants","Upgrade Blacksmith","Upgrade Prospector","Hire an additional Prospector"], //20:["Forge Steel Rings and Scales"], }, }, { // Platesmithing taskName:"Armorsmithing_Heavy", level: { 0:["Hvy_Armorsmithing_Tier0_Intro"], 1:["Hvy_Armorsmithing_Tier1_Plate_Boots_1","Hvy_Armorsmithing_Tier1_Plate_Shirt_1","Hvy_Armorsmithing_Tier1_Shield_1"], 2:["Hvy_Armorsmithing_Tier1_Plate_Armor_1","Hvy_Armorsmithing_Tier1_Plate_Pants_1"], 3:["Hvy_Armorsmithing_Tier1_Plate_Armor_1","Hvy_Armorsmithing_Tier1_Plate_Boots_Set_1"], 4:["Hvy_Armorsmithing_Tier1_Plate_Armor_1","Hvy_Armorsmithing_Tier1_Plate_Boots_Set_1"], 5:["Hvy_Armorsmithing_Tier1_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier1_Plate_Boots_Set_1"], 6:["Hvy_Armorsmithing_Tier1_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier1_Plate_Boots_Set_1"], 7:["Hvy_Armorsmithing_Tier1_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Boots_Set_1","Hvy_Armorsmithing_Tier2_Plate_Shirt","Hvy_Armorsmithing_Tier2_Shield_Set_1"], 8:["Hvy_Armorsmithing_Tier2_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Pants_1","Hvy_Armorsmithing_Tier2_Plate_Boots_Set_1","Hvy_Armorsmithing_Tier2_Plate_Shirt"], 9:["Hvy_Armorsmithing_Tier2_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Pants_1","Hvy_Armorsmithing_Tier2_Plate_Boots_Set_1","Hvy_Armorsmithing_Tier2_Plate_Shirt"], 10:["Hvy_Armorsmithing_Tier2_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Pants_1","Hvy_Armorsmithing_Tier2_Plate_Boots_Set_1","Hvy_Armorsmithing_Tier2_Plate_Shirt_2"], 11:["Hvy_Armorsmithing_Tier2_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Pants_2","Hvy_Armorsmithing_Tier2_Plate_Boots_Set_1","Hvy_Armorsmithing_Tier2_Plate_Shirt_2","Hvy_Armorsmithing_Tier2_Plate_Pants_1"], 12:["Hvy_Armorsmithing_Tier2_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Pants_2","Hvy_Armorsmithing_Tier2_Plate_Boots_Set_1","Hvy_Armorsmithing_Tier2_Plate_Shirt_2","Hvy_Armorsmithing_Tier2_Plate_Pants_1"], 13:["Hvy_Armorsmithing_Tier2_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Pants_2","Hvy_Armorsmithing_Tier2_Plate_Boots_Set_1","Hvy_Armorsmithing_Tier2_Plate_Shirt_2","Hvy_Armorsmithing_Tier2_Plate_Pants_1"], 14:["Hvy_Armorsmithing_Tier2_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier2_Plate_Pants_2","Hvy_Armorsmithing_Tier3_Plate_Shirt","Hvy_Armorsmithing_Tier3_Plate_Boots_Set_1"], 15:["Hvy_Armorsmithing_Tier3_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants","Hvy_Armorsmithing_Tier3_Plate_Shirt2","Hvy_Armorsmithing_Tier3_Plate_Boots_Set_1"], 16:["Hvy_Armorsmithing_Tier3_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants2","Hvy_Armorsmithing_Tier3_Plate_Shirt2","Hvy_Armorsmithing_Tier3_Plate_Helm_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants"], 17:["Hvy_Armorsmithing_Tier3_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants2","Hvy_Armorsmithing_Tier3_Plate_Shirt2","Hvy_Armorsmithing_Tier3_Plate_Helm_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants"], 18:["Hvy_Armorsmithing_Tier3_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants2","Hvy_Armorsmithing_Tier3_Plate_Shirt2","Hvy_Armorsmithing_Tier3_Plate_Helm_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants"], 19:["Hvy_Armorsmithing_Tier3_Plate_Armor_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants2","Hvy_Armorsmithing_Tier3_Plate_Shirt2","Hvy_Armorsmithing_Tier3_Plate_Helm_Set_1","Hvy_Armorsmithing_Tier3_Plate_Pants"], 20:["Hvy_Armorsmithing_Tier2_Refine_Basic"], //19:["Plate Armor +4","Fancy Plate Pants","Fancy Plate Shirt","Plate Helm +4","Ornate Plate Pants","Upgrade Armorer","Upgrade Miner","Hire an additional Miner"], //20:["Forge Steel Plates"], }, }, { // Leatherworking taskName:"Leatherworking", level: { 0:["Leatherworking_Tier0_Intro_1"], 1:["Leatherworking_Tier1_Leather_Boots_1","Leatherworking_Tier1_Leather_Shirt_1"], 2:["Leatherworking_Tier1_Leather_Armor_1","Leatherworking_Tier1_Leather_Pants_1"], 3:["Leatherworking_Tier1_Leather_Armor_1","Leatherworking_Tier1_Leather_Boots_Set_1"], 4:["Leatherworking_Tier1_Leather_Armor_1","Leatherworking_Tier1_Leather_Boots_Set_1"], 5:["Leatherworking_Tier1_Leather_Armor_Set_1","Leatherworking_Tier1_Leather_Boots_Set_1"], 6:["Leatherworking_Tier1_Leather_Armor_Set_1","Leatherworking_Tier1_Leather_Boots_Set_1"], 7:["Leatherworking_Tier1_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Boots_Set_1","Leatherworking_Tier2_Leather_Shirt"], 8:["Leatherworking_Tier2_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Pants_1","Leatherworking_Tier2_Leather_Boots_Set_1","Leatherworking_Tier2_Leather_Shirt"], 9:["Leatherworking_Tier2_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Pants_1","Leatherworking_Tier2_Leather_Boots_Set_1","Leatherworking_Tier2_Leather_Shirt"], 10:["Leatherworking_Tier2_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Pants_1","Leatherworking_Tier2_Leather_Boots_Set_1","Leatherworking_Tier2_Leather_Shirt_2"], 11:["Leatherworking_Tier2_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Pants_2","Leatherworking_Tier2_Leather_Boots_Set_1","Leatherworking_Tier2_Leather_Shirt_2","Leatherworking_Tier2_Leather_Pants_1"], 12:["Leatherworking_Tier2_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Pants_2","Leatherworking_Tier2_Leather_Boots_Set_1","Leatherworking_Tier2_Leather_Shirt_2","Leatherworking_Tier2_Leather_Pants_1"], 13:["Leatherworking_Tier2_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Pants_2","Leatherworking_Tier2_Leather_Boots_Set_1","Leatherworking_Tier2_Leather_Shirt_2","Leatherworking_Tier2_Leather_Pants_1"], /* 14:["Leatherworking_Tier2_Leather_Armor_Set_1","Leatherworking_Tier2_Leather_Pants_2","Ornate Leatherworking_Tier1_Leather_Shirt_1","Leatherworking_Tier3_Leather_Boots_Set_1"], 15:["Leatherworking_Tier3_Leather_Armor_Set_1","Leatherworking_Tier3_Leather_Pants","Leatherworking_Tier3_Leather_Shirt2","Leatherworking_Tier3_Leather_Boots_Set_1"], 16:["Leatherworking_Tier3_Leather_Armor_Set_1","Leatherworking_Tier3_Leather_Pants2","Leatherworking_Tier3_Leather_Shirt2","Leatherworking_Tier3_Leather_Helm_Set_1","Leatherworking_Tier3_Leather_Pants"], 17:["Leatherworking_Tier3_Leather_Armor_Set_1","Leatherworking_Tier3_Leather_Pants2","Leatherworking_Tier3_Leather_Shirt2","Leatherworking_Tier3_Leather_Helm_Set_1","Leatherworking_Tier3_Leather_Pants"], 18:["Leatherworking_Tier3_Leather_Armor_Set_1","Leatherworking_Tier3_Leather_Pants2","Leatherworking_Tier3_Leather_Shirt2","Leatherworking_Tier3_Leather_Helm_Set_1","Leatherworking_Tier3_Leather_Pants"], 19:["Leatherworking_Tier3_Leather_Armor_Set_1","Leatherworking_Tier3_Leather_Pants2","Leatherworking_Tier3_Leather_Shirt2","Leatherworking_Tier3_Leather_Helm_Set_1","Leatherworking_Tier3_Leather_Pants"], 20:["Leatherworking_Tier2_Refine_Basic"], */ //19:["Leather Armor +4","Fancy Leather Pants","Fancy Leather Shirt","Leather Helm +4","Ornate Leather Pants","Upgrade Tanner","Upgrade Skinner","Hire an additional Skinner"], //20:["Cure Tough Pelts"], // Experience 14:["Leatherworking_Tier3_Gather_Basic_Mass","Leatherworking_Tier3_Refine_Basic_Mass"], 15:["Leatherworking_Tier3_Gather_Basic_Mass","Leatherworking_Tier3_Refine_Basic_Mass"], 16:["Leatherworking_Tier3_Gather_Basic_Mass","Leatherworking_Tier3_Refine_Basic_Mass"], 17:["Leatherworking_Tier3_Gather_Basic_Mass","Leatherworking_Tier3_Refine_Basic_Mass"], 18:["Leatherworking_Tier3_Gather_Basic_Mass","Leatherworking_Tier3_Refine_Basic_Mass"], }, }, { // Tailoring taskName:"Tailoring", level: { 0:["Tailoring_Tier0_Intro"], 1:["Tailoring_Tier1_Cloth_Boots_1","Tailoring_Tier1_Cloth_Shirt_1"], 2:["Tailoring_Tier1_Cloth_Armor_1","Tailoring_Tier1_Cloth_Pants_1"], 3:["Tailoring_Tier1_Cloth_Armor_1","Tailoring_Tier1_Cloth_Boots_Set_1"], 4:["Tailoring_Tier1_Cloth_Armor_1","Tailoring_Tier1_Cloth_Boots_Set_1"], 5:["Tailoring_Tier1_Cloth_Armor_Set_1","Tailoring_Tier1_Cloth_Boots_Set_1"], 6:["Tailoring_Tier1_Cloth_Armor_Set_1","Tailoring_Tier1_Cloth_Boots_Set_1"], 7:["Tailoring_Tier1_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Boots_Set_1","Tailoring_Tier2_Cloth_Shirt"], 8:["Tailoring_Tier2_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Pants_1","Tailoring_Tier2_Cloth_Boots_Set_1","Tailoring_Tier2_Cloth_Shirt"], 9:["Tailoring_Tier2_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Pants_1","Tailoring_Tier2_Cloth_Boots_Set_1","Tailoring_Tier2_Cloth_Shirt"], 10:["Tailoring_Tier2_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Pants_1","Tailoring_Tier2_Cloth_Boots_Set_1","Tailoring_Tier2_Cloth_Shirt_2"], 11:["Tailoring_Tier2_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Pants_2","Tailoring_Tier2_Cloth_Boots_Set_1","Tailoring_Tier2_Cloth_Shirt_2","Tailoring_Tier2_Cloth_Pants_1"], 12:["Tailoring_Tier2_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Pants_2","Tailoring_Tier2_Cloth_Boots_Set_1","Tailoring_Tier2_Cloth_Shirt_2","Tailoring_Tier2_Cloth_Pants_1"], 13:["Tailoring_Tier2_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Pants_2","Tailoring_Tier2_Cloth_Boots_Set_1","Tailoring_Tier2_Cloth_Shirt_2","Tailoring_Tier2_Cloth_Pants_1"], 14:["Tailoring_Tier2_Cloth_Armor_Set_1","Tailoring_Tier2_Cloth_Pants_2", "Tailoring_Tier3_Cloth_Shirt","Tailoring_Tier3_Cloth_Boots_Set_1"], 15:["Tailoring_Tier3_Cloth_Armor_Set_1","Tailoring_Tier3_Cloth_Pants","Tailoring_Tier3_Cloth_Shirt2","Tailoring_Tier3_Cloth_Boots_Set_1"], 16:["Tailoring_Tier3_Cloth_Armor_Set_1","Tailoring_Tier3_Cloth_Pants2","Tailoring_Tier3_Cloth_Shirt2","Tailoring_Tier3_Cloth_Helm_Set_1","Tailoring_Tier3_Cloth_Pants"], 17:["Tailoring_Tier3_Cloth_Armor_Set_1","Tailoring_Tier3_Cloth_Pants2","Tailoring_Tier3_Cloth_Shirt2","Tailoring_Tier3_Cloth_Helm_Set_1","Tailoring_Tier3_Cloth_Pants"], 18:["Tailoring_Tier3_Cloth_Armor_Set_1","Tailoring_Tier3_Cloth_Pants2","Tailoring_Tier3_Cloth_Shirt2","Tailoring_Tier3_Cloth_Helm_Set_1","Tailoring_Tier3_Cloth_Pants"], 19:["Tailoring_Tier3_Cloth_Armor_Set_1","Tailoring_Tier3_Cloth_Pants2","Tailoring_Tier3_Cloth_Shirt2","Tailoring_Tier3_Cloth_Helm_Set_1","Tailoring_Tier3_Cloth_Pants"], 20:["Tailoring_Tier2_Refine_Basic"], //19:["Cloth Robes +4","Fancy Cloth Pants","Fancy Cloth Shirt","Cloth Cap +4","Ornate Cloth Pants","Upgrade Outfitter","Upgrade Weaver","Hire an additional Weaver"], //20:["Weave Cotton Cloth"], }, }, { // Artificing taskName: "Artificing", level: { 0:["Artificing_Tier0_Intro_1"], 1:["Artificing_Tier1_Symbol_Virtuous_1"], 2:["Artificing_Tier1_Icon_Virtuous_1"], 3:["Artificing_Tier1_Icon_Virtuous_1"], 4:["Artificing_Tier1_Icon_Virtuous_2"], 5:["Artificing_Tier1_Icon_Virtuous_2"], 6:["Artificing_Tier1_Icon_Virtuous_2"], 7:["Artificing_Tier1_Icon_Virtuous_2"], 8:["Artificing_Tier2_Icon_Virtuous_3"], 9:["Artificing_Tier2_Icon_Virtuous_3"], 10:["Artificing_Tier2_Icon_Virtuous_3"], 11:["Artificing_Tier2_Icon_Virtuous_3"], 12:["Artificing_Tier2_Icon_Virtuous_3"], 13:["Artificing_Tier2_Icon_Virtuous_3"], 14:["Artificing_Tier3_Icon_Virtuous_4"], 15:["Artificing_Tier3_Icon_Virtuous_4"], 16:["Artificing_Tier3_Icon_Virtuous_4"], 17:["Artificing_Tier3_Icon_Virtuous_5"], 18:["Artificing_Tier3_Icon_Virtuous_5"], 19:["Artificing_Tier3_Icon_Virtuous_5"], 20:["Artificing_Tier2_Refine_Basic"], //19:["Virtuous Icon +5","Upgrade Engraver","Upgrade Carver","Hire an additional Carver"], //20:["7:Craft Ornamental metal and Carved Wood"], }, }, { // Weaponsmithing taskName: "Weaponsmithing", level: { 0: ["Hire your first Smelter"], 1: ["Weaponsmithing_Tier1_Gather_Basic","Weaponsmithing_Tier1_Refine_Basic"], 2: ["Weaponsmithing_Tier1_Gather_Basic","Weaponsmithing_Tier1_Refine_Basic"], 3: ["Weaponsmithing_Tier1_Gather_Basic","Weaponsmithing_Tier1_Refine_Basic"], 4: ["Weaponsmithing_Tier1_Gather_Basic","Weaponsmithing_Tier1_Refine_Basic"], 5: ["Weaponsmithing_Tier1_Gather_Basic","Weaponsmithing_Tier1_Refine_Basic"], 6: ["Weaponsmithing_Tier1_Gather_Basic","Weaponsmithing_Tier1_Refine_Basic"], 7: ["Weaponsmithing_Tier1_Refine_Basic","Weaponsmithing_Tier1_Refine_Basic"], 8: ["Weaponsmithing_Tier2_Gather_Basic","Weaponsmithing_Tier2_Refine_Basic"], 9: ["Weaponsmithing_Tier2_Gather_Basic","Weaponsmithing_Tier2_Refine_Basic"], 10: ["Weaponsmithing_Tier2_Gather_Basic","Weaponsmithing_Tier2_Refine_Basic"], 11: ["Weaponsmithing_Tier2_Gather_Basic","Weaponsmithing_Tier2_Refine_Basic"], 12: ["Weaponsmithing_Tier2_Gather_Basic","Weaponsmithing_Tier2_Refine_Basic"], 13: ["Weaponsmithing_Tier2_Gather_Basic","Weaponsmithing_Tier2_Refine_Basic"], 14: ["Weaponsmithing_Tier3_Gather_Basic_Mass","Weaponsmithing_Tier3_Refine_Basic_Mass"], 15: ["Weaponsmithing_Tier3_Gather_Basic_Mass","Weaponsmithing_Tier3_Refine_Basic_Mass"], 16: ["Weaponsmithing_Tier3_Gather_Basic_Mass","Weaponsmithing_Tier3_Refine_Basic_Mass"], 17: ["Weaponsmithing_Tier3_Gather_Basic_Mass","Weaponsmithing_Tier3_Refine_Basic_Mass"], 18: ["Weaponsmithing_Tier3_Gather_Basic_Mass","Weaponsmithing_Tier3_Refine_Basic_Mass"], //19: ["Weaponsmithing_Tier3_Gather_Basic_Mass","Weaponsmithing_Tier3_Refine_Basic_Mass"], //20: ["Weaponsmithing_Tier3_Gather_Basic_Mass","Weaponsmithing_Tier3_Refine_Basic_Mass"], }, }, { // Alchemy taskName: "Alchemy", level: { 0:["Alchemy_Tier0_Intro_1"], 1:["Alchemy_Tier1_Experiment_Rank2","Alchemy_Tier1_Experimentation_Rank1",], 2:["Alchemy_Tier1_Experiment_Rank3","Alchemy_Tier1_Experimentation_Rank2"], 3:["Alchemy_Tier1_Experiment_Rank4","Alchemy_Tier1_Experimentation_Rank3"], 4:["Alchemy_Tier1_Experiment_Rank5","Alchemy_Tier1_Experimentation_Rank4"], 5:["Alchemy_Tier1_Experiment_Rank6","Alchemy_Tier1_Experimentation_Rank5"], 6:["Alchemy_Tier1_Experiment_Rank7","Alchemy_Tier1_Experimentation_Rank6"], 7:["Alchemy_Tier2_Experiment_Rank08","Alchemy_Tier2_Experimentation_Rank07"], 8:["Alchemy_Tier2_Experiment_Rank09","Alchemy_Tier2_Experimentation_Rank08"], 9:["Alchemy_Tier2_Experiment_Rank10","Alchemy_Tier2_Experimentation_Rank09"], 10:["Alchemy_Tier2_Experiment_Rank11","Alchemy_Tier2_Experimentation_Rank10"], 11:["Alchemy_Tier2_Experiment_Rank12","Alchemy_Tier2_Experimentation_Rank11"], 12:["Alchemy_Tier2_Experiment_Rank13","Alchemy_Tier2_Experimentation_Rank12"], 13:["Alchemy_Tier2_Experiment_Rank14","Alchemy_Tier2_Experimentation_Rank13"], 14:["Alchemy_Tier3_Experiment_Rank15","Alchemy_Tier3_Experimentation_Rank14"], 15:["Alchemy_Tier3_Experiment_Rank16","Alchemy_Tier3_Experimentation_Rank15"], 16:["Alchemy_Tier3_Experiment_Rank17","Alchemy_Tier3_Experimentation_Rank16"], 17:["Alchemy_Tier3_Experiment_Rank18","Alchemy_Tier3_Experimentation_Rank17"], 18:["Alchemy_Tier3_Experiment_Rank19","Alchemy_Tier3_Experimentation_Rank18"], 19:["Alchemy_Tier3_Experiment_Rank20","Alchemy_Tier3_Experimentation_Rank19"], 20:["Alchemy_Tier3_Experimentation_Rank20"], }, }, { // Black Ice taskName:"BlackIce", level: { 0:["Blackice_Tier1_Mass_Process_Blackice","Blackice_Tier1_Process_Blackice"], 1:["Blackice_Tier2_Purified_Enchantment_Healthsteal_Lesser","Blackice_Tier2_Corrupt_Enchantment_Lesser","Blackice_Tier1_Process_Blackice"], 2:["Blackice_Tier3_Corrupt_Enchantment_Greater","Blackice_Tier3_Purified_Enchantment_Healthsteal_Greater","Blackice_Tier2_Purified_Enchantment_Healthsteal_Lesser","Blackice_Tier2_Corrupt_Enchantment_Lesser","Blackice_Tier1_Process_Blackice"], //Blackice_Tier1_Process_Blackice //Blackice_Tier1_Mass_Process_Blackice //Blackice_Tier2_Corrupt_Enchantment_Lesser //Blackice_Tier2_Purified_Enchantment_Healthsteal_Lesser //Blackice_Tier2_Purified_Enchantment_Deflect_Lesser //Blackice_Tier2_Purified_Enchantment_Lesser //Blackice_Tier3_Corrupt_Enchantment_Greater //Blackice_Tier3_Purified_Enchantment_Healthsteal_Greater //Blackice_Tier3_Purified_Enchantment_Deflect_Greater //Blackice_Tier3_Purified_Enchantment_Greater //Blackice_Tier2_Corrupt_Enchantment_Lesser,Blackice_Tier2_Purified_Enchantment_Healthsteal_Lesser, //Blackice_Tier3_Corrupt_Enchantment_Greater,Blackice_Tier3_Purified_Enchantment_Healthsteal_Greater, }, }, ]; // settings definitions var globalSettingNames = [ {name: 'paused', title: 'Pause Script', def: false, type: 'checkbox', tooltip: 'Disable All Automation'}, {name: 'trainassets', title: 'Train additional assets if needed', def: false, type: 'checkbox', tooltip: 'Enable to train/recruit assets if required by a task'}, {name: 'preservelog', title: 'Preserve log', def: false, type: 'checkbox', tooltip: 'Enable to preserve log between page reloads'}, {name: 'optionals', title: 'Fill Optional Assets', def: false, type: 'checkbox', tooltip: 'Enable to include selecting the optional assets of tasks'}, {name: 'autopurchase', title: 'Auto Purchase Resources', def: true, type: 'checkbox', tooltip: 'Automatically purchase required resources from gateway shop (100 at a time)'}, {name: 'refinead', title: 'Refine AD', def: true, type: 'checkbox', tooltip: 'Enable refining of AD on character switch'}, {name: 'autoreload', title: 'Auto Reload', def: false, type: 'checkbox', tooltip: 'Enabling this will reload the gateway periodically'}, {name: 'autologin', title: 'Attempt to login automatically', def: false, type: 'checkbox', tooltip: 'Automatically attempt to login to the neverwinter gateway site'}, {name: 'nw_username', title: ' Neverwinter Username', def: '', type: 'text', tooltip: ''}, {name: 'nw_password', title: ' Neverwinter Password', def: '', type: 'password', tooltip: ''}, ]; var charSettingNames = [ {name: 'entity', title: 'Entity', def: 'character@handle', type: 'text', tooltip: 'Entity'}, {name: 'Leadership', title: 'Leadership', def: '9', type: 'text', tooltip: 'Number of slots to assign to Leadership'}, {name: 'Armorsmithing_Med', title: 'Mailsmithing', def: '0', type: 'text', tooltip: 'Number of slots to assign to Mailsmithing'}, {name: 'Armorsmithing_Heavy', title: 'Platesmithing', def: '0', type: 'text', tooltip: 'Number of slots to assign to Platesmithing'}, {name: 'Leatherworking', title: 'Leatherworking', def: '0', type: 'text', tooltip: 'Number of slots to assign to Leatherworking'}, {name: 'Tailoring', title: 'Tailoring', def: '0', type: 'text', tooltip: 'Number of slots to assign to Tailoring'}, {name: 'Artificing', title: 'Artificing', def: '0', type: 'text', tooltip: 'Number of slots to assign to Artificing'}, {name: 'Weaponsmithing', title: 'Weaponsmithing', def: '0', type: 'text', tooltip: 'Number of slots to assign to Weaponsmithing'}, {name: 'Alchemy', title: 'Alchemy', def: '0', type: 'text', tooltip: 'Number of slots to assign to Alchemy'}, {name: 'BlackIce', title: 'Black Ice Shaping', def: '0', type: 'text', tooltip: 'Number of slots to assign to BlackIce'}, ]; // Load global settings from persistent store var globalSettings = JSON.parse(GM_getValue('mlng_globalSettings', "{}")); // Set defaults if not found for each setting globalSettingNames.forEach(function (element, index, array) { // Ignore label types if (element.type === 'label') { return; } if (globalSettings[element.name] === undefined) { globalSettings[element.name] = element.def; } // call the onsave for the setting if it exists if (typeof (element.onsave) === "function") { _log("Calling 'onsave' for", element.name); element.onsave(globalSettings[element.name], globalSettings[element.name]); } }); // write back in case new defaults were merged GM_setValue('mlng_globalSettings', JSON.stringify(globalSettings)); // Load character settings from persistent store var charSettings = JSON.parse(GM_getValue('mlng_charSettings', "{}")); // Page definitions var pages = { LOGIN: { name: "Login", path: "div#login" }, GUARD: { name: "Account Guard", path: "div#page-accountguard" }, CHARSELECT: { name: "Character Select", path: "div.page-characterselect" }, FRONTPAGE: { name: "Front Page", path: "div.page-front" }, PROFESSIONS: { name: "Professions", path: "div.page-professions" }, }; function _log(msg) { var _el = $("#logWindow"); // append msg to log window _el.append('<p>[' + new Date().toLocaleString() + '] ' + msg + '</p>'); // if user doesn't hover the div, scroll it; warning: buggy in jquery 1.9.x if (!_el.is(':hover')) { _el.prop('scrollTop', _el.prop('scrollHeight')); } } function settingsCharacterInjectHTML() { // replace HTML containing character settings UI. var _text = ''; Object.keys(charSettings).forEach(function (i) { _text += '<li><input type="radio" name="radio_position" id="value_' + i.replace(' ', '_') + '" value="' + i.replace(' ', '_') + '" /><label for="value_' + i.replace(' ', '_') + '">' + charSettings[i].entity + '</label>'; _text += '<div id="charContainer_' + i.replace(' ', '_') + '" style="display:none"><ul style="list-style: none outside none;overflow:none;">'; charSettingNames.forEach(function (element) { var id = 'charsettings_' + i.replace(' ', '_') + '_' + element.name; _text += '<li title="' + element.tooltip + '"><input style="margin:4px" name="' + id + '" id="' + id + '" type="text" value="' + charSettings[i][element.name] + '"/><label for="' + id + '">' + element.title + '</label></li>'; }); _text += '</ul></li></div>'; }); $("#charSettings ul").html(_text); } function settingsCharacterAdd() { var _entity, i; _entity = prompt("Enter your character's entity / ingame mail address", "character@handle"); if (_entity === null || _entity.match(/\w@\w/) === null) { alert('Incorrect data, use charactername@accountname format'); return; } charSettings[_entity] = {}; for (i = 0; i < charSettingNames.length; i++) { charSettings[_entity][charSettingNames[i].name] = charSettingNames[i].name === 'entity' ? _entity : charSettingNames[i].def; } settingsCharacterInjectHTML(); } function settingsCharacterWipe() { charSettings = {}; GM_deleteValue('mlng_charSettings'); settingsCharacterAdd(); _log('Character settings wiped'); } function settingsSave() { var name, el, value, i, j; // Global Settings for (i = 0; i < globalSettingNames.length; i++) { name = globalSettingNames[i].name; el = $('#globalsettings_' + name); value = false; switch (globalSettingNames[i].type) { case "checkbox": value = el.prop("checked"); break; case "text": case "password": case "select": value = el.val(); break; case "label": // Labels don't have values continue; } if (typeof (globalSettingNames[i].onsave) === "function") { _log("Calling 'onsave' for: " + name); globalSettingNames[i].onsave(value, globalSettings[name]); } if (globalSettings[name] !== value) { globalSettings[name] = value; } } GM_setValue('mlng_globalSettings', JSON.stringify(globalSettings)); // Get character settings from UI for (i in charSettings) { for (j in charSettingNames) { name = charSettingNames[j].name; value = $('#charsettings_' + i.replace('@', '\\@').replace(' ', '_') + '_' + name).val(); if (charSettings[i][name] !== value) { charSettings[i][name] = value; } } } // Check if entity changed for (i in charSettings) { if (charSettings[i].entity !== i) { charSettings[charSettings[i].entity] = charSettings[i]; delete charSettings[i]; } } GM_setValue('mlng_charSettings', JSON.stringify(charSettings)); settingsCharacterInjectHTML(); _log('Settings saved.'); } function AddCss(cssString) { var newCss = document.createElement('style'); newCss.type = "text/css"; newCss.innerHTML = cssString; document.getElementsByTagName('head')[0].appendChild(newCss); } function injectHTML() { if ($("#settingsButton").length) { return; } // Add the required CSS AddCss("\ #logWindow{ position: fixed; right:0px; bottom:0px; width:50%; height:20%; overflow:auto;z-index: 1000; background: none rgb(238, 238, 238); text-align:left;font: 12px sans-serif; border:1px solid rgb(102, 102, 102);}\ #logWindow * { margin:0.2em; }\ #settingsButtons{ position: fixed; right: 0px; top: 0px; z-index: 1000; background: none rgb(238, 238, 238);}\ #settingsButtons div {float:left; border-right: 1px solid rgb(102, 102, 102);}\ #settingsButtons a, #settingsButtons a:visited {display:block; width: 22px; height: 22px; text-decoration: none; font-weight:bold; text-align:center; line-height:22px; color:black;}\ #settingsButtons img { background: repeat scroll 0% 0%; padding: 3px;}\ #settingsPanel{border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); background: none repeat scroll 0% 0% rgb(238, 238, 238); color: rgb(0, 0, 0); position: fixed; overflow: auto; right: 0px; top: 0px; width: 350px;max-height:750px;font: 12px sans-serif; text-align: left; display: block; z-index: 1000;}\ #settings_title{font-weight: bolder; background: none repeat scroll 0% 0% rgb(204, 204, 204); border-bottom: 1px solid rgb(102, 102, 102); padding: 3px;}\ #settingsPanelButtonContainer {background: none repeat scroll 0% 0% rgb(204, 204, 204); border-top: 1px solid rgb(102, 102, 102);padding: 3px;text-align:center} \ #charPanel {width:340px;max-height:400px;overflow:auto;display:block;padding:3px;}\ "); // Add settings panel to page body $("body").append( '<div id="settingsPanel">\ <div id="settings_title">\ <img src=' + image_prefs + ' style="float: left; vertical-align: text-bottom;">\ <img id="settings_cancel" src=' + image_close + ' title="Click to hide preferences" style="float: right; vertical-align: text-bottom; cursor: pointer; display: block;">\ <span style="margin:3px">Settings</span>\ </div>\ <div>\ <form style="margin: 0px; padding: 0px">\ <div id="globalSettings">\ <span>Global Settings</span>\ <ul style="list-style: none outside none; max-height: 500px; overflow: auto; margin: 3px; padding: 0px;">\ </ul>\ </div>\ <div id="charSettings">\ <span>Character Settings</span>\ <ul style="list-style: none outside none; max-height: 500px; overflow: auto; margin: 3px; padding: 0px;">\ </ul>\ </div>\ <div id="settingsPanelButtonContainer">\ <input id="settings_addchar" type="button" value="Add Character">\ <input id="settings_save" type="button" value="Save and Apply">\ <input id="settings_close" type="button" value="Close">\ <input id="settings_wipechar" type="button" value="Wipe" title="Wipe character settings">\ </div>\ </form>\ </div>\ </div>\ '); // Add pause & open settings buttons to page $("body").append('\ <div id="settingsButtons">\ <div id="pauseButton">\ <img src="' + (globalSettings.paused ? image_play : image_pause) + '" title="Click to ' + (globalSettings.paused ? "resume" : "pause") + ' task script" style="cursor: pointer; display: block;">\ </div>\ <div id="logButton">\ <a title="Click to toggle log window" href="javascript:void(0)">L</a>\ </div>\ <div id="settingsButton">\ <img src="' + image_prefs + '" title="Click to show preferences" style="cursor: pointer; display: block;">\ </div>\ </div>\ '); // Add log window $("body").append('\ <div id="logWindow" />\ '); // restore log contents var _el = $("#logWindow"); _el.append(GM_getValue('mlng_log', "")); _el.prop('scrollTop', _el.prop('scrollHeight')); // Add global settings var settingsList = $("div#globalSettings ul"); for (var i = 0; i < globalSettingNames.length; i++) { var id = 'globalsettings_' + globalSettingNames[i].name; switch (globalSettingNames[i].type) { case "checkbox": settingsList.append('<li title="' + globalSettingNames[i].tooltip + '"><input style="margin:4px" name="' + id + '" id="' + id + '" type="checkbox" /><label for="' + id + '">' + globalSettingNames[i].title + '</label></li>'); $('#' + id).prop('checked', globalSettings[globalSettingNames[i].name]); break; case "text": settingsList.append('<li title="' + globalSettingNames[i].tooltip + '"><label for="' + id + '">' + globalSettingNames[i].title + '</label><input style="margin:4px" name="' + id + '" id="' + id + '" type="text" /></li>'); $('#' + id).val(globalSettings[globalSettingNames[i].name]); break; case "password": settingsList.append('<li title="' + globalSettingNames[i].tooltip + '"><label for="' + id + '">' + globalSettingNames[i].title + '</label><input style="margin:4px" name="' + id + '" id="' + id + '" type="password" /></li>'); $('#' + id).val(globalSettings[globalSettingNames[i].name]); break; case "select": settingsList.append('<li title="' + globalSettingNames[i].tooltip + '"><label style="padding-left:4px" for="' + id + '">' + globalSettingNames[i].title + '</label><select style="margin:4px" name="' + id + '" id="' + id + '" /></li>'); var options = globalSettingNames[i].opts; var select = $('#' + id); for (var j = 0; j < options.length; j++) { if (globalSettings[globalSettingNames[i].name] == options[j].path) select.append('<option value="' + options[j].path + '" selected="selected">' + options[j].name + '</option>'); else select.append('<option value="' + options[j].path + '">' + options[j].name + '</option>'); } break; case "label": settingsList.append('<li title="' + globalSettingNames[i].tooltip + '"><label>' + globalSettingNames[i].title + '</label></li>'); break; } } // Add character settings for each char settingsCharacterInjectHTML(); $("#settingsPanel, #logWindow").hide(); // Add click handlers $("#charSettings").on('click', 'input[name=radio_position]', function () { var _container = "#charContainer_" + $(this).attr('value').replace('@', '\\@'); console.log(_container); $("#charSettings div[id^=charContainer_]").each(function () { $(this).hide(); }); $(_container).show(); }); $("#settingsButton, #settings_close, #settings_cancel").click(function () { $("#settingsButtons, #settingsPanel").toggle(); }); $("#logButton").click(function () { $("#logWindow").toggle(); }); $("#pauseButton").click(function () { globalSettings.paused = !globalSettings.paused; setTimeout(function () { GM_setValue('mlng_globalSettings', JSON.stringify(globalSettings)); }, 0); $("#globalsettings_paused").prop("checked", globalSettings.paused); $("#pauseButton img").attr("src", (globalSettings.paused ? image_play : image_pause)); $("#pauseButton img").attr("title", "Click to " + (globalSettings.paused ? "resume" : "pause") + " task script"); }); $("#settings_save").click(function () { setTimeout(function () { settingsSave(); }, 0); }); $("#settings_wipechar").click(function () { setTimeout(function () { settingsCharacterWipe(); }, 0); }); $("#settings_addchar").click(function () { setTimeout(function () { settingsCharacterAdd(); }, 0); }); $(unsafeWindow).one('beforeunload', function () { setTimeout(function () { if (globalSettings.preservelog === true) { GM_setValue('mlng_log', $('#logWindow').html()); } else { GM_deleteValue('mlng_log'); } }, 0); }); } /** * Uses the page settings to determine which page is currently displayed */ function getCurrentPage() { var _page, i; for (i in pages) { if ($(pages[i].path).filter(":visible").length) { _page = pages[i]; break; } } _log('Current page is: ' + (_page ? _page.name : 'Unknown')); return _page; } function characterGetCurrent() { try { var _ent = unsafeWindow.client.dataModel.model.ent.main; return _ent.name + '@' + _ent.publicaccountname; } catch (e) {} return undefined; } function characterGetNext() { // we need to get the next char in charSettings that actually is available for the logged in account. var _available, // array of characters available to the current account _filtered, // array of characters from charSettings containing only those in _available _currentChar = characterGetCurrent(); // current character // assignment finish time info characterGetNext.assignmentFinish = characterGetNext.assignmentFinish || {}; // save current characters earliest assignment finish time if (_currentChar !== undefined) { characterGetNext.assignmentFinish[_currentChar] = Math.min.apply(Math,unsafeWindow.client.dataModel.model.ent.main.itemassignments.assignments.map(function(x) { return new Date(x.ufinishdate).getTime() === 946684800000 ? 8640000000000000 : new Date(x.ufinishdate).getTime(); })); } try { _available = unsafeWindow.client.dataModel.model.loginInfo.choices.map(function (element) { return element.name + '@' + element.pubaccountname; }); _filtered = Object.keys(charSettings).filter(function (element) { return _available.indexOf(element) !== -1; }); if (_filtered.length === Object.keys(characterGetNext.assignmentFinish).length) { // assignment finish times are available for all chars, return character with earliest finish return Object.keys(characterGetNext.assignmentFinish).sort(function (a, b) { return characterGetNext.assignmentFinish[a] - characterGetNext.assignmentFinish[b]; })[0]; } // assignment finish times not available for all chars, return next char in list return _filtered[_filtered.indexOf(_currentChar) + 1] || _filtered[0]; // working for _currentChar === undefined just fine, because indexOf() will return -1 } catch (e) {} return undefined; } function characterSwitch() { // TODO: make switching priority based on time left to completion; no point in switching back and forth every delay.DEFAULT when we're waiting for tasks anyway. var _currentChar, _nextChar; _log('Switching characters:'); _currentChar = characterGetCurrent(); _nextChar = characterGetNext(); if (_nextChar && unsafeWindow.location.hash === '#/characterselect') { _log('-->Selected character: ' + _nextChar); unsafeWindow.location.hash = '#char(' + _nextChar + ')/'; } else if (_nextChar === _currentChar) { _log('-->Current character: ' + _currentChar + ' equals next character: ' + _nextChar + '. Doing nothing'); } else if (_nextChar && _currentChar) { _log('-->Switching character from: ' + _currentChar + ' to: ' + _nextChar); // fix for memory leak? unsafeWindow.client.dataModel.rmgr.rmgr.dicts.PersonalProject[unsafeWindow.client.dataModel.model.ent.main.id]._requesters = []; unsafeWindow.location.hash = unsafeWindow.location.hash.replace(_currentChar, _nextChar); } else { _log('-->.logininfo not available. Switching chars failed.'); } dfdNextRun.resolve(); } function utilRefineAD() { // refine AD; WARNING: this function doesn't resolve()! if (globalSettings.refinead === false) { return; } try { var lv_cur = unsafeWindow.client.dataModel.model.ent.main.currencies; if (lv_cur && lv_cur.roughdiamonds && lv_cur.diamondsconvertleft) { unsafeWindow.client.sendCommand('Gateway_ConvertNumeric', 'Astral_Diamonds'); _log('Refined AD'); } } catch (e) {} //TODO: wait for message back from server } function professionCollectRewards() { // collect profession rewards if they exist; WARNING: this function doesn't resolve()! var _dfd, _collected, _ia; _dfd = $.Deferred(); _collected = false; try { _ia = unsafeWindow.client.dataModel.model.ent.main.itemassignments; if (_ia.complete && _ia.complete > 0) { _ia.assignments.forEach(function (element) { if (element.rewards) { unsafeWindow.client.professionTaskCollectRewards(JSON.stringify(element.uassignmentid)); _collected = true; } }); } } catch (e) {} if (_collected === true) { _log('Collected profession rewards'); setTimeout(function () { professionCollectRewards() .then( function() { unsafeWindow.client.dataModel.model.craftinglist = {}; // need to invalidate the old craftinglists, they refresh after a few secs _dfd.resolve(); }); }, delay.SHORT); } else { _dfd.resolve(); } return _dfd.promise(); } /** * Will continually test for the given query state and resolve the given deferred object when the state is reached * and the loading symbol is not visible * * @param {string} query The query for the state to wait for */ function WaitForElement(selector) { var _dfd, _check; _dfd = $.Deferred(); _check = setInterval(function () { if ((selector === '' || $(selector).length) && $("div.loading-image:visible").length === 0) { clearInterval(_check); _dfd.resolve(); } }, 300); return _dfd.promise(); } function WaitForProperty(property) { // need to use eval() because of GM userscript being wrapped in an anonymous function // didn't want to have it work for unsafeWindow[property] only // could rewrite not to use exceptions, but meh, performance loss from stack trace should be negligible in this case var _dfd, _check; _dfd = $.Deferred(); _check = setInterval(function () { try { if (eval(property) === undefined) { throw ''; //needed when foo exists && foo.bar doesn't exist } clearInterval(_check); _dfd.resolve(); } catch (e) {} }, 300); return _dfd.promise(); } /** * Selects the highest level asset for the i'th button in the list. Uses an iterative approach * in order to apply a sufficient delay after the asset is assigned * * @param {Array} The list of buttons to use to click and assign assets for * @param {int} i The current iteration number. Will select assets for the i'th button * @param {Deferred} jQuery Deferred object to resolve when all of the assets have been assigned */ function SelectItemFor(buttonListIn, i, def, prof) { buttonListIn[i].click(); WaitForElement("") .then(function () { var specialItems = $("div.modal-item-list a.Special"); var goldItems = $("div.modal-item-list a.Gold"); var silverItems = $("div.modal-item-list a.Silver"); var bronzeItems = $("div.modal-item-list a.Bronze"); var clicked = false; // Try to avoid using up higher rank assets needlessly // Comment out for random use of all high assets if (prof.taskName === "Leadership") { var mercenarys = $("div.modal-item-list a.Bronze:contains('Mercenary')"); var guards = $("div.modal-item-list a.Bronze:contains('Guard')"); var footmen = $("div.modal-item-list a.Bronze:contains('Footman')"); var manatarms = $("div.modal-item-list a.Silver:contains('Man-at-Arms')"); var adventurers = $("div.modal-item-list a.Gold:contains('Adventurer')"); var heros = $("div.modal-item-list a.Special:contains('Hero')"); if (mercenarys.length) { clicked = true; mercenarys[0].click(); } else if (guards.length) { clicked = true; guards[0].click(); } else if (footmen.length) { clicked = true; footmen[0].click(); } else if (manatarms.length) { clicked = true; manatarms[0].click(); } else if (adventurers.length) { clicked = true; adventurers[0].click(); } else if (heros.length) { clicked = true; heros[0].click(); } } if (prof.taskName === "Armorsmithing_Med") { var prospectors = $("div.modal-item-list a.Bronze:contains('Prospector')"); var blacksmiths = $("div.modal-item-list a.Bronze:contains('Blacksmith')"); var amailsmiths = $("div.modal-item-list a.Bronze:contains('Assistant Mailsmith')"); var mailsmiths = $("div.modal-item-list a.Silver:contains('Mailsmith')"); var mmailsmiths = $("div.modal-item-list a.Gold:contains('Master Mailsmith')"); var gmailsmiths = $("div.modal-item-list a.Special:contains('Grandmaster Mailsmith')"); if (prospectors.length) { clicked = true; prospectors[0].click(); } else if (blacksmiths.length) { clicked = true; blacksmiths[0].click(); } else if (amailsmiths.length) { clicked = true; amailsmiths[0].click(); } else if (mailsmiths.length) { clicked = true; mailsmiths[0].click(); } else if (mmailsmiths.length) { clicked = true; mmailsmiths[0].click(); } else if (gmailsmiths.length) { clicked = true; gmailsmiths[0].click(); } } if (prof.taskName === "Armorsmithing_Heavy") { var miners = $("div.modal-item-list a.Bronze:contains('Miner')"); var armorers = $("div.modal-item-list a.Bronze:contains('Armorer')"); var aplatesmiths = $("div.modal-item-list a.Bronze:contains('Assistant Platesmith')"); var platsmiths = $("div.modal-item-list a.Silver:contains('Platsmith')"); var mplatsmiths = $("div.modal-item-list a.Gold:contains('Master Platsmith')"); var gplatsmiths = $("div.modal-item-list a.Special:contains('Grandmaster Platsmith')"); if (miners.length) { clicked = true; miners[0].click(); } else if (armorers.length) { clicked = true; armorers[0].click(); } else if (aplatesmiths.length) { clicked = true; aplatesmiths[0].click(); } else if (platsmiths.length) { clicked = true; platsmiths[0].click(); } else if (mplatsmiths.length) { clicked = true; mplatsmiths[0].click(); } else if (gplatsmiths.length) { clicked = true; gplatsmiths[0].click(); } } if (prof.taskName === "Leatherworking") { var skinners = $("div.modal-item-list a.Bronze:contains('Skinner')"); var tanners = $("div.modal-item-list a.Bronze:contains('Tanner')"); var aleatherworkers = $("div.modal-item-list a.Bronze:contains('Assistant Leatherworker')"); var leatherworkers = $("div.modal-item-list a.Silver:contains('Leatherworker')"); var mleatherworkers = $("div.modal-item-list a.Gold:contains('Master Leatherworker')"); var gleatherworkers = $("div.modal-item-list a.Special:contains('Grandmaster Leatherworker')"); if (skinners.length) { clicked = true; skinners[0].click(); } else if (tanners.length) { clicked = true; tanners[0].click(); } else if (aleatherworkers.length) { clicked = true; aleatherworkers[0].click(); } else if (leatherworkers.length) { clicked = true; leatherworkers[0].click(); } else if (mleatherworkers.length) { clicked = true; mleatherworkers[0].click(); } else if (gleatherworkers.length) { clicked = true; gleatherworkers[0].click(); } } if (prof.taskName === "Tailoring") { var weavers = $("div.modal-item-list a.Bronze:contains('Weaver')"); var outfitters = $("div.modal-item-list a.Bronze:contains('Outfitter')"); var atailors = $("div.modal-item-list a.Bronze:contains('Assistant Tailor')"); var tailors = $("div.modal-item-list a.Silver:contains('Leatherworker')"); var mtailors = $("div.modal-item-list a.Gold:contains('Master Tailor')"); var gtailors = $("div.modal-item-list a.Special:contains('Grandmaster Tailor')"); if (weavers.length) { clicked = true; weavers[0].click(); } else if (outfitters.length) { clicked = true; outfitters[0].click(); } else if (atailors.length) { clicked = true; atailors[0].click(); } else if (tailors.length) { clicked = true; tailors[0].click(); } else if (mtailors.length) { clicked = true; mtailors[0].click(); } else if (gtailors.length) { clicked = true; gtailors[0].click(); } } if (prof.taskName === "Artificing") { var carvers = $("div.modal-item-list a.Bronze:contains('Carver')"); var engravers = $("div.modal-item-list a.Bronze:contains('Engraver')"); var aartificers = $("div.modal-item-list a.Bronze:contains('Assistant Artificer')"); var artificers = $("div.modal-item-list a.Silver:contains('Artificer')"); var martificers = $("div.modal-item-list a.Gold:contains('Master Artificer')"); var gartificers = $("div.modal-item-list a.Special:contains('Grandmaster Artificer')"); if (carvers.length) { clicked = true; carvers[0].click(); } else if (engravers.length) { clicked = true; engravers[0].click(); } else if (aartificers.length) { clicked = true; aartificers[0].click(); } else if (aartificers.length) { clicked = true; aartificers[0].click(); } else if (martificers.length) { clicked = true; martificers[0].click(); } else if (gartificers.length) { clicked = true; gartificers[0].click(); } } if (prof.taskName === "Weaponsmithing") { var smelters = $("div.modal-item-list a.Bronze:contains('Smelter')"); var grinders = $("div.modal-item-list a.Bronze:contains('Grinder')"); var aweaponsmiths = $("div.modal-item-list a.Bronze:contains('Assistant Weaponsmith')"); var weaponsmiths = $("div.modal-item-list a.Silver:contains('Weaponsmith')"); var mweaponsmiths = $("div.modal-item-list a.Gold:contains('Master Weaponsmith')"); var gweaponsmiths = $("div.modal-item-list a.Special:contains('Grandmaster Weaponsmith')"); if (smelters.length) { clicked = true; smelters[0].click(); } else if (grinders.length) { clicked = true; grinders[0].click(); } else if (aweaponsmiths.length) { clicked = true; aweaponsmiths[0].click(); } else if (weaponsmiths.length) { clicked = true; weaponsmiths[0].click(); } else if (mweaponsmiths.length) { clicked = true; mweaponsmiths[0].click(); } else if (gweaponsmiths.length) { clicked = true; gweaponsmiths[0].click(); } } if (prof.taskName === "Alchemy") { var apothecarys = $("div.modal-item-list a.Bronze:contains('Apothecary')"); var mixologists = $("div.modal-item-list a.Bronze:contains('Mixologist')"); var aalchemists = $("div.modal-item-list a.Bronze:contains('Assistant Alchemist')"); var alchemists = $("div.modal-item-list a.Silver:contains('Alchemist')"); var malchemists = $("div.modal-item-list a.Gold:contains('Master Alchemist')"); var galchemists = $("div.modal-item-list a.Special:contains('Grandmaster Alchemist')"); if (apothecarys.length) { clicked = true; apothecarys[0].click(); } else if (mixologists.length) { clicked = true; mixologists[0].click(); } else if (aalchemists.length) { clicked = true; aalchemists[0].click(); } else if (alchemists.length) { clicked = true; alchemists[0].click(); } else if (malchemists.length) { clicked = true; malchemists[0].click(); } else if (galchemists.length) { clicked = true; galchemists[0].click(); } } if (prof.taskName === "BlackIce") { var chillwrights = $("div.modal-item-list a.Bronze:contains('Apothecary')"); var black_ice_smiths = $("div.modal-item-list a.Bronze:contains('Black Ice Smith')"); var acryomancers = $("div.modal-item-list a.Bronze:contains('Assistant Cryomancer')"); var cryomancers = $("div.modal-item-list a.Silver:csontains('Cryomancer')"); var mcryomancers = $("div.modal-item-list a.Gold:contains('Master Cryomancer')"); var gcryomancers = $("div.modal-item-list a.Special:contains('Grandmaster Cryomancer')"); if (chillwrights.length) { clicked = true; chillwrights[0].click(); } else if (black_ice_smiths.length) { clicked = true; black_ice_smiths[0].click(); } else if (acryomancers.length) { clicked = true; acryomancers[0].click(); } else if (cryomancers.length) { clicked = true; cryomancers[0].click(); } else if (mcryomancers.length) { clicked = true; mcryomancers[0].click(); } else if (gcryomancers.length) { clicked = true; gcryomancers[0].click(); } } if (!clicked) { // Click the highest slot if (specialItems.length) { specialItems[0].click(); } else if (goldItems.length) { goldItems[0].click(); } else if (silverItems.length) { silverItems[0].click(); } else if (bronzeItems.length) { bronzeItems[0].click(); } else { $("button.close-button").click(); } } _log("Clicked item"); return true; }) .then( function () { return WaitForElement(""); }) .then(function () { // Get the new set of select buttons created since the other ones are removed when the asset loads var buttonList = $("h3:contains('Optional Assets:')").closest("div").find("button"); if (i < buttonList.length - 1) { SelectItemFor(buttonList, i + 1, def, prof); } else { _log('all optional slots populated'); // Let main loop continue def.resolve(); } }); } function professionBuyResource(item, count) { _log("Purchasing resources:" + item); count = count || 100; var resourceID = { Crafting_Resource_Charcoal: 0, Crafting_Resource_Rocksalt: 1, Crafting_Resource_Spool_Thread: 2, Crafting_Resource_Porridge: 3, Crafting_Resource_Solvent: 4, Crafting_Resource_Brimstone: 5, Crafting_Resource_Coal: 6, Crafting_Resource_Moonseasalt: 7, Crafting_Resource_Quicksilver: 8, Crafting_Resource_Spool_Threadsilk: 9, }; // fetch store; we don't really need the vars to be populated, just that the buy command won't execute unless we send this 1st; unsafeWindow.client.dataModel.fetchVendor('Nw_Gateway_Professions_Merchant'); //send an 'analytic tick', that's what the outer client function does ... unsafeWindow.client.analyticTick("User:BuyItem", count); // Make purchase unsafeWindow.client.sendCommand( "GatewayVendor_PurchaseVendorItem", { vendor: 'Nw_Gateway_Professions_Merchant', store: 'Store_Crafting_Resources', idx: resourceID[item], count: count }); // Wait for the notification and close it WaitForElement("button.closeNotification").done(function () { $('button.closeNotification').click(); }); } function searchForTask(taskname, profName) { // assuming we are on the correct profession page - NEEDS FIX; // looks through ALL available tasks, even if they are not visible on the page (i.e. paginated or filtered) var _dfd = $.Deferred(); var searchItem = null; var searchAsset = false; try { // Return first object that matches exact craft name var thisTask = unsafeWindow.client.dataModel.model.craftinglist['craft_' + profName].entries.filter(function (entry) { return entry.def && entry.def.name == taskname; })[0]; // If no task is returned then we have three of this task already or wrong name in settings if (!thisTask) { _log('searchForTask: Task ' + taskname + ' not available.'); _dfd.resolve(false); return _dfd.promise(); } // start task if requirements are met if (!thisTask.failedrequirementsreasons.length) { _dfd.resolve(thisTask.def.name); return _dfd.promise(); } // Too high level if (thisTask.failslevelrequirements) { _log("searchForTask: Wrong task settings: task level is too high: " + taskname); _dfd.resolve(false); return _dfd.promise(); } // Missing assets or ingredients if (thisTask.failsresourcesrequirements) { var failedAssets = thisTask.required.filter(function (entry) { return !entry.fillsrequirements; }); // Missing required assets if (failedAssets.length) { var failedCrafter = failedAssets.filter(function (entry) { return entry.categories.indexOf("Person") >= 0; }); if (failedCrafter.length && globalSettings.trainassets) { _log("searchForTask: Crafting: " + failedCrafter[0].icon); searchItem = failedCrafter[0].icon; searchAsset = true; } else { _log("searchForTask: Auto crafting assets disabled, missing: " + failedCrafter[0].icon); _dfd.resolve(false); return _dfd.promise(); } } else { // Check for craftable or buyable ingredients var failedResources = thisTask.consumables.filter(function (entry) { return entry.required && !entry.fillsrequirements; }); // Check first required ingredient only // If it fails to buy or craft task cannot be completed anyway // If it succeeds script will search for tasks anew var itemName = failedResources[0].hdef.match(/\[(\w+)\]/)[1]; // purchase buyable resources if (itemName.match(/^Crafting_Resource_(Charcoal|Rocksalt|Spool_Thread|Porridge|Solvent|Brimstone|Coal|Moonseasalt|Quicksilver|Spool_Threadsilk)$/)) { if (globalSettings.autopurchase) { professionBuyResource(itemName); _dfd.resolve(null); return _dfd.promise(); } _log("searchForTask: Auto resource purchasing disabled, missing: " + itemName); _dfd.resolve(false); return _dfd.promise(); } // craft ingredient items _log("searchForTask: Crafting: " + itemName); searchItem = itemName; } } // either no craftable items/assets found or other task requirements are not met // Skip crafting ingredient tasks for Leadership if (searchItem === null || !searchItem.length || (profName == 'Leadership' && !searchAsset && !searchItem.match(/Crafting_Asset_Craftsman/))) { _log("searchForTask: Failed to resolve item requirements for task: " + taskname); _dfd.resolve(false); return _dfd.promise(); } // Generate list of available tasks to search ingredients/assets from _log("searchForTask: Searching tasks for ingredient: " + searchItem); var taskList = unsafeWindow.client.dataModel.model.craftinglist['craft_' + profName].entries.filter(function (entry) { // remove header lines first to avoid null def if (entry.isheader) { return false; } // Too high level if (entry.failslevelrequirements) { return false; } // Rewards do not contain item we want to make if (searchAsset === true) { if (entry.def.icon != searchItem || entry.def.name.indexOf('Recruit') === -1 || entry.def.requiredrank > 14) { return false; } } else { if (!(entry.rewards.some(function (itm) { return (itm.hdef.indexOf(searchItem) !== -1); }))) { return false; } } // Skip mass production tasks if (entry.def.displayname.match(/^(Batch|Mass|Deep|Intensive) /)) { return false; } // Skip trading tasks if (entry.def.displayname.indexOf('Trading') !== -1) { return false; } // Skip looping Transmute tasks if (entry.def.displayname.match(/^(Transmute|Create) /)) { return false; } return true; }); if (!taskList.length) { _log("searchForTask: Unable to find tasks for ingredient: " + searchItem); _dfd.resolve(false); return _dfd.promise(); } // Use more efficient Empowered task for Aqua Vitae if available. if (searchItem == "Crafting_Resource_Aquavitae" && taskList.length > 1) { taskList.shift(); } // Should really only be one result now _log("searchForTask: Attempting to find task for ingredient: " + taskList[0].def.name); searchForTask(taskList[0].def.name, profName) .then( function (task) { _dfd.resolve(task); }); return _dfd.promise(); } catch (e) {} _log('searchForTask: No valid task found for: ' + taskname); _dfd.resolve(false); return _dfd.promise(); } function professionGetCurrentLevel(professionName) { var _level; _level = 0; if (professionName !== undefined) { try { unsafeWindow.client.dataModel.model.ent.main.itemassignmentcategories.categories.some(function(entry) { if(entry.name == professionName) { _level = entry.currentrank; return true; } return false; }); } catch (e) {} } return _level; } // TO BE REPLACED function professionStartTask() { var _dfd = $.Deferred(); //Get the start task button if it is enabled var enabledButton = $("div.footer-body > div.input-field.button:not('.disabled') > button:contains('Start Task')"); if (enabledButton.length) { _log("professionStartTask(): clicking Start Task button"); enabledButton.click(); } else { // Button not enabled, something required was probably missing _log('professionStartTask(): something went wrong, start task button not enabled.'); } // an ugly hack, not sure how to go about waiting for the task to actually start/fail // 2 options: either read notifications or hook client functions; both ugly setTimeout(function () { _dfd.resolve(); }, delay.SHORT); return _dfd.promise(); } // TO BE REPLACED function professionSlotItems(prof) { var _dfd, _buttonList; _dfd = $.Deferred(); if (!globalSettings.optionals) { _dfd.resolve(); } else { _buttonList = $("h3:contains('Optional Assets:')").closest("div").find("button"); if (_buttonList.length) { _log('createNextTask: populating optional slots.'); SelectItemFor(_buttonList, 0, _dfd, prof); } else { _dfd.resolve(); } } return _dfd.promise(); } function professionGetCraftingList(profName) { // resolving with the actual craftinglist, not used atm var _dfd, _craftingList; _dfd = $.Deferred(); _craftingList = unsafeWindow.client.dataModel.model.craftinglist; if (_craftingList && _craftingList['craft_' + profName]) { _log('professionGetTaskList(): ' + profName + ' craftlist available.'); _dfd.resolve(_craftingList['craft_' + profName]); } else { _log('professionGetTaskList(): ' + profName + ' craftlist not available, fetching.'); unsafeWindow.client.professionFetchTaskList('craft_' + profName); WaitForProperty('unsafeWindow.client.dataModel.model.craftinglist["craft_' + profName + '"]') .then(function() { _log('professionGetTaskList(): done fetching ' + profName + ' craftlist'); _dfd.resolve(unsafeWindow.client.dataModel.model.craftinglist['craft_' + profName]); }); } return _dfd.promise(); } // TO BE REPLACED /** * Iterative approach to finding the next task to assign to an open slot. * * @param {Array} list The list of task names to try in order of precedence * @param {int} i The current attempt number. Will try to find the i'th task. */ function createNextTask(prof, i) { var _dfd = $.Deferred(); // get tasks for current profession and rank var list = prof.level[ professionGetCurrentLevel(prof.taskName) ]; if (list.length <= i) { _log("Nothing Found"); _dfd.resolve(); } else { var taskName = list[i]; _log("createNextTask: searching for: " + list.length + ' ' + i + ' ' + taskName); professionGetCraftingList(prof.taskName) .then( function () { return searchForTask(taskName, prof.taskName); }) .then( function (task) { if (task == null) { _log("Skipping task selection to purchase resources"); _dfd.resolve(); } else if (task) { _log('createNextTask: found: ' + task); // navigate to task details page unsafeWindow.location.hash = unsafeWindow.location.hash.replace(/\)\/.+/, ')' + '/professions-tasks/' + prof.taskName + '/' + task); WaitForElement("div.page-professions-taskdetails") .then(function () { // fill optional slots if needed return professionSlotItems(prof); }) .then(function () { // start the task return professionStartTask(); }) .then(function() { _dfd.resolve(); }); } else { _log('createNextTask: finding next task.'); createNextTask(prof, i + 1) .then( function() { _dfd.resolve(); }); } }); } return _dfd.promise(); } function pageCHARSELECT() { //select next character characterSwitch(); dfdNextRun.resolve(); } function pageFRONTPAGE() { // go to professions page _log('pageFRONTPAGE: switching to professions page.'); $("a.professions").click(); dfdNextRun.resolve(); } function professionAssignTasks() { // returns true if work still needs to be done, false if finished var _assignments, _currentTasks, _craftingList, i; try { _assignments = unsafeWindow.client.dataModel.model.ent.main.itemassignments.assignments; // check if slots available if (!_assignments.filter(function (entry) { return (!entry.islockedslot && !entry.uassignmentid); }).length) { _log("professionAssignTasks(): No available task slots."); return false; } // Go through the professions to assign tasks until specified slots filled for (i = 0; i < taskList.length; i++) { _currentTasks = _assignments.filter(function (entry) { return entry.category == taskList[i].taskName; }); if (_currentTasks.length < charSettings[characterGetCurrent()][taskList[i].taskName]) { _log(taskList[i].taskName + ': ' + _currentTasks.length + '/' + charSettings[characterGetCurrent()][taskList[i].taskName] + ' filled.'); createNextTask(taskList[i], 0) .then( function() { _log('createNextTask(): done.'); dfdNextRun.resolve(); }); return true; } } _log("professionAssignTasks(): All task counts assigned."); return false; } catch (e) { } // if we got here stuff is still loading, let's wait another cycle _log('professionAssignTasks(): assignments still loading, wating.'); dfdNextRun.resolve(); return true; } function pagePROFESSIONS() { WaitForElement("") .then(function () { return professionCollectRewards(); }) .then( function () { // assign tasks if slots available if (professionAssignTasks()) { // dfdNextRun.resolve(); return; } // switch characters characterSwitch(); }); } function pageLOGIN() { if (globalSettings.autologin === true) { _log('pageLOGIN: logging in.'); $("input#user").val(globalSettings.nw_username); $("input#pass").val(globalSettings.nw_password); $("div#login > input").click(); } else { _log('pageLOGIN: auto logging in disabled.'); } dfdNextRun.resolve(delay.LONG); } /** * The main process loop: * - Determine which page we are on and call the page specific logic * - When processing is complete, process again later * - Use a short timer when something changed last time through * - Use a longer timer when waiting for tasks to complete */ function process() { _log('starting cycle'); // Make sure our custom HTML is injected and working injectHTML(); // Check if timer is paused if (globalSettings.paused) { // Just continue later - the deferred object is still set and nothing will resolve it until we get past this point _log('Paused...'); // clear the timeout clearTimeout(timeoutHandle); window.setTimeout(function () { process(); }, delay.DEFAULT); return; } // refine AD; page doesn't matter, no need to do resolve(); utilRefineAD(); switch (getCurrentPage()) { case pages.CHARSELECT: pageCHARSELECT(); break; case pages.FRONTPAGE: pageFRONTPAGE(); break; case pages.PROFESSIONS: pagePROFESSIONS(); break; case pages.LOGIN: pageLOGIN(); break; default: // _log('No logic defined for current page, sleeping for: ' + delay.LONG + 'ms.'); // dfdNextRun.resolve(delay.LONG); } // Continue again later dfdNextRun.done(function (delayTimer) { var _cycleDelay = delayTimer || delay.DEFAULT; var _cycleTimeout = _cycleDelay + delay.TIMEOUT; _log('Scheduling next cycle in: ' + _cycleDelay + 'ms. Timeout in: ' + _cycleTimeout + 'ms.'); dfdNextRun = $.Deferred(); // cycle succeeded, clear the timeout clearTimeout(timeoutHandle); // setting timeout for next cycle timeoutHandle = setTimeout(function () { dfdNextRun.reject(_cycleTimeout); }, _cycleTimeout); // scheduling next cycle setTimeout(function () { process(); }, _cycleDelay); }).fail(function (timeout) { _log('Last cycle took longer than: ' + timeout + 'ms. Reloading gateway...'); unsafeWindow.location.href = "http://gateway.playneverwinter.com"; }); } // inject our HTML and schedule main loop injectHTML(); _log('Script started.'); dfdNextRun.resolve(); setTimeout(function () { process(); }, delay.SHORT); })();