// ==UserScript== // @name Mooneycalc-Importer (Party battle) // @namespace http://tampermonkey.net/ // @version 1.4.9.7 // @description 脚本基于Mooneycalc-Importer v5.3,增加了组队模拟功能,使用时请手动查看队友装备以获取数据。https://amvoidguy.github.io/MWICombatSimulatorTest/dist/index.html. // @match https://www.milkywayidle.com/* // @match https://mooneycalc.vercel.app/* // @match https://tobytorn.github.io/mwisim.github.io/* // @match https://amvoidguy.github.io/MWICombatSimulatorTest/dist/index.html // @run-at document-start // @grant GM_getValue // @grant GM_setValue // @downloadURL none // ==/UserScript== (function () { "use strict"; const userLanguage = navigator.language || navigator.userLanguage; const isZH = userLanguage.startsWith("zh"); const SCRIPT_SIMULATE_TIME = "24";//模拟时长 //启动前先把所有队友的装备手动看一遍!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (document.URL.includes("milkywayidle.com")) { hookWS(); } else if (document.URL.includes("mooneycalc.vercel.app")) { addImportButton1(); } else if(document.URL.includes("MWICombatSimulatorTest")){ addImportButton4(); waitSimulationResultsLoading(); } function waitSimulationResultsLoading(){ const waitForNavi = () => { if(document.querySelector(`div.row`)?.querySelectorAll(`div.col-md-5`)?.[2]?.querySelector(`div.row > div.col-md-5`))observeResults(); else setTimeout(waitSimulationResultsLoading, 200); }; waitForNavi(); } function hookWS() { const dataProperty = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data"); const oriGet = dataProperty.get; dataProperty.get = hookedGet; Object.defineProperty(MessageEvent.prototype, "data", dataProperty); function hookedGet() { const socket = this.currentTarget; if (!(socket instanceof WebSocket)) { return oriGet.call(this); } if (socket.url.indexOf("api.milkywayidle.com/ws") <= -1) { return oriGet.call(this); } const message = oriGet.call(this); Object.defineProperty(this, "data", { value: message }); // Anti-loop return handleMessage(message); } } function handleMessage(message) { let obj = JSON.parse(message); if (obj && obj.type === "init_character_data") { //console.log(obj); GM_setValue("init_character_data", message); const init_client_data = localStorage.getItem("initClientData"); if(init_client_data)GM_setValue("init_client_data", init_client_data); }else if (obj && obj.type === "new_battle"){ //console.log(obj); GM_setValue("team_battle", message); }else if (obj && obj.type === "profile_shared"){ //console.log(obj); GM_setValue(obj.profile.sharableCharacter.name, message); get_sim_json(obj); } return message; } function get_sim_json(obj) { const checkElem = () => { const selectedElement = document.querySelector(`div.SharableProfile_overviewTab__W4dCV`); if (selectedElement) { clearInterval(timer); //获取模拟数据 let player_name=obj.profile.sharableCharacter.name; let exportObj = {}; exportObj.player = {}; exportObj.player.equipment = []; exportObj.houseRooms = {}; //装备 for (const key in obj.profile.wearableItemMap) { const item = obj.profile.wearableItemMap[key]; exportObj.player.equipment.push({ itemLocationHrid: item.itemLocationHrid, itemHrid: item.itemHrid, enhancementLevel: item.enhancementLevel, }); } //别人房子 for (const house of Object.values(obj.profile.characterHouseRoomMap)) { exportObj.houseRooms[house.houseRoomHrid] = house.level; } //技能等级 for (const skill of obj.profile.characterSkills) { if (skill.skillHrid.includes("stamina")) { exportObj.player.staminaLevel = skill.level; } else if (skill.skillHrid.includes("intelligence")) { exportObj.player.intelligenceLevel = skill.level; } else if (skill.skillHrid.includes("attack")) { exportObj.player.attackLevel = skill.level; } else if (skill.skillHrid.includes("power")) { exportObj.player.powerLevel = skill.level; } else if (skill.skillHrid.includes("defense")) { exportObj.player.defenseLevel = skill.level; } else if (skill.skillHrid.includes("ranged")) { exportObj.player.rangedLevel = skill.level; } else if (skill.skillHrid.includes("magic")) { exportObj.player.magicLevel = skill.level; } } //战斗技能等级 exportObj.abilities = [ { abilityHrid: "", level: "1", }, { abilityHrid: "", level: "1", }, { abilityHrid: "", level: "1", }, { abilityHrid: "", level: "1", }, { abilityHrid: "", level: "1", }, ]; let clientObj = JSON.parse(GM_getValue("init_client_data")); let normalAbillityIndex = 1; for (const ability of obj.profile.equippedAbilities) { if (ability && clientObj.abilityDetailMap[ability.abilityHrid].isSpecialAbility) { exportObj.abilities[0] = { abilityHrid: ability.abilityHrid, level: ability.level, }; } else if (ability) { exportObj.abilities[normalAbillityIndex++] = { abilityHrid: ability.abilityHrid, level: ability.level, }; } } //吃喝 exportObj.food={}; exportObj.drinks={}; exportObj.food["/action_types/combat"] = []; exportObj.drinks["/action_types/combat"] = []; let weapon=obj.profile.wearableItemMap["/item_locations/main_hand"]?.itemHrid||obj.profile.wearableItemMap["/item_locations/two_hand"]?.itemHrid; if(weapon.includes("shooter")||weapon.includes("bow")){ //远程 // xp,超远,暴击 exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/wisdom_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/super_ranged_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/critical_coffee" }); // 2红1蓝 exportObj.food["/action_types/combat"].push({ itemHrid:"/items/spaceberry_donut" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/spaceberry_cake" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/star_fruit_yogurt" }); }else if (weapon.includes("boomstick")||weapon.includes("staff")){ //法师 //xp,超魔,吟唱 exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/wisdom_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/super_magic_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/channeling_coffee" }); // 1红2蓝 exportObj.food["/action_types/combat"].push({ itemHrid:"/items/spaceberry_cake" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/star_fruit_gummy" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/star_fruit_yogurt" }); }else if (weapon.includes("bulwark")){ //双手盾 精暮光 //xp,超防,超耐 xp,超智,幸运 exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/wisdom_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/super_defense_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/super_stamina_coffee" }); // 2红1蓝 exportObj.food["/action_types/combat"].push({ itemHrid:"/items/spaceberry_donut" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/spaceberry_cake" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/star_fruit_yogurt" }); }else{ //战士 //xp,超力,迅捷 exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/wisdom_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/super_power_coffee" }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"/items/swiftness_coffee" }); // 2红1蓝 exportObj.food["/action_types/combat"].push({ itemHrid:"/items/spaceberry_donut" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/spaceberry_cake" }); exportObj.food["/action_types/combat"].push({ itemHrid:"/items/star_fruit_yogurt" }); } //队内检测 let team_data = GM_getValue("team_battle", ""); let team_obj = JSON.parse(team_data); if(team_obj){ for(const team_member of team_obj.players){ if(team_member.name==player_name){ for(const food_or_drink of team_member.combatConsumables){ if(food_or_drink.itemHrid.includes('coffee')){ exportObj.drinks["/action_types/combat"].push({ itemHrid:food_or_drink.itemHrid, }); }else{ exportObj.food["/action_types/combat"].push({ itemHrid:food_or_drink.itemHrid, }); } } } } } //我不知道有什么用,以防万一写一下,和原版保持一致 exportObj.food["/action_types/combat"].push({ itemHrid:"", }); exportObj.drinks["/action_types/combat"].push({ itemHrid:"", }); let sim_json_value=JSON.stringify(exportObj); //按钮粘贴 let button = document.createElement("button"); selectedElement.appendChild(button); button.textContent = "获取模拟器导入数据"; button.style.borderRadius = '5px'; button.style.height = '30px'; button.style.backgroundColor = '#4357AF'; button.style.color = 'white'; button.style.boxShadow = 'none'; button.style.border = '0px'; button.onclick = function () { navigator.clipboard.writeText(sim_json_value); button.textContent = "导入数据已粘贴到剪切板"; return false; }; return false; }; }; let timer = setInterval(checkElem, 200); } function addImportButton1() { const checkElem = () => { const selectedElement = document.querySelector(`div[role="tablist"]`); if (selectedElement) { clearInterval(timer); console.log("Mooneycalc-Importer: Found elem"); let button = document.createElement("button"); selectedElement.parentNode.insertBefore(button, selectedElement.nextSibling); button.textContent = isZH ? "导入人物数据 (刷新游戏网页更新人物数据; 左边Market设置里可以改进货价出货价)" : "Import character settings (Refresh game page to update character settings)"; button.style.backgroundColor = "green"; button.style.padding = "5px"; button.onclick = function () { console.log("Mooneycalc-Importer: Button onclick"); importData1(button); return false; }; } }; let timer = setInterval(checkElem, 200); } async function importData1(button) { let data = GM_getValue("init_character_data"); let obj = JSON.parse(data); console.log(obj); if (!obj || !obj.characterSkills || !obj.currentTimestamp) { button.textContent = isZH ? "错误:没有人物数据" : "Error: no character settings found"; return; } let ls = constructMooneycalcLocalStorage(obj); localStorage.setItem("settings", ls); let timestamp = new Date(obj.currentTimestamp).getTime(); let now = new Date().getTime(); button.textContent = isZH ? "已导入,人物数据更新时间:" + timeReadable(now - timestamp) + " 前" : "Imported, updated " + timeReadable(now - timestamp) + " ago"; await new Promise((r) => setTimeout(r, 500)); location.reload(); } function constructMooneycalcLocalStorage(obj) { const websiteSupportedEquipmentsMap = new Map([ ["/items/abyssal_essence", true], ["/items/advanced_task_ring", true], ["/items/amber", true], ["/items/amethyst", true], ["/items/apple", true], ["/items/apple_gummy", true], ["/items/apple_yogurt", true], ["/items/aqua_arrow", true], ["/items/aqua_essence", true], ["/items/arabica_coffee_bean", true], ["/items/arcane_bow", true], ["/items/arcane_crossbow", true], ["/items/arcane_fire_staff", true], ["/items/arcane_log", true], ["/items/arcane_lumber", true], ["/items/arcane_nature_staff", true], ["/items/arcane_shield", true], ["/items/arcane_water_staff", true], ["/items/artisan_tea", true], ["/items/attack_coffee", true], ["/items/azure_boots", true], ["/items/azure_brush", true], ["/items/azure_buckler", true], ["/items/azure_bulwark", true], ["/items/azure_cheese", true], ["/items/azure_chisel", true], ["/items/azure_enhancer", true], ["/items/azure_gauntlets", true], ["/items/azure_hammer", true], ["/items/azure_hatchet", true], ["/items/azure_helmet", true], ["/items/azure_mace", true], ["/items/azure_milk", true], ["/items/azure_needle", true], ["/items/azure_plate_body", true], ["/items/azure_plate_legs", true], ["/items/azure_pot", true], ["/items/azure_shears", true], ["/items/azure_spatula", true], ["/items/azure_spear", true], ["/items/azure_sword", true], ["/items/bag_of_10_cowbells", true], ["/items/bamboo_boots", true], ["/items/bamboo_branch", true], ["/items/bamboo_fabric", true], ["/items/bamboo_gloves", true], ["/items/bamboo_hat", true], ["/items/bamboo_robe_bottoms", true], ["/items/bamboo_robe_top", true], ["/items/basic_task_ring", true], ["/items/bear_essence", true], ["/items/beast_boots", true], ["/items/beast_bracers", true], ["/items/beast_chaps", true], ["/items/beast_hide", true], ["/items/beast_hood", true], ["/items/beast_leather", true], ["/items/beast_tunic", true], ["/items/berserk", true], ["/items/birch_bow", true], ["/items/birch_crossbow", true], ["/items/birch_fire_staff", true], ["/items/birch_log", true], ["/items/birch_lumber", true], ["/items/birch_nature_staff", true], ["/items/birch_shield", true], ["/items/birch_water_staff", true], ["/items/black_bear_fluff", true], ["/items/black_bear_shoes", true], ["/items/black_tea_leaf", true], ["/items/blackberry", true], ["/items/blackberry_cake", true], ["/items/blackberry_donut", true], ["/items/blessed_tea", true], ["/items/blueberry", true], ["/items/blueberry_cake", true], ["/items/blueberry_donut", true], ["/items/brewing_tea", true], ["/items/burble_boots", true], ["/items/burble_brush", true], ["/items/burble_buckler", true], ["/items/burble_bulwark", true], ["/items/burble_cheese", true], ["/items/burble_chisel", true], ["/items/burble_enhancer", true], ["/items/burble_gauntlets", true], ["/items/burble_hammer", true], ["/items/burble_hatchet", true], ["/items/burble_helmet", true], ["/items/burble_mace", true], ["/items/burble_milk", true], ["/items/burble_needle", true], ["/items/burble_plate_body", true], ["/items/burble_plate_legs", true], ["/items/burble_pot", true], ["/items/burble_shears", true], ["/items/burble_spatula", true], ["/items/burble_spear", true], ["/items/burble_sword", true], ["/items/burble_tea_leaf", true], ["/items/cedar_bow", true], ["/items/cedar_crossbow", true], ["/items/cedar_fire_staff", true], ["/items/cedar_log", true], ["/items/cedar_lumber", true], ["/items/cedar_nature_staff", true], ["/items/cedar_shield", true], ["/items/cedar_water_staff", true], ["/items/centaur_boots", true], ["/items/centaur_hoof", true], ["/items/channeling_coffee", true], ["/items/cheese", true], ["/items/cheese_boots", true], ["/items/cheese_brush", true], ["/items/cheese_buckler", true], ["/items/cheese_bulwark", true], ["/items/cheese_chisel", true], ["/items/cheese_enhancer", true], ["/items/cheese_gauntlets", true], ["/items/cheese_hammer", true], ["/items/cheese_hatchet", true], ["/items/cheese_helmet", true], ["/items/cheese_mace", true], ["/items/cheese_needle", true], ["/items/cheese_plate_body", true], ["/items/cheese_plate_legs", true], ["/items/cheese_pot", true], ["/items/cheese_shears", true], ["/items/cheese_spatula", true], ["/items/cheese_spear", true], ["/items/cheese_sword", true], ["/items/cheesesmithing_tea", true], ["/items/chrono_gloves", true], ["/items/chrono_sphere", true], ["/items/cleave", true], ["/items/cocoon", true], ["/items/coin", true], ["/items/collectors_boots", true], ["/items/colossus_core", true], ["/items/colossus_plate_body", true], ["/items/colossus_plate_legs", true], ["/items/cooking_tea", true], ["/items/cotton", true], ["/items/cotton_boots", true], ["/items/cotton_fabric", true], ["/items/cotton_gloves", true], ["/items/cotton_hat", true], ["/items/cotton_robe_bottoms", true], ["/items/cotton_robe_top", true], ["/items/cowbell", true], ["/items/crab_pincer", true], ["/items/crafting_tea", true], ["/items/crimson_boots", true], ["/items/crimson_brush", true], ["/items/crimson_buckler", true], ["/items/crimson_bulwark", true], ["/items/crimson_cheese", true], ["/items/crimson_chisel", true], ["/items/crimson_enhancer", true], ["/items/crimson_gauntlets", true], ["/items/crimson_hammer", true], ["/items/crimson_hatchet", true], ["/items/crimson_helmet", true], ["/items/crimson_mace", true], ["/items/crimson_milk", true], ["/items/crimson_needle", true], ["/items/crimson_plate_body", true], ["/items/crimson_plate_legs", true], ["/items/crimson_pot", true], ["/items/crimson_shears", true], ["/items/crimson_spatula", true], ["/items/crimson_spear", true], ["/items/crimson_sword", true], ["/items/critical_coffee", true], ["/items/crushed_amber", true], ["/items/crushed_amethyst", true], ["/items/crushed_garnet", true], ["/items/crushed_jade", true], ["/items/crushed_moonstone", true], ["/items/crushed_pearl", true], ["/items/cupcake", true], ["/items/defense_coffee", true], ["/items/demonic_core", true], ["/items/demonic_plate_body", true], ["/items/demonic_plate_legs", true], ["/items/donut", true], ["/items/dragon_fruit", true], ["/items/dragon_fruit_gummy", true], ["/items/dragon_fruit_yogurt", true], ["/items/earrings_of_armor", true], ["/items/earrings_of_gathering", true], ["/items/earrings_of_rare_find", true], ["/items/earrings_of_regeneration", true], ["/items/earrings_of_resistance", true], ["/items/efficiency_tea", true], ["/items/egg", true], ["/items/elemental_affinity", true], ["/items/elusiveness", true], ["/items/emp_tea_leaf", true], ["/items/enchanted_gloves", true], ["/items/enhancing_tea", true], ["/items/entangle", true], ["/items/excelsa_coffee_bean", true], ["/items/expert_task_ring", true], ["/items/eye_of_the_watcher", true], ["/items/eye_watch", true], ["/items/eyessence", true], ["/items/fieriosa_coffee_bean", true], ["/items/fighter_necklace", true], ["/items/fireball", true], ["/items/firestorm", true], ["/items/flame_arrow", true], ["/items/flame_blast", true], ["/items/flaming_cloth", true], ["/items/flaming_robe_bottoms", true], ["/items/flaming_robe_top", true], ["/items/flax", true], ["/items/fluffy_red_hat", true], ["/items/foraging_tea", true], ["/items/frenzy", true], ["/items/frost_sphere", true], ["/items/frost_staff", true], ["/items/frost_surge", true], ["/items/garnet", true], ["/items/gathering_tea", true], ["/items/gator_vest", true], ["/items/giant_pouch", true], ["/items/ginkgo_bow", true], ["/items/ginkgo_crossbow", true], ["/items/ginkgo_fire_staff", true], ["/items/ginkgo_log", true], ["/items/ginkgo_lumber", true], ["/items/ginkgo_nature_staff", true], ["/items/ginkgo_shield", true], ["/items/ginkgo_water_staff", true], ["/items/gobo_boomstick", true], ["/items/gobo_boots", true], ["/items/gobo_bracers", true], ["/items/gobo_chaps", true], ["/items/gobo_defender", true], ["/items/gobo_essence", true], ["/items/gobo_hide", true], ["/items/gobo_hood", true], ["/items/gobo_leather", true], ["/items/gobo_rag", true], ["/items/gobo_shooter", true], ["/items/gobo_slasher", true], ["/items/gobo_smasher", true], ["/items/gobo_stabber", true], ["/items/gobo_tunic", true], ["/items/goggles", true], ["/items/golem_essence", true], ["/items/gourmet_tea", true], ["/items/granite_bludgeon", true], ["/items/green_tea_leaf", true], ["/items/grizzly_bear_fluff", true], ["/items/grizzly_bear_shoes", true], ["/items/gummy", true], ["/items/heal", true], ["/items/holy_boots", true], ["/items/holy_brush", true], ["/items/holy_buckler", true], ["/items/holy_bulwark", true], ["/items/holy_cheese", true], ["/items/holy_chisel", true], ["/items/holy_enhancer", true], ["/items/holy_gauntlets", true], ["/items/holy_hammer", true], ["/items/holy_hatchet", true], ["/items/holy_helmet", true], ["/items/holy_mace", true], ["/items/holy_milk", true], ["/items/holy_needle", true], ["/items/holy_plate_body", true], ["/items/holy_plate_legs", true], ["/items/holy_pot", true], ["/items/holy_shears", true], ["/items/holy_spatula", true], ["/items/holy_spear", true], ["/items/holy_sword", true], ["/items/ice_spear", true], ["/items/icy_cloth", true], ["/items/icy_robe_bottoms", true], ["/items/icy_robe_top", true], ["/items/infernal_battlestaff", true], ["/items/infernal_ember", true], ["/items/intelligence_coffee", true], ["/items/jade", true], ["/items/jungle_essence", true], ["/items/large_artisans_crate", true], ["/items/large_meteorite_cache", true], ["/items/large_pouch", true], ["/items/large_treasure_chest", true], ["/items/liberica_coffee_bean", true], ["/items/linen_boots", true], ["/items/linen_fabric", true], ["/items/linen_gloves", true], ["/items/linen_hat", true], ["/items/linen_robe_bottoms", true], ["/items/linen_robe_top", true], ["/items/living_granite", true], ["/items/log", true], ["/items/lucky_coffee", true], ["/items/lumber", true], ["/items/luna_robe_bottoms", true], ["/items/luna_robe_top", true], ["/items/luna_wing", true], ["/items/magic_coffee", true], ["/items/magnet", true], ["/items/magnetic_gloves", true], ["/items/magnifying_glass", true], ["/items/maim", true], ["/items/marine_chaps", true], ["/items/marine_scale", true], ["/items/marine_tunic", true], ["/items/marsberry", true], ["/items/marsberry_cake", true], ["/items/marsberry_donut", true], ["/items/medium_artisans_crate", true], ["/items/medium_meteorite_cache", true], ["/items/medium_pouch", true], ["/items/medium_treasure_chest", true], ["/items/milk", true], ["/items/milking_tea", true], ["/items/minor_heal", true], ["/items/mirror_of_protection", true], ["/items/mooberry", true], ["/items/mooberry_cake", true], ["/items/mooberry_donut", true], ["/items/moolong_tea_leaf", true], ["/items/moonstone", true], ["/items/natures_veil", true], ["/items/necklace_of_efficiency", true], ["/items/necklace_of_wisdom", true], ["/items/orange", true], ["/items/orange_gummy", true], ["/items/orange_yogurt", true], ["/items/panda_fluff", true], ["/items/panda_gloves", true], ["/items/peach", true], ["/items/peach_gummy", true], ["/items/peach_yogurt", true], ["/items/pearl", true], ["/items/pierce", true], ["/items/pincer_gloves", true], ["/items/plum", true], ["/items/plum_gummy", true], ["/items/plum_yogurt", true], ["/items/poke", true], ["/items/polar_bear_fluff", true], ["/items/polar_bear_shoes", true], ["/items/power_coffee", true], ["/items/precision", true], ["/items/processing_tea", true], ["/items/puncture", true], ["/items/purpleheart_bow", true], ["/items/purpleheart_crossbow", true], ["/items/purpleheart_fire_staff", true], ["/items/purpleheart_log", true], ["/items/purpleheart_lumber", true], ["/items/purpleheart_nature_staff", true], ["/items/purpleheart_shield", true], ["/items/purpleheart_water_staff", true], ["/items/purples_gift", true], ["/items/quick_shot", true], ["/items/radiant_boots", true], ["/items/radiant_fabric", true], ["/items/radiant_fiber", true], ["/items/radiant_gloves", true], ["/items/radiant_hat", true], ["/items/radiant_robe_bottoms", true], ["/items/radiant_robe_top", true], ["/items/rain_of_arrows", true], ["/items/rainbow_boots", true], ["/items/rainbow_brush", true], ["/items/rainbow_buckler", true], ["/items/rainbow_bulwark", true], ["/items/rainbow_cheese", true], ["/items/rainbow_chisel", true], ["/items/rainbow_enhancer", true], ["/items/rainbow_gauntlets", true], ["/items/rainbow_hammer", true], ["/items/rainbow_hatchet", true], ["/items/rainbow_helmet", true], ["/items/rainbow_mace", true], ["/items/rainbow_milk", true], ["/items/rainbow_needle", true], ["/items/rainbow_plate_body", true], ["/items/rainbow_plate_legs", true], ["/items/rainbow_pot", true], ["/items/rainbow_shears", true], ["/items/rainbow_spatula", true], ["/items/rainbow_spear", true], ["/items/rainbow_sword", true], ["/items/ranged_coffee", true], ["/items/ranger_necklace", true], ["/items/red_chefs_hat", true], ["/items/red_panda_fluff", true], ["/items/red_tea_leaf", true], ["/items/redwood_bow", true], ["/items/redwood_crossbow", true], ["/items/redwood_fire_staff", true], ["/items/redwood_log", true], ["/items/redwood_lumber", true], ["/items/redwood_nature_staff", true], ["/items/redwood_shield", true], ["/items/redwood_water_staff", true], ["/items/reptile_boots", true], ["/items/reptile_bracers", true], ["/items/reptile_chaps", true], ["/items/reptile_hide", true], ["/items/reptile_hood", true], ["/items/reptile_leather", true], ["/items/reptile_tunic", true], ["/items/revenant_anima", true], ["/items/revenant_chaps", true], ["/items/revenant_tunic", true], ["/items/ring_of_armor", true], ["/items/ring_of_gathering", true], ["/items/ring_of_rare_find", true], ["/items/ring_of_regeneration", true], ["/items/ring_of_resistance", true], ["/items/robusta_coffee_bean", true], ["/items/rough_boots", true], ["/items/rough_bracers", true], ["/items/rough_chaps", true], ["/items/rough_hide", true], ["/items/rough_hood", true], ["/items/rough_leather", true], ["/items/rough_tunic", true], ["/items/scratch", true], ["/items/shard_of_protection", true], ["/items/shoebill_feather", true], ["/items/shoebill_shoes", true], ["/items/sighted_bracers", true], ["/items/silencing_shot", true], ["/items/silk_boots", true], ["/items/silk_fabric", true], ["/items/silk_gloves", true], ["/items/silk_hat", true], ["/items/silk_robe_bottoms", true], ["/items/silk_robe_top", true], ["/items/smack", true], ["/items/small_artisans_crate", true], ["/items/small_meteorite_cache", true], ["/items/small_pouch", true], ["/items/small_treasure_chest", true], ["/items/snail_shell", true], ["/items/snail_shell_helmet", true], ["/items/snake_fang", true], ["/items/snake_fang_dirk", true], ["/items/sorcerer_boots", true], ["/items/sorcerer_essence", true], ["/items/sorcerers_sole", true], ["/items/soul_fragment", true], ["/items/soul_hunter_crossbow", true], ["/items/spaceberry", true], ["/items/spaceberry_cake", true], ["/items/spaceberry_donut", true], ["/items/spacia_coffee_bean", true], ["/items/spike_shell", true], ["/items/spiked_bulwark", true], ["/items/stalactite_shard", true], ["/items/stalactite_spear", true], ["/items/stamina_coffee", true], ["/items/star_fragment", true], ["/items/star_fruit", true], ["/items/star_fruit_gummy", true], ["/items/star_fruit_yogurt", true], ["/items/steady_shot", true], ["/items/strawberry", true], ["/items/strawberry_cake", true], ["/items/strawberry_donut", true], ["/items/stunning_blow", true], ["/items/sugar", true], ["/items/super_attack_coffee", true], ["/items/super_brewing_tea", true], ["/items/super_cheesesmithing_tea", true], ["/items/super_cooking_tea", true], ["/items/super_crafting_tea", true], ["/items/super_defense_coffee", true], ["/items/super_enhancing_tea", true], ["/items/super_foraging_tea", true], ["/items/super_intelligence_coffee", true], ["/items/super_magic_coffee", true], ["/items/super_milking_tea", true], ["/items/super_power_coffee", true], ["/items/super_ranged_coffee", true], ["/items/super_stamina_coffee", true], ["/items/super_tailoring_tea", true], ["/items/super_woodcutting_tea", true], ["/items/swamp_essence", true], ["/items/sweep", true], ["/items/swiftness_coffee", true], ["/items/tailoring_tea", true], ["/items/task_crystal", true], ["/items/task_token", true], ["/items/tome_of_healing", true], ["/items/tome_of_the_elements", true], ["/items/toughness", true], ["/items/toxic_pollen", true], ["/items/treant_bark", true], ["/items/treant_shield", true], ["/items/turtle_shell", true], ["/items/turtle_shell_body", true], ["/items/turtle_shell_legs", true], ["/items/twilight_essence", true], ["/items/umbral_boots", true], ["/items/umbral_bracers", true], ["/items/umbral_chaps", true], ["/items/umbral_hide", true], ["/items/umbral_hood", true], ["/items/umbral_leather", true], ["/items/umbral_tunic", true], ["/items/vampire_fang", true], ["/items/vampire_fang_dirk", true], ["/items/vampiric_bow", true], ["/items/vampirism", true], ["/items/verdant_boots", true], ["/items/verdant_brush", true], ["/items/verdant_buckler", true], ["/items/verdant_bulwark", true], ["/items/verdant_cheese", true], ["/items/verdant_chisel", true], ["/items/verdant_enhancer", true], ["/items/verdant_gauntlets", true], ["/items/verdant_hammer", true], ["/items/verdant_hatchet", true], ["/items/verdant_helmet", true], ["/items/verdant_mace", true], ["/items/verdant_milk", true], ["/items/verdant_needle", true], ["/items/verdant_plate_body", true], ["/items/verdant_plate_legs", true], ["/items/verdant_pot", true], ["/items/verdant_shears", true], ["/items/verdant_spatula", true], ["/items/verdant_spear", true], ["/items/verdant_sword", true], ["/items/vision_helmet", true], ["/items/vision_shield", true], ["/items/watchful_relic", true], ["/items/water_strike", true], ["/items/werewolf_claw", true], ["/items/werewolf_slasher", true], ["/items/wheat", true], ["/items/wisdom_coffee", true], ["/items/wisdom_tea", true], ["/items/wizard_necklace", true], ["/items/woodcutting_tea", true], ["/items/wooden_bow", true], ["/items/wooden_crossbow", true], ["/items/wooden_fire_staff", true], ["/items/wooden_nature_staff", true], ["/items/wooden_shield", true], ["/items/wooden_water_staff", true], ["/items/yogurt", true], ]); const ls = localStorage.getItem("settings"); let lsObj = JSON.parse(ls); // 人物技能等级 lsObj.state.settings.levels = {}; for (const skill of obj.characterSkills) { lsObj.state.settings.levels[skill.skillHrid] = skill.level; } // 社区全局buff lsObj.state.settings.communityBuffs = {}; for (const buff of obj.communityBuffs) { lsObj.state.settings.communityBuffs[buff.hrid] = buff.level; } // 装备 & 装备强化等级 lsObj.state.settings.equipment = {}; lsObj.state.settings.equipmentLevels = {}; for (const item of obj.characterItems) { if (item.itemLocationHrid !== "/item_locations/inventory" && websiteSupportedEquipmentsMap.has(item.itemHrid)) { lsObj.state.settings.equipment[item.itemLocationHrid.replace("item_locations", "equipment_types")] = item.itemHrid; lsObj.state.settings.equipmentLevels[item.itemLocationHrid.replace("item_locations", "equipment_types")] = item.enhancementLevel; } } // 房子 lsObj.state.settings.houseRooms = {}; for (const house of Object.values(obj.characterHouseRoomMap)) { if(house.houseRoomHrid=="/house_rooms/observatory"||house.houseRoomHrid=="/house_rooms/laboratory")continue; lsObj.state.settings.houseRooms[house.houseRoomHrid] = house.level; } return JSON.stringify(lsObj); } function timeReadable(ms) { const d = new Date(1000 * Math.round(ms / 1000)); function pad(i) { return ("0" + i).slice(-2); } let str = d.getUTCHours() + ":" + pad(d.getUTCMinutes()) + ":" + pad(d.getUTCSeconds()); console.log("Mooneycalc-Importer: " + str); return str; } function addImportButton4() { const checkElem = () => { const selectedElement = document.querySelector(`button#buttonImportExport`); if (selectedElement) { clearInterval(timer); console.log("Mooneycalc-Importer: Found elem"); let button = document.createElement("button"); selectedElement.parentNode.parentElement.parentElement.insertBefore(button, selectedElement.parentElement.parentElement.nextSibling); button.textContent = isZH ? "导入人物数据(刷新游戏网页更新人物数据)" : "Import character settings (Refresh game page to update character settings)"; button.style.backgroundColor = "green"; button.style.padding = "5px"; button.onclick = function () { console.log("Mooneycalc-Importer: Button onclick"); const getPriceButton = document.querySelector(`button#buttonGetPrices`); if (getPriceButton) { console.log("Click getPriceButton"); getPriceButton.click(); } importData4(button); return false; }; } }; let timer = setInterval(checkElem, 200); } async function importData4(button) { let data = GM_getValue("team_battle", ""); let obj = JSON.parse(data); if (!obj) { button.textContent = isZH ? "错误:没有人物数据" : "Error: no character settings found"; return; } const jsonObj = constructImportJsonObj_team(obj); console.log(jsonObj); for(let i=1;i<=jsonObj.player_number;i++){ const importInputElem = document.querySelector(`input#inputSetGroupCombatplayer`+i); importInputElem.value = JSON.stringify(jsonObj.players[i-1]); } document.querySelector(`button#buttonImportSet`).click(); let timestamp = new Date(obj.currentTimestamp).getTime(); let now = new Date().getTime(); button.textContent = isZH ? "已导入,人物数据更新时间:" + timeReadable(now - timestamp) + " 前" : "Imported, updated " + timeReadable(now - timestamp) + " ago"; if (document.URL.includes(`//amvoidguy.github.io/`)) { setTimeout(() => { const selectZone = document.querySelector(`select#selectZone`); for (let i = 0; i < selectZone.options.length; i++) { if (selectZone.options[i].value == jsonObj.zone) { selectZone.options[i].selected = true; break; } } const player1Checkbox = document.querySelector(`input#player1.form-check-input.player-checkbox`); const player2Checkbox = document.querySelector(`input#player2.form-check-input.player-checkbox`); const player3Checkbox = document.querySelector(`input#player3.form-check-input.player-checkbox`); switch (jsonObj.player_number) { case 1: player1Checkbox.checked = true; break; case 2: player1Checkbox.checked = true; player2Checkbox.checked = true; break; case 3: player1Checkbox.checked = true; player2Checkbox.checked = true; player3Checkbox.checked = true; break; } const time_set = document.querySelector(`input#inputSimulationTime`); time_set.value=jsonObj.simulationTime //无法获取别人的触发器会报错 const errorModal = document.querySelector('div#errorModal'); if (errorModal) { errorModal.parentNode.removeChild(errorModal); } document.querySelector(`button#buttonStartSimulation`).click(); document.querySelector(`button.btn.btn-secondary`).click(); }, 500); } } function constructImportJsonObj_team(obj) { let clientObj = JSON.parse(GM_getValue("init_client_data")); let init_character_obj = JSON.parse(GM_getValue("init_character_data")); let exportObj = {}; exportObj.player_number=obj.players.length; exportObj.players = {}; //看一圈所有人配置 for(let player_num=0;player_num div.col-md-5`); if(document.URL.includes("mwisim.github.io")||document.URL.includes("simTest")){ resultDiv = document.querySelectorAll(`div.row`)?.[1]?.querySelectorAll(`div.col-md-5`)?.[2]?.querySelector(`div.row > div.col-md-5`); } const deathDiv = document.querySelector(`div#simulationResultPlayerDeaths`); const expDiv = document.querySelector(`div#simulationResultExperienceGain`); const consumeDiv = document.querySelector(`div#simulationResultConsumablesUsed`); deathDiv.style.backgroundColor = "#FFEAE9"; deathDiv.style.color = "black"; expDiv.style.backgroundColor = "#CDFFDD"; expDiv.style.color = "black"; consumeDiv.style.backgroundColor = "#F0F8FF"; consumeDiv.style.color = "black"; let div = document.createElement("div"); div.id = "tillLevel"; div.style.backgroundColor = "#FFFFE0"; div.style.color = "black"; div.textContent = ""; resultDiv.append(div); new MutationObserver((mutationsList) => { mutationsList.forEach((mutation) => { if (mutation.addedNodes.length >= 3) { handleResult(mutation.addedNodes, div); } }); }).observe(expDiv, { childList: true, subtree: true }); } function handleResult(expNodes, parentDiv) { let perHourGainExp = { stamina: 0, intelligence: 0, attack: 0, power: 0, defense: 0, ranged: 0, magic: 0, }; expNodes.forEach((expNodes) => { if (expNodes.textContent.includes("Stamina")||expNodes.textContent.includes("耐力")) { perHourGainExp.stamina = Number(expNodes.children[1].textContent); } else if (expNodes.textContent.includes("Intelligence")||expNodes.textContent.includes("智力")) { perHourGainExp.intelligence = Number(expNodes.children[1].textContent); } else if (expNodes.textContent.includes("Attack")||expNodes.textContent.includes("攻击")) { perHourGainExp.attack = Number(expNodes.children[1].textContent); } else if (expNodes.textContent.includes("Power")||expNodes.textContent.includes("力量")) { perHourGainExp.power = Number(expNodes.children[1].textContent); } else if (expNodes.textContent.includes("Defense")||expNodes.textContent.includes("防御")) { perHourGainExp.defense = Number(expNodes.children[1].textContent); } else if (expNodes.textContent.includes("Ranged")||expNodes.textContent.includes("远程")) { perHourGainExp.ranged = Number(expNodes.children[1].textContent); } else if (expNodes.textContent.includes("Magic")||expNodes.textContent.includes("魔法")) { perHourGainExp.magic = Number(expNodes.children[1].textContent); } }); let data = GM_getValue("init_character_data"); let obj = JSON.parse(data); if (!obj || !obj.characterSkills || !obj.currentTimestamp) { console.error("handleResult no character localstorage"); return; } let skillLevels = {}; for (const skill of obj.characterSkills) { if (skill.skillHrid.includes("stamina")) { skillLevels.stamina = {}; skillLevels.stamina.skillName = "Stamina"; skillLevels.stamina.currentLevel = skill.level; skillLevels.stamina.currentExp = skill.experience; } else if (skill.skillHrid.includes("intelligence")) { skillLevels.intelligence = {}; skillLevels.intelligence.skillName = "Intelligence"; skillLevels.intelligence.currentLevel = skill.level; skillLevels.intelligence.currentExp = skill.experience; } else if (skill.skillHrid.includes("attack")) { skillLevels.attack = {}; skillLevels.attack.skillName = "Attack"; skillLevels.attack.currentLevel = skill.level; skillLevels.attack.currentExp = skill.experience; } else if (skill.skillHrid.includes("power")) { skillLevels.power = {}; skillLevels.power.skillName = "Power"; skillLevels.power.currentLevel = skill.level; skillLevels.power.currentExp = skill.experience; } else if (skill.skillHrid.includes("defense")) { skillLevels.defense = {}; skillLevels.defense.skillName = "Defense"; skillLevels.defense.currentLevel = skill.level; skillLevels.defense.currentExp = skill.experience; } else if (skill.skillHrid.includes("ranged")) { skillLevels.ranged = {}; skillLevels.ranged.skillName = "Ranged"; skillLevels.ranged.currentLevel = skill.level; skillLevels.ranged.currentExp = skill.experience; } else if (skill.skillHrid.includes("magic")) { skillLevels.magic = {}; skillLevels.magic.skillName = "Magic"; skillLevels.magic.currentLevel = skill.level; skillLevels.magic.currentExp = skill.experience; } } const skillNamesInOrder = ["stamina", "intelligence", "attack", "power", "defense", "ranged", "magic"]; let hTMLStr = ""; for (const skill of skillNamesInOrder) { hTMLStr += `
${skillLevels[skill].skillName}${ isZH ? "到" : " to level " }${isZH ? "级" : ""}
`; } hTMLStr += `
${ isZH ? "天后" : "days after" }
`; hTMLStr += `
`; hTMLStr += `
`; parentDiv.innerHTML = hTMLStr; for (const skill of skillNamesInOrder) { const skillDiv = parentDiv.querySelector(`div#${"inputDiv_" + skill}`); const skillInput = parentDiv.querySelector(`input#${"input_" + skill}`); skillInput.onchange = () => { calculateTill(skill, skillInput, skillLevels, parentDiv, perHourGainExp); }; skillInput.addEventListener("keyup", function (evt) { calculateTill(skill, skillInput, skillLevels, parentDiv, perHourGainExp); }); skillDiv.onclick = () => { calculateTill(skill, skillInput, skillLevels, parentDiv, perHourGainExp); }; } const daysAfterDiv = parentDiv.querySelector(`div#script_afterDays`); const daysAfterInput = parentDiv.querySelector(`input#script_afterDays_input`); daysAfterInput.onchange = () => { calculateAfterDays(daysAfterInput, skillLevels, parentDiv, perHourGainExp, skillNamesInOrder); }; daysAfterInput.addEventListener("keyup", function (evt) { calculateAfterDays(daysAfterInput, skillLevels, parentDiv, perHourGainExp, skillNamesInOrder); }); daysAfterDiv.onclick = () => { calculateAfterDays(daysAfterInput, skillLevels, parentDiv, perHourGainExp, skillNamesInOrder); }; // 提取成本和收益 const expensesSpan = document.querySelector(`span#expensesSpan`); const revenueSpan = document.querySelector(`span#revenueSpan`); const profitSpan = document.querySelector(`span#profitPreview`); const expenseDiv = document.querySelector(`div#script_expense`); const revenueDiv = document.querySelector(`div#script_revenue`); if (expenseDiv && expenseDiv) { expenseDiv.textContent = expensesSpan.parentNode.textContent; revenueDiv.textContent = revenueSpan.parentNode.textContent; } else { profitSpan.parentNode.insertAdjacentHTML( "beforeend", `
${expensesSpan.parentNode.textContent}
${revenueSpan.parentNode.textContent}
` ); } } function calculateAfterDays(daysAfterInput, skillLevels, parentDiv, perHourGainExp, skillNamesInOrder) { const initData_levelExperienceTable = JSON.parse(GM_getValue("init_client_data")).levelExperienceTable; const days = Number(daysAfterInput.value); parentDiv.querySelector(`div#needDiv`).textContent = `${isZH ? "" : "After"} ${days} ${isZH ? "天后:" : "days: "}`; const listDiv = parentDiv.querySelector(`div#needListDiv`); let html = ""; let resultLevels = {}; for (const skillName of skillNamesInOrder) { for (const skill of Object.values(skillLevels)) { if (skill.skillName.toLowerCase() === skillName.toLowerCase()) { const exp = skill.currentExp + perHourGainExp[skill.skillName.toLowerCase()] * days * 24; let level = 1; while (initData_levelExperienceTable[level] < exp) { level++; } level--; const minExpAtLevel = initData_levelExperienceTable[level]; const maxExpAtLevel = initData_levelExperienceTable[level + 1] - 1; const expSpanInLevel = maxExpAtLevel - minExpAtLevel; const levelPercentage = Number(((exp - minExpAtLevel) / expSpanInLevel) * 100).toFixed(1); resultLevels[skillName.toLowerCase()] = level; html += `
${skill.skillName} ${isZH ? "" : "level"} ${level} ${isZH ? "级" : ""} ${levelPercentage}%
`; break; } } } const combatLevel = 0.2 * (resultLevels.stamina + resultLevels.intelligence + resultLevels.defense) + 0.4 * Math.max(0.5 * (resultLevels.attack + resultLevels.power), resultLevels.ranged, resultLevels.magic); html += `
${isZH ? "战斗等级:" : "Combat level: "} ${combatLevel.toFixed(1)}
`; listDiv.innerHTML = html; } function calculateTill(skillName, skillInputElem, skillLevels, parentDiv, perHourGainExp) { const initData_levelExperienceTable = JSON.parse(GM_getValue("init_client_data")).levelExperienceTable; const targetLevel = Number(skillInputElem.value); parentDiv.querySelector(`div#needDiv`).textContent = `${skillLevels[skillName].skillName} ${isZH ? "到" : "to level"} ${targetLevel} ${ isZH ? "级 还需:" : " takes: " }`; const listDiv = parentDiv.querySelector(`div#needListDiv`); const currentLevel = Number(skillLevels[skillName].currentLevel); const currentExp = Number(skillLevels[skillName].currentExp); if (targetLevel > currentLevel && targetLevel <= 200) { if (perHourGainExp[skillName] === 0) { listDiv.innerHTML = isZH ? "永远" : "Forever"; } else { let needExp = initData_levelExperienceTable[targetLevel] - currentExp; let needHours = needExp / perHourGainExp[skillName]; let html = ""; html += `
[${hoursToReadableString(needHours)}]
`; const consumeDivs = document.querySelectorAll(`div#simulationResultConsumablesUsed div.row`); for (const elem of consumeDivs) { const conName = elem.children[0].textContent; const conPerHour = Number(elem.children[1].textContent); html += `
${conName} ${Number(conPerHour * needHours).toFixed(0)}
`; } listDiv.innerHTML = html; } } else { listDiv.innerHTML = isZH ? "输入错误" : "Input error"; } } function hoursToReadableString(hours) { const sec = hours * 60 * 60; if (sec >= 86400) { return Number(sec / 86400).toFixed(1) + (isZH ? " 天" : " days"); } const d = new Date(Math.round(sec * 1000)); function pad(i) { return ("0" + i).slice(-2); } let str = d.getUTCHours() + "h " + pad(d.getUTCMinutes()) + "m " + pad(d.getUTCSeconds()) + "s"; return str; } })();