Magic Way Idle

法师助手

Fra 22.12.2024. Se den seneste versjonen.

// ==UserScript==
// @name         Magic Way Idle
// @namespace    http://tampermonkey.net/
// @version      2.3.4
// @description  法师助手
// @icon         https://www.milkywayidle.com/favicon.svg
// @match        https://www.milkywayidle.com/*
// @run-at       document-start
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_notification
// @grant        GM_xmlhttpRequest
// @require      https://cdnjs.cloudflare.com/ajax/libs/mathjs/12.4.2/math.js
// ==/UserScript==

(function () {
// 全局URL链接配置
const global_url_config={
    market:{
        //市场API本地备份
        LOCAL_BACKUP : `{"time":1720276202,"market":{"Amber":{"ask":6400,"bid":6200},"Amethyst":{"ask":64000,"bid":62000},"Apple":{"ask":5,"bid":4},"Apple Gummy":{"ask":11,"bid":-1},"Apple Yogurt":{"ask":275,"bid":110},"Aqua Arrow":{"ask":13500,"bid":10000},"Aqua Essence":{"ask":23,"bid":18},"Arabica Coffee Bean":{"ask":135,"bid":130},"Arcane Bow":{"ask":265000,"bid":120000},"Arcane Crossbow":{"ask":285000,"bid":260000},"Arcane Fire Staff":{"ask":185000,"bid":155000},"Arcane Log":{"ask":270,"bid":255},"Arcane Lumber":{"ask":960,"bid":900},"Arcane Nature Staff":{"ask":220000,"bid":120000},"Arcane Water Staff":{"ask":120000,"bid":105000},"Artisan Tea":{"ask":740,"bid":540},"Attack Coffee":{"ask":500,"bid":380},"Azure Boots":{"ask":21000,"bid":1200},"Azure Brush":{"ask":35000,"bid":2100},"Azure Buckler":{"ask":15500,"bid":1800},"Azure Bulwark":{"ask":35000,"bid":-1},"Azure Cheese":{"ask":360,"bid":340},"Azure Chisel":{"ask":25000,"bid":-1},"Azure Enhancer":{"ask":23500,"bid":-1},"Azure Gauntlets":{"ask":21000,"bid":-1},"Azure Hammer":{"ask":33000,"bid":6000},"Azure Hatchet":{"ask":30000,"bid":2100},"Azure Helmet":{"ask":23500,"bid":1450},"Azure Mace":{"ask":36000,"bid":-1},"Azure Milk":{"ask":110,"bid":94},"Azure Needle":{"ask":32000,"bid":-1},"Azure Plate Body":{"ask":35000,"bid":-1},"Azure Plate Legs":{"ask":28500,"bid":2100},"Azure Pot":{"ask":29500,"bid":-1},"Azure Shears":{"ask":50000,"bid":-1},"Azure Spatula":{"ask":28000,"bid":-1},"Azure Spear":{"ask":36000,"bid":20000},"Azure Sword":{"ask":36000,"bid":-1},"Bamboo Boots":{"ask":11000,"bid":-1},"Bamboo Branch":{"ask":30,"bid":16},"Bamboo Fabric":{"ask":270,"bid":235},"Bamboo Gloves":{"ask":14500,"bid":-1},"Bamboo Hat":{"ask":18500,"bid":5400},"Bamboo Robe Bottoms":{"ask":23000,"bid":-1},"Bamboo Robe Top":{"ask":24000,"bid":15000},"Bear Essence":{"ask":68,"bid":62},"Beast Boots":{"ask":52000,"bid":-1},"Beast Bracers":{"ask":48000,"bid":17000},"Beast Chaps":{"ask":98000,"bid":76000},"Beast Hide":{"ask":21,"bid":20},"Beast Hood":{"ask":62000,"bid":40000},"Beast Leather":{"ask":520,"bid":460},"Beast Tunic":{"ask":84000,"bid":70000},"Berserk":{"ask":430000,"bid":370000},"Birch Bow":{"ask":13000,"bid":-1},"Birch Crossbow":{"ask":17000,"bid":-1},"Birch Fire Staff":{"ask":15000,"bid":-1},"Birch Log":{"ask":56,"bid":48},"Birch Lumber":{"ask":360,"bid":195},"Birch Nature Staff":{"ask":15500,"bid":2200},"Birch Water Staff":{"ask":26500,"bid":760},"Black Bear Fluff":{"ask":44000,"bid":43000},"Black Bear Shoes":{"ask":235000,"bid":62000},"Black Tea Leaf":{"ask":20,"bid":18},"Blackberry":{"ask":45,"bid":42},"Blackberry Cake":{"ask":295,"bid":225},"Blackberry Donut":{"ask":255,"bid":180},"Blessed Tea":{"ask":490,"bid":350},"Blueberry":{"ask":28,"bid":25},"Blueberry Cake":{"ask":390,"bid":96},"Blueberry Donut":{"ask":380,"bid":72},"Brewing Tea":{"ask":240,"bid":105},"Burble Brush":{"ask":56000,"bid":-1},"Burble Buckler":{"ask":49000,"bid":-1},"Burble Bulwark":{"ask":33000,"bid":-1},"Burble Chisel":{"ask":54000,"bid":-1},"Burble Enhancer":{"ask":48000,"bid":20000},"Burble Gauntlets":{"ask":46000,"bid":-1},"Burble Hatchet":{"ask":49000,"bid":-1},"Burble Helmet":{"ask":46000,"bid":-1},"Burble Mace":{"ask":56000,"bid":15000},"Burble Needle":{"ask":44000,"bid":18000},"Burble Plate Body":{"ask":50000,"bid":17000},"Burble Pot":{"ask":45000,"bid":21000},"Burble Shears":{"ask":52000,"bid":-1},"Burble Spatula":{"ask":40000,"bid":5200},"Burble Sword":{"ask":52000,"bid":-1},"Burble Tea Leaf":{"ask":66,"bid":50},"Cedar Bow":{"ask":42000,"bid":3500},"Cedar Fire Staff":{"ask":41000,"bid":3200},"Cedar Log":{"ask":92,"bid":72},"Cedar Lumber":{"ask":450,"bid":360},"Cedar Water Staff":{"ask":42000,"bid":4300},"Centaur Boots":{"ask":980000,"bid":700000},"Centaur Hoof":{"ask":125000,"bid":120000},"Cheese Boots":{"ask":2400,"bid":66},"Cheese Brush":{"ask":4400,"bid":125},"Cheese Buckler":{"ask":-1,"bid":400},"Cheese Chisel":{"ask":3500,"bid":-1},"Cheese Enhancer":{"ask":3300,"bid":1000},"Cheese Gauntlets":{"ask":2400,"bid":66},"Cheese Hammer":{"ask":4200,"bid":-1},"Cheese Helmet":{"ask":2650,"bid":100},"Cheese Mace":{"ask":5800,"bid":150},"Cheese Plate Body":{"ask":2550,"bid":155},"Cheese Plate Legs":{"ask":-1,"bid":1000},"Cheese Pot":{"ask":4000,"bid":2000},"Cheese Spatula":{"ask":4100,"bid":115},"Cheese Spear":{"ask":14000,"bid":300},"Cheese Sword":{"ask":5000,"bid":300},"Cleave":{"ask":135000,"bid":100000},"Cocoon":{"ask":145,"bid":120},"Coin":{"ask":-1,"bid":-1},"Cotton":{"ask":30,"bid":15},"Cotton Boots":{"ask":440,"bid":-1},"Cotton Fabric":{"ask":74,"bid":31},"Cotton Hat":{"ask":1100,"bid":-1},"Cotton Robe Bottoms":{"ask":1900,"bid":-1},"Cotton Robe Top":{"ask":2700,"bid":-1},"Crab Pincer":{"ask":8600,"bid":8200},"Crafting Tea":{"ask":360,"bid":185},"Crimson Boots":{"ask":72000,"bid":18000},"Crimson Buckler":{"ask":105000,"bid":-1},"Crimson Bulwark":{"ask":49000,"bid":-1},"Crimson Cheese":{"ask":430,"bid":390},"Crimson Enhancer":{"ask":54000,"bid":43000},"Crimson Gauntlets":{"ask":52000,"bid":15000},"Crimson Hammer":{"ask":66000,"bid":40000},"Crimson Helmet":{"ask":84000,"bid":36000},"Crimson Mace":{"ask":96000,"bid":-1},"Crimson Milk":{"ask":110,"bid":96},"Crimson Plate Body":{"ask":60000,"bid":-1},"Crimson Plate Legs":{"ask":78000,"bid":22000},"Crimson Pot":{"ask":50000,"bid":-1},"Crimson Spatula":{"ask":68000,"bid":-1},"Crimson Spear":{"ask":-1,"bid":58000},"Crimson Sword":{"ask":-1,"bid":72000},"Crushed Amber":{"ask":390,"bid":300},"Crushed Amethyst":{"ask":4000,"bid":3000},"Crushed Garnet":{"ask":1300,"bid":840},"Crushed Moonstone":{"ask":2850,"bid":1000},"Crushed Pearl":{"ask":920,"bid":800},"Cupcake":{"ask":180,"bid":20},"Donut":{"ask":155,"bid":17},"Dragon Fruit":{"ask":115,"bid":110},"Dragon Fruit Gummy":{"ask":500,"bid":440},"Earrings Of Armor":{"ask":2250000,"bid":-1},"Earrings Of Gathering":{"ask":4900000,"bid":-1},"Earrings Of Regeneration":{"ask":4400000,"bid":3600000},"Earrings Of Resistance":{"ask":880000,"bid":30000},"Efficiency Tea":{"ask":540,"bid":470},"Elemental Affinity":{"ask":580000,"bid":560000},"Emp Tea Leaf":{"ask":86,"bid":84},"Enhancing Tea":{"ask":370,"bid":170},"Excelsa Coffee Bean":{"ask":320,"bid":285},"Eyessence":{"ask":76,"bid":70},"Fieriosa Coffee Bean":{"ask":360,"bid":340},"Fireball":{"ask":16500,"bid":16000},"Flame Arrow":{"ask":13000,"bid":7800},"Flame Blast":{"ask":160000,"bid":150000},"Flaming Cloth":{"ask":29000,"bid":20000},"Flaming Robe Top":{"ask":98000,"bid":60000},"Flax":{"ask":49,"bid":44},"Foraging Tea":{"ask":215,"bid":10},"Garnet":{"ask":14000,"bid":13500},"Gathering Tea":{"ask":340,"bid":295},"Giant Pouch":{"ask":6400000,"bid":5600000},"Ginkgo Bow":{"ask":100000,"bid":20000},"Ginkgo Crossbow":{"ask":110000,"bid":-1},"Ginkgo Log":{"ask":58,"bid":48},"Ginkgo Lumber":{"ask":370,"bid":265},"Ginkgo Nature Staff":{"ask":88000,"bid":-1},"Gobo Boomstick":{"ask":21000,"bid":-1},"Gobo Boots":{"ask":22000,"bid":-1},"Gobo Bracers":{"ask":18500,"bid":8600},"Gobo Essence":{"ask":155,"bid":105},"Gobo Hide":{"ask":21,"bid":15},"Gobo Hood":{"ask":15000,"bid":10000},"Gobo Shooter":{"ask":25500,"bid":23000},"Gobo Slasher":{"ask":24500,"bid":-1},"Gobo Smasher":{"ask":20000,"bid":-1},"Gobo Tunic":{"ask":31000,"bid":17000},"Goggles":{"ask":46000,"bid":37000},"Golem Essence":{"ask":230,"bid":180},"Granite Bludgeon":{"ask":42000000,"bid":1000000},"Green Tea Leaf":{"ask":14,"bid":11},"Grizzly Bear Fluff":{"ask":50000,"bid":43000},"Gummy":{"ask":175,"bid":20},"Heal":{"ask":210000,"bid":195000},"Holy Boots":{"ask":120000,"bid":-1},"Holy Buckler":{"ask":240000,"bid":-1},"Holy Bulwark":{"ask":140000,"bid":-1},"Holy Cheese":{"ask":960,"bid":920},"Holy Enhancer":{"ask":205000,"bid":185000},"Holy Gauntlets":{"ask":220000,"bid":-1},"Holy Hammer":{"ask":235000,"bid":185000},"Holy Helmet":{"ask":360000,"bid":70000},"Holy Mace":{"ask":285000,"bid":-1},"Holy Milk":{"ask":300,"bid":270},"Holy Plate Body":{"ask":390000,"bid":-1},"Holy Plate Legs":{"ask":295000,"bid":165000},"Holy Pot":{"ask":210000,"bid":160000},"Holy Spatula":{"ask":220000,"bid":185000},"Holy Spear":{"ask":200000,"bid":80000},"Holy Sword":{"ask":290000,"bid":245000},"Icy Cloth":{"ask":21000,"bid":12000},"Icy Robe Bottoms":{"ask":100000,"bid":41000},"Icy Robe Top":{"ask":100000,"bid":60000},"Jade":{"ask":19000,"bid":16000},"Jungle Essence":{"ask":74,"bid":66},"Large Artisan's Crate":{"ask":-1,"bid":-1},"Large Pouch":{"ask":800000,"bid":500000},"Large Treasure Chest":{"ask":-1,"bid":-1},"Liberica Coffee Bean":{"ask":285,"bid":255},"Linen Boots":{"ask":7400,"bid":600},"Linen Gloves":{"ask":9800,"bid":580},"Linen Hat":{"ask":9400,"bid":-1},"Linen Robe Bottoms":{"ask":16500,"bid":1100},"Living Granite":{"ask":1400000,"bid":820000},"Log":{"ask":29,"bid":25},"Lucky Coffee":{"ask":1250,"bid":880},"Magic Coffee":{"ask":400,"bid":370},"Magnet":{"ask":90000,"bid":74000},"Magnifying Glass":{"ask":680000,"bid":620000},"Maim":{"ask":130000,"bid":115000},"Marsberry":{"ask":35,"bid":31},"Marsberry Donut":{"ask":420,"bid":340},"Medium Artisan's Crate":{"ask":-1,"bid":-1},"Medium Meteorite Cache":{"ask":-1,"bid":-1},"Medium Treasure Chest":{"ask":-1,"bid":-1},"Milk":{"ask":32,"bid":28},"Milking Tea":{"ask":430,"bid":100},"Minor Heal":{"ask":17000,"bid":14000},"Mooberry":{"ask":64,"bid":52},"Mooberry Cake":{"ask":440,"bid":285},"Mooberry Donut":{"ask":330,"bid":145},"Moonstone":{"ask":21000,"bid":20000},"Necklace Of Efficiency":{"ask":6800000,"bid":-1},"Necklace Of Wisdom":{"ask":7200000,"bid":6200000},"Orange Gummy":{"ask":39,"bid":25},"Orange Yogurt":{"ask":410,"bid":175},"Panda Gloves":{"ask":-1,"bid":-1},"Peach":{"ask":31,"bid":19},"Peach Gummy":{"ask":210,"bid":170},"Pearl":{"ask":14000,"bid":13500},"Pierce":{"ask":-1,"bid":-1},"Pincer Gloves":{"ask":52000,"bid":10000},"Plum":{"ask":88,"bid":58},"Plum Yogurt":{"ask":340,"bid":290},"Poke":{"ask":7200,"bid":7000},"Power Coffee":{"ask":700,"bid":420},"Precision":{"ask":13000,"bid":9600},"Purpleheart Bow":{"ask":60000,"bid":-1},"Purpleheart Crossbow":{"ask":50000,"bid":35000},"Purpleheart Fire Staff":{"ask":100000,"bid":6800},"Purpleheart Lumber":{"ask":340,"bid":310},"Purpleheart Nature Staff":{"ask":68000,"bid":12500},"Purpleheart Water Staff":{"ask":76000,"bid":7400},"Quick Shot":{"ask":2900,"bid":2300},"Radiant Fabric":{"ask":820,"bid":800},"Radiant Fiber":{"ask":150,"bid":125},"Radiant Gloves":{"ask":86000,"bid":54000},"Radiant Robe Bottoms":{"ask":250000,"bid":165000},"Radiant Robe Top":{"ask":255000,"bid":120000},"Rain Of Arrows":{"ask":165000,"bid":135000},"Rainbow Brush":{"ask":110000,"bid":72000},"Rainbow Buckler":{"ask":84000,"bid":-1},"Rainbow Bulwark":{"ask":140000,"bid":-1},"Rainbow Chisel":{"ask":110000,"bid":30000},"Rainbow Enhancer":{"ask":105000,"bid":32000},"Rainbow Gauntlets":{"ask":84000,"bid":-1},"Rainbow Hatchet":{"ask":96000,"bid":30000},"Rainbow Helmet":{"ask":74000,"bid":50000},"Rainbow Mace":{"ask":125000,"bid":-1},"Rainbow Needle":{"ask":115000,"bid":30000},"Rainbow Plate Body":{"ask":170000,"bid":-1},"Rainbow Plate Legs":{"ask":-1,"bid":-1},"Rainbow Shears":{"ask":98000,"bid":60000},"Rainbow Spatula":{"ask":-1,"bid":76000},"Rainbow Spear":{"ask":125000,"bid":-1},"Ranged Coffee":{"ask":480,"bid":260},"Ranger Necklace":{"ask":7800000,"bid":5600000},"Red Tea Leaf":{"ask":58,"bid":52},"Redwood Crossbow":{"ask":130000,"bid":32000},"Redwood Fire Staff":{"ask":120000,"bid":-1},"Redwood Log":{"ask":32,"bid":27},"Redwood Nature Staff":{"ask":130000,"bid":-1},"Redwood Water Staff":{"ask":74000,"bid":-1},"Reptile Boots":{"ask":12500,"bid":580},"Reptile Chaps":{"ask":11000,"bid":1100},"Reptile Hide":{"ask":18,"bid":10},"Reptile Hood":{"ask":12000,"bid":720},"Reptile Tunic":{"ask":12500,"bid":-1},"Ring Of Armor":{"ask":2500000,"bid":1000000},"Ring Of Gathering":{"ask":-1,"bid":2000000},"Ring Of Regeneration":{"ask":4300000,"bid":2000000},"Ring Of Resistance":{"ask":1400000,"bid":30000},"Robusta Coffee Bean":{"ask":220,"bid":190},"Rough Bracers":{"ask":2650,"bid":-1},"Rough Chaps":{"ask":2200,"bid":-1},"Rough Hide":{"ask":42,"bid":35},"Rough Leather":{"ask":200,"bid":165},"Rough Tunic":{"ask":7000,"bid":-1},"Scratch":{"ask":2900,"bid":1450},"Silk Boots":{"ask":-1,"bid":8000},"Silk Fabric":{"ask":740,"bid":700},"Silk Gloves":{"ask":40000,"bid":28500},"Silk Robe Bottoms":{"ask":60000,"bid":52000},"Silk Robe Top":{"ask":96000,"bid":-1},"Smack":{"ask":4100,"bid":3900},"Small Meteorite Cache":{"ask":-1,"bid":-1},"Small Pouch":{"ask":58000,"bid":15000},"Snail Shell":{"ask":4000,"bid":3600},"Snail Shell Helmet":{"ask":6000,"bid":-1},"Snake Fang":{"ask":2100,"bid":2000},"Sorcerer Boots":{"ask":145000,"bid":70000},"Sorcerer Essence":{"ask":175,"bid":150},"Sorcerer's Sole":{"ask":64000,"bid":62000},"Spaceberry Cake":{"ask":920,"bid":900},"Spaceberry Donut":{"ask":760,"bid":700},"Spacia Coffee Bean":{"ask":720,"bid":660},"Stalactite Shard":{"ask":960000,"bid":760000},"Stalactite Spear":{"ask":-1,"bid":14000000},"Stamina Coffee":{"ask":310,"bid":275},"Star Fruit":{"ask":310,"bid":295},"Star Fruit Gummy":{"ask":700,"bid":640},"Star Fruit Yogurt":{"ask":940,"bid":900},"Strawberry Cake":{"ask":400,"bid":255},"Strawberry Donut":{"ask":260,"bid":33},"Stunning Blow":{"ask":560000,"bid":540000},"Super Attack Coffee":{"ask":1650,"bid":1450},"Super Brewing Tea":{"ask":740,"bid":165},"Super Cheesesmithing Tea":{"ask":2400,"bid":1650},"Super Crafting Tea":{"ask":2900,"bid":1550},"Super Defense Coffee":{"ask":1450,"bid":1300},"Super Enhancing Tea":{"ask":1950,"bid":520},"Super Foraging Tea":{"ask":1650,"bid":520},"Super Magic Coffee":{"ask":5400,"bid":5000},"Super Milking Tea":{"ask":2400,"bid":600},"Super Power Coffee":{"ask":2750,"bid":2450},"Super Stamina Coffee":{"ask":1800,"bid":1600},"Super Tailoring Tea":{"ask":6000,"bid":3500},"Super Woodcutting Tea":{"ask":4500,"bid":1450},"Sweep":{"ask":100000,"bid":90000},"Swiftness Coffee":{"ask":980,"bid":880},"Tailoring Tea":{"ask":250,"bid":125},"Tome Of The Elements":{"ask":160000,"bid":105000},"Toughness":{"ask":68000,"bid":25000},"Toxic Pollen":{"ask":135000,"bid":125000},"Turtle Shell Body":{"ask":17500,"bid":9000},"Turtle Shell Legs":{"ask":38000,"bid":6000},"Twilight Essence":{"ask":120,"bid":115},"Umbral Bracers":{"ask":43000,"bid":-1},"Umbral Chaps":{"ask":84000,"bid":-1},"Umbral Hide":{"ask":68,"bid":48},"Umbral Leather":{"ask":700,"bid":680},"Umbral Tunic":{"ask":115000,"bid":-1},"Vampire Fang":{"ask":430000,"bid":350000},"Vampirism":{"ask":50000,"bid":22000},"Verdant Boots":{"ask":11500,"bid":320},"Verdant Brush":{"ask":15500,"bid":5000},"Verdant Bulwark":{"ask":8000,"bid":-1},"Verdant Cheese":{"ask":270,"bid":255},"Verdant Chisel":{"ask":14500,"bid":-1},"Verdant Gauntlets":{"ask":9400,"bid":-1},"Verdant Hammer":{"ask":17500,"bid":560},"Verdant Hatchet":{"ask":14500,"bid":600},"Verdant Mace":{"ask":14500,"bid":-1},"Verdant Milk":{"ask":58,"bid":54},"Verdant Needle":{"ask":14000,"bid":-1},"Verdant Plate Legs":{"ask":13000,"bid":-1},"Verdant Pot":{"ask":14000,"bid":10000},"Verdant Shears":{"ask":13500,"bid":-1},"Verdant Spear":{"ask":14000,"bid":1450},"Verdant Sword":{"ask":15500,"bid":720},"Vision Helmet":{"ask":82000,"bid":42000},"Water Strike":{"ask":16500,"bid":16000},"Werewolf Claw":{"ask":260000,"bid":92000},"Werewolf Slasher":{"ask":5000000,"bid":-1},"Wisdom Coffee":{"ask":860,"bid":840},"Wisdom Tea":{"ask":600,"bid":500},"Wizard Necklace":{"ask":9600000,"bid":4300000},"Wooden Bow":{"ask":5000,"bid":-1},"Wooden Crossbow":{"ask":3200,"bid":-1},"Wooden Fire Staff":{"ask":3600,"bid":-1},"Wooden Water Staff":{"ask":3500,"bid":145},"Yogurt":{"ask":200,"bid":40},"Burble Boots":{"ask":38000,"bid":-1},"Burble Cheese":{"ask":330,"bid":320},"Burble Hammer":{"ask":46000,"bid":16000},"Burble Milk":{"ask":125,"bid":115},"Cedar Nature Staff":{"ask":42000,"bid":3200},"Cheese":{"ask":140,"bid":105},"Cheese Bulwark":{"ask":2250,"bid":-1},"Cheese Hatchet":{"ask":5400,"bid":-1},"Cheese Needle":{"ask":2200,"bid":-1},"Cheese Shears":{"ask":3100,"bid":-1},"Cheesesmithing Tea":{"ask":500,"bid":250},"Cooking Tea":{"ask":160,"bid":150},"Cotton Gloves":{"ask":620,"bid":-1},"Cowbell":{"ask":-1,"bid":-1},"Crimson Brush":{"ask":66000,"bid":50000},"Crimson Chisel":{"ask":74000,"bid":40000},"Crimson Hatchet":{"ask":56000,"bid":45000},"Crimson Shears":{"ask":-1,"bid":-1},"Critical Coffee":{"ask":1900,"bid":1700},"Crushed Jade":{"ask":1200,"bid":1100},"Defense Coffee":{"ask":640,"bid":340},"Dragon Fruit Yogurt":{"ask":560,"bid":500},"Flaming Robe Bottoms":{"ask":100000,"bid":40000},"Frenzy":{"ask":175000,"bid":165000},"Gobo Leather":{"ask":410,"bid":265},"Holy Chisel":{"ask":210000,"bid":185000},"Holy Hatchet":{"ask":195000,"bid":180000},"Holy Needle":{"ask":185000,"bid":165000},"Holy Shears":{"ask":200000,"bid":155000},"Ice Spear":{"ask":30000,"bid":28500},"Intelligence Coffee":{"ask":380,"bid":285},"Linen Fabric":{"ask":310,"bid":195},"Linen Robe Top":{"ask":10000,"bid":-1},"Lumber":{"ask":330,"bid":255},"Mirror Of Protection":{"ask":7800000,"bid":7400000},"Moolong Tea Leaf":{"ask":40,"bid":33},"Orange":{"ask":9,"bid":6},"Panda Fluff":{"ask":90000,"bid":56000},"Peach Yogurt":{"ask":-1,"bid":370},"Plum Gummy":{"ask":64,"bid":52},"Processing Tea":{"ask":760,"bid":600},"Purpleheart Log":{"ask":90,"bid":60},"Radiant Boots":{"ask":22500,"bid":-1},"Radiant Hat":{"ask":190000,"bid":130000},"Rainbow Boots":{"ask":98000,"bid":50000},"Rainbow Cheese":{"ask":420,"bid":390},"Rainbow Hammer":{"ask":105000,"bid":40000},"Rainbow Milk":{"ask":125,"bid":105},"Rainbow Pot":{"ask":90000,"bid":-1},"Rainbow Sword":{"ask":135000,"bid":120000},"Redwood Bow":{"ask":155000,"bid":50000},"Redwood Lumber":{"ask":235,"bid":215},"Reptile Bracers":{"ask":10500,"bid":-1},"Reptile Leather":{"ask":140,"bid":110},"Ring Of Rare Find":{"ask":3700000,"bid":3100000},"Rough Boots":{"ask":2000,"bid":-1},"Rough Hood":{"ask":2000,"bid":1200},"Shard Of Protection":{"ask":44000,"bid":42000},"Silk Hat":{"ask":62000,"bid":-1},"Small Artisan's Crate":{"ask":-1,"bid":-1},"Small Treasure Chest":{"ask":-1,"bid":-1},"Snake Fang Dirk":{"ask":10500,"bid":2500},"Spaceberry":{"ask":190,"bid":170},"Spike Shell":{"ask":360000,"bid":310000},"Star Fragment":{"ask":7000,"bid":6800},"Strawberry":{"ask":50,"bid":48},"Super Cooking Tea":{"ask":1650,"bid":800},"Super Intelligence Coffee":{"ask":2000,"bid":1750},"Super Ranged Coffee":{"ask":2450,"bid":2300},"Swamp Essence":{"ask":19,"bid":17},"Tome Of Healing":{"ask":20000,"bid":16000},"Turtle Shell":{"ask":11500,"bid":5800},"Umbral Boots":{"ask":26500,"bid":-1},"Umbral Hood":{"ask":145000,"bid":-1},"Vampire Fang Dirk":{"ask":9000000,"bid":5200000},"Verdant Buckler":{"ask":7000,"bid":600},"Verdant Enhancer":{"ask":11000,"bid":-1},"Verdant Helmet":{"ask":11000,"bid":-1},"Verdant Spatula":{"ask":12500,"bid":-1},"Vision Shield":{"ask":1150000,"bid":80000},"Wheat":{"ask":25,"bid":22},"Woodcutting Tea":{"ask":220,"bid":100},"Wooden Nature Staff":{"ask":18500,"bid":145},"Cedar Crossbow":{"ask":19500,"bid":12000},"Earrings Of Rare Find":{"ask":3500000,"bid":2900000},"Egg":{"ask":29,"bid":20},"Entangle":{"ask":2950,"bid":2000},"Fighter Necklace":{"ask":4900000,"bid":-1},"Gator Vest":{"ask":10000,"bid":7800},"Ginkgo Fire Staff":{"ask":74000,"bid":15000},"Gobo Chaps":{"ask":29500,"bid":15500},"Gobo Stabber":{"ask":20000,"bid":-1},"Gourmet Tea":{"ask":460,"bid":350},"Grizzly Bear Shoes":{"ask":580000,"bid":64000},"Holy Brush":{"ask":220000,"bid":190000},"Large Meteorite Cache":{"ask":-1,"bid":-1},"Magnetic Gloves":{"ask":640000,"bid":-1},"Marsberry Cake":{"ask":540,"bid":520},"Medium Pouch":{"ask":245000,"bid":-1},"Polar Bear Fluff":{"ask":74000,"bid":68000},"Verdant Plate Body":{"ask":14000,"bid":860},"Ginkgo Water Staff":{"ask":66000,"bid":14000},"Polar Bear Shoes":{"ask":660000,"bid":185000},"Sugar":{"ask":7,"bid":6},"Crimson Needle":{"ask":56000,"bid":40000},"Burble Plate Legs":{"ask":49000,"bid":-1},"Burble Spear":{"ask":56000,"bid":25000},"Arcane Shield":{"ask":70000,"bid":-1},"Birch Shield":{"ask":3300,"bid":490},"Cedar Shield":{"ask":50000,"bid":2000},"Ginkgo Shield":{"ask":19000,"bid":-1},"Purpleheart Shield":{"ask":14000,"bid":-1},"Redwood Shield":{"ask":39000,"bid":-1},"Sighted Bracers":{"ask":840000,"bid":640000},"Spiked Bulwark":{"ask":-1,"bid":500000},"Wooden Shield":{"ask":480,"bid":-1},"Advanced Task Ring":{"ask":-1,"bid":-1},"Basic Task Ring":{"ask":-1,"bid":-1},"Expert Task Ring":{"ask":-1,"bid":-1},"Purple's Gift":{"ask":-1,"bid":-1},"Task Crystal":{"ask":-1,"bid":-1},"Task Token":{"ask":-1,"bid":-1},"Abyssal Essence":{"ask":280,"bid":260},"Channeling Coffee":{"ask":780,"bid":700},"Chrono Gloves":{"ask":3600000,"bid":2100000},"Chrono Sphere":{"ask":360000,"bid":320000},"Collector's Boots":{"ask":1100000,"bid":640000},"Colossus Core":{"ask":600000,"bid":500000},"Colossus Plate Body":{"ask":6200000,"bid":-1},"Colossus Plate Legs":{"ask":4600000,"bid":2100000},"Demonic Core":{"ask":1150000,"bid":1100000},"Demonic Plate Body":{"ask":10000000,"bid":9200000},"Demonic Plate Legs":{"ask":9800000,"bid":7200000},"Elusiveness":{"ask":11500,"bid":7600},"Enchanted Gloves":{"ask":4500000,"bid":3500000},"Eye Of The Watcher":{"ask":400000,"bid":370000},"Eye Watch":{"ask":3900000,"bid":2800000},"Firestorm":{"ask":720000,"bid":620000},"Fluffy Red Hat":{"ask":2250000,"bid":-1},"Frost Sphere":{"ask":520000,"bid":470000},"Frost Staff":{"ask":-1,"bid":3000000},"Frost Surge":{"ask":760000,"bid":720000},"Gobo Defender":{"ask":275000,"bid":240000},"Gobo Rag":{"ask":92000,"bid":84000},"Infernal Battlestaff":{"ask":-1,"bid":21500000},"Infernal Ember":{"ask":1750000,"bid":1600000},"Luna Robe Bottoms":{"ask":2050000,"bid":800000},"Luna Robe Top":{"ask":2250000,"bid":800000},"Luna Wing":{"ask":155000,"bid":140000},"Marine Chaps":{"ask":430000,"bid":-1},"Marine Scale":{"ask":39000,"bid":31000},"Marine Tunic":{"ask":580000,"bid":-1},"Nature's Veil":{"ask":880000,"bid":740000},"Puncture":{"ask":185000,"bid":160000},"Red Chef's Hat":{"ask":1300000,"bid":1100000},"Red Panda Fluff":{"ask":145000,"bid":120000},"Revenant Anima":{"ask":700000,"bid":640000},"Revenant Chaps":{"ask":7200000,"bid":4500000},"Revenant Tunic":{"ask":9000000,"bid":4000000},"Shoebill Feather":{"ask":26000,"bid":20000},"Shoebill Shoes":{"ask":-1,"bid":-1},"Silencing Shot":{"ask":135000,"bid":120000},"Soul Fragment":{"ask":760000,"bid":580000},"Soul Hunter Crossbow":{"ask":-1,"bid":7400000},"Steady Shot":{"ask":640000,"bid":480000},"Treant Bark":{"ask":9800,"bid":8600},"Treant Shield":{"ask":32000,"bid":-1},"Vampiric Bow":{"ask":8400000,"bid":5600000},"Watchful Relic":{"ask":3900000,"bid":2700000},"Bag Of 10 Cowbells":{"ask":290000,"bid":275000},"Aqua Aura":{"ask":3200000,"bid":2450000},"Critical Aura":{"ask":9600000,"bid":5800000},"Fierce Aura":{"ask":16500000,"bid":6800000},"Flame Aura":{"ask":5200000,"bid":4200000},"Insanity":{"ask":6800000,"bid":5800000},"Invincible":{"ask":5000000,"bid":3100000},"Provoke":{"ask":245000,"bid":175000},"Quick Aid":{"ask":720000,"bid":620000},"Rejuvenate":{"ask":1250000,"bid":1100000},"Revive":{"ask":1250000,"bid":680000},"Speed Aura":{"ask":8400000,"bid":5200000},"Sylvan Aura":{"ask":6000000,"bid":4500000},"Taunt":{"ask":90000,"bid":24000},"Acrobatic Hood":{"ask":-1,"bid":35000000},"Acrobat's Ribbon":{"ask":4800000,"bid":4500000},"Bishop's Codex":{"ask":-1,"bid":-1},"Bishop's Scroll":{"ask":6800000,"bid":6600000},"Blue Key Fragment":{"ask":420000,"bid":400000},"Brown Key Fragment":{"ask":840000,"bid":740000},"Burning Key Fragment":{"ask":1800000,"bid":1700000},"Chaotic Chain":{"ask":9600000,"bid":9200000},"Chaotic Flail":{"ask":-1,"bid":145000000},"Chimerical Chest":{"ask":-1,"bid":-1},"Chimerical Essence":{"ask":1300,"bid":980},"Chimerical Key":{"ask":2300000,"bid":2150000},"Chimerical Quiver":{"ask":-1,"bid":-1},"Crippling Slash":{"ask":94000,"bid":92000},"Cursed Ball":{"ask":4000000,"bid":1550000},"Cursed Bow":{"ask":-1,"bid":9000000},"Dark Key Fragment":{"ask":2000000,"bid":1900000},"Dodocamel Gauntlets":{"ask":-1,"bid":42000000},"Dodocamel Plume":{"ask":8000000,"bid":7000000},"Earrings Of Threat":{"ask":4200000,"bid":1050000},"Enchanted Chest":{"ask":-1,"bid":-1},"Enchanted Cloak":{"ask":-1,"bid":-1},"Enchanted Essence":{"ask":3800,"bid":3600},"Enchanted Key":{"ask":5400000,"bid":5000000},"Green Key Fragment":{"ask":330000,"bid":290000},"Griffin Chaps":{"ask":7000000,"bid":-1},"Griffin Leather":{"ask":520000,"bid":330000},"Griffin Tunic":{"ask":8000000,"bid":3300000},"Impale":{"ask":17500,"bid":8000},"Jackalope Antler":{"ask":1600000,"bid":1050000},"Jackalope Staff":{"ask":-1,"bid":16500000},"Knight's Aegis":{"ask":64000000,"bid":42000000},"Knight's Ingot":{"ask":5600000,"bid":5200000},"Magician's Cloth":{"ask":8200000,"bid":7600000},"Magician's Hat":{"ask":92000000,"bid":70000000},"Mana Spring":{"ask":880000,"bid":820000},"Manticore Shield":{"ask":18000000,"bid":-1},"Manticore Sting":{"ask":1300000,"bid":1250000},"Orange Key Fragment":{"ask":380000,"bid":300000},"Penetrating Shot":{"ask":1200000,"bid":980000},"Penetrating Strike":{"ask":230000,"bid":190000},"Pestilent Shot":{"ask":96000,"bid":84000},"Purple Key Fragment":{"ask":500000,"bid":320000},"Regal Jewel":{"ask":9800000,"bid":7400000},"Regal Sword":{"ask":-1,"bid":100000000},"Ring Of Threat":{"ask":3200000,"bid":1050000},"Royal Cloth":{"ask":9800000,"bid":9000000},"Royal Fire Robe Bottoms":{"ask":-1,"bid":5200000},"Royal Fire Robe Top":{"ask":-1,"bid":5200000},"Royal Nature Robe Bottoms":{"ask":-1,"bid":10000000},"Royal Nature Robe Top":{"ask":-1,"bid":10000000},"Royal Water Robe Bottoms":{"ask":-1,"bid":-1},"Royal Water Robe Top":{"ask":-1,"bid":-1},"Sinister Cape":{"ask":-1,"bid":-1},"Sinister Chest":{"ask":-1,"bid":-1},"Sinister Essence":{"ask":1900,"bid":1850},"Sinister Key":{"ask":3700000,"bid":3500000},"Smoke Burst":{"ask":105000,"bid":100000},"Stone Key Fragment":{"ask":2100000,"bid":1750000},"Sundering Crossbow":{"ask":420000000,"bid":240000000},"Sundering Jewel":{"ask":14500000,"bid":13500000},"White Key Fragment":{"ask":1000000,"bid":940000}}}`,
        //市场API median算法
        API_URL : "https://raw.githubusercontent.com/holychikenz/MWIApi/main/medianmarket.json",
        //市场API 香港服务器备份
        API_URL_BACKUP:"http://43.129.194.214:5500/apijson"
    },
    recource:{
        //2024.12.21 SVG图标备份 用于保存原始圣系列装备图标
        OLD_SVG_URL : "https://raw.githubusercontent.com/kobayashi7777/milky-way-idel-resource/main/items_sprite.3999af53.svg",
        //Magic Way Idle Logo 右侧文字
        MAGIC_WAY_IDLE_TITLE : 'https://tupian.li/images/2024/10/03/66fd73f009f84.png'
    },
    magic_api:{
        //服务器存活状态,万一哪天服务器挂了所有依赖数据库的服务将都不可用
        SERVER_ALIVE:true,
        //QQ秀上传接口
        QQ_SHOW:"http://www.ratatatata.ip-ddns.com:43967/api/qqshow.php",
        //个人信息上传接口
        PROFILE_SHARED_UPLOAD:"http://www.ratatatata.ip-ddns.com:43967/api/uploadProfileShared.php",
        //组队信息上传接口
        PARTY_INFO:"http://www.ratatatata.ip-ddns.com:43967/api/partyInfo.php"
    }
};

// 功能开启设置
let settingsMap = {
        replaceMagicWayIdleLogo: {
            id: "replaceMagicWayIdleLogo",
            desc:"LOGO替换:左上角LOGO替换为Maigc May Idle",
            isTrue: true,
        },
        deathNotify: {
            id: "deathNotify",
            desc:"死亡报警:队伍中有角色死亡时立即弹窗报警",
            isTrue: true,
        },
        marketPriceUpdate: {
            id: "marketPriceUpdate",
            desc:"价格更新:通过手动查看市场中物品价格,强制更新marketAPI缓存",
            isTrue: true,
        },
        qqShow: {
            id: "qqShow",
            desc:"启用QQ秀:原MWI玩家图标替换功能,现支持即时更换头像",
            isTrue: true,
        },
        taskSorting: {
            id: "taskSorting",
            desc:"任务排序:将任务按照战斗地图顺序自动排列。本功能依赖MWItool,没装的也是神人了",
            isTrue: true,
        },
        taskValue: {
            id: "taskValue",
            desc:"任务价值:显示每个任务的期望收益。本功能依赖食用工具,下载链接附后",
            isTrue: true,
        },
        profileSharedStyle: {
            id: "profileSharedStyle",
            desc:"UI风格:修改MWItool个人面板UI风格与系统UI风格一致",
            isTrue: true,
        },
        marketFreezeFunds: {
            id: "marketFreezeFunds",
            desc:"冻结资金:显示撤单后可获取金币",
            isTrue: true,
        },
        oldHolyItem: {
            id: "oldHolyItem",
            desc:"圣物品图标:显示原版圣系列物品图标",
            isTrue: false,
        }
}

// 全局变量
let globalVariable={
    gameRawData:{
        // 游戏基础数据
        initClientData : null,
        // 老SVG图标链接
        oldSvgBlobUrl : null
    },
    dependency:{
        // 玩家是否安装插件"[银河奶牛]食用工具"
        isInstallEdibleTools : false,
        // 玩家是否安装插件"MWITools"
        isInstallMWITools : false
    },
    replaceMagicWayIdleLogo:{
        isReplaceable : false
    },
    deathNotify : {
        // 队伍中玩家信息
        battleMembers : {},
        // 是否刚进入游戏,继续上次战斗
        isBattleBegin : null
    },
    qqShow:{
        // 保存玩家QQ秀链接
        replacementTargets : {},
        // 图标替换观察者
        observer : null,
        characterName : null
    },
    market:{
        // 是否启用市场API本地备份
        isUsingLocalMarketBackup : false,
        // 当前冻结资金金额
        freezeFundsValue : null,
        // 冻结资金更新标记
        freezeFundsUpdateFlag : false
    },
    task : {
        // 是否处于任务界面
        isTaskSortable : false,
        // 战斗任务索引,使战斗任务始终处于其他任务后面
        taskBattleIndex: 99,
        // 任务类型排序规则
        taskOrderIndex : {
            Milking: 1,
            Foraging: 2,
            Woodcutting: 3,
            Cheesesmithing: 4,
            Crafting: 5,
            Tailoring: 6,
            Cooking: 7,
            Brewing: 8,
            Enhancing: 9,
            Defeat: 99, //战斗处于其他任务后面
        }
    }
};

    // 主函数
    scriptMain();
    function scriptMain(){
        // IOS必定报错,不可与业务逻辑合并。移动设备无弹窗无需修复
        try{
            // 获取通知权限
            Notification.requestPermission().then(function(result) {
                if (result === 'denied') {
                    console.info('无法获取通知权限,强制关闭死亡报警');
                    return;
                }
                if (result === 'default') {
                    return;
                }
            });
        }catch(error){
            console.error(error);
        }
        try{
            // 加载功能设置
            readSettings();
            // 加载游戏基础数据
            globalVariable.gameRawData.initClientData = JSON.parse(localStorage.getItem("initClientData"));
            // 判断依赖:食用工具是否安装
            if('Edible_Tools' in localStorage)globalVariable.dependency.isInstallEdibleTools=true;
            // 判断依赖:MWITools是否安装
            if('script_settingsMap' in localStorage)globalVariable.dependency.isInstallMWITools=true;
            // 拦截WebSocket
            hookWebSocket();
            // 若功能设置开启,且服务器存活 => 开启QQ秀功能
            if(settingsMap.qqShow.isTrue && global_url_config.magic_api.SERVER_ALIVE){
                // 优先从缓存加载QQ秀
                if('magic_qqshow_cache' in localStorage){
                    globalVariable.qqShow.replacementTargets=JSON.parse(localStorage.getItem("magic_qqshow_cache"));
                }
                if('magic_qqshow_cache_timestamp' in localStorage){
                    // 若缓存过期(有效期 1 天) => 立即更新缓存
                    if(Math.abs(Date.now()- localStorage.getItem("magic_qqshow_cache_timestamp"))>86400000)getQQShowData();
                }else{
                    // 未找到缓存  => 立即更新缓存
                    getQQShowData();
                }
                // 初始化观察者,分配替换目标
                initQQShowObserver();
                // 启动观察者,替换QQ秀
                globalVariable.qqShow.observer.observe(document, { attributes: false, childList: true, subtree: true });
            }
            // 统一观察者
            let globalObserver=new MutationObserver(function (mutationsList, observer) {
                if(settingsMap.replaceMagicWayIdleLogo.isTrue)replaceMagicWayIdleLogo();
                // 任务排序 & 显示任务价值,依赖MWItool
                if(globalVariable.dependency.isInstallMWITools)autoClickTaskManager();
                // 显示QQ秀提交UI
                if(settingsMap.qqShow.isTrue && global_url_config.magic_api.SERVER_ALIVE)addQQshowButton();
                // 显示冻结资金
                if(settingsMap.marketFreezeFunds.isTrue)showMarketFreezeFunds();
                // 修改MWITools的个人资料页面
                if(settingsMap.profileSharedStyle.isTrue)fixPlayerInfoStyle();
                // 修改神圣奶酪系列道具图标
                if(settingsMap.oldHolyItem.isTrue)replaceHolyItemIcon();
                // 显示功能设置面板
                addSettingMenu();
            });
            globalObserver.observe(document,{ childList: true, subtree: true });
            globalVariable.deathNotify.isBattleBegin=true;
        }catch(error){
            console.error(error);
        }
    }
    // 拦截WS
    function hookWebSocket() {
        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 && socket.url.indexOf("api-test.milkywayidle.com/ws") <= -1) {
                return oriGet.call(this);
            }
            const message = oriGet.call(this);
            Object.defineProperty(this, "data", { value: message });
            return handleMessage(message);
        }
    }
    // WS拦截后处理,主进程
    function handleMessage(message,debug=false) {
        let obj = JSON.parse(message);
        if (obj && obj.type === "init_character_data") {
            // 切角色,再次刷新左上角LOGO
            globalVariable.replaceMagicWayIdleLogo.isReplaceable = true;
            // 读取角色名称用于上传QQ秀
            globalVariable.qqShow.characterName=obj.character.name;
            // 刚进入游戏,可能继续上次战斗 => 标记为刚进入战斗
            globalVariable.deathNotify.isBattleBegin=true;
            // 战斗排行
            addRankButton();
            // 组队情况
            addPartyButton();
            // 读取背包
            uploadInitCharacterData(obj);
            globalVariable.market.freezeFundsValue=calculateMarketFreezeFunds(obj.myMarketListings);
        }else if (obj && obj.type === "new_battle") {
            // 死亡报警
            if(settingsMap.deathNotify.isTrue)notifyDeath(obj);
        } else if (obj && obj.type === "battle_updated") {
            // 死亡报警
            if(settingsMap.deathNotify.isTrue)notifyDeath(obj);
        }else if (obj && obj.type === "profile_shared"){
            // 上传个人资料
            uploadProfileShared(obj);
        }else if (obj && obj.type === "market_item_order_books_updated") {
            // 强制刷新市场价格
            if(settingsMap.marketPriceUpdate.isTrue)marketPriceUpdate(obj);
        }else if (obj && obj.type === "actions_updated") {
            // 切换行动,可能开始战斗 => 标记为刚进入战斗
            globalVariable.deathNotify.isBattleBegin=true;
        }else if(obj && obj.type ==="market_listings_updated"){
            // 维护冻结资金挂单、撤单
            updateMarketFreezeFunds(obj);
        }
        //other
        return message;
    }
    // 加载功能设置面板
    function addSettingMenu(){
        const targetNode = document.querySelector("div.SettingsPanel_profileTab__214Bj");
        if (targetNode) {
            if (!targetNode.querySelector("#script_settings_magic_way_idle")) {
                targetNode.insertAdjacentHTML("beforeend", `<div id="script_settings_magic_way_idle"></div>`);
                const insertElem = targetNode.querySelector("div#script_settings_magic_way_idle");
                insertElem.insertAdjacentHTML(
                    "beforeend",
                    `<div style="float: left;">${
                        "MagicWayIdle 设置 (刷新生效):"
                    }</div></br>`
                );
                for (const setting of Object.values(settingsMap)) {
                    insertElem.insertAdjacentHTML(
                        "beforeend",
                        `<div style="float: left;"><input type="checkbox" id="${setting.id}" ${setting.isTrue ? "checked" : ""}></input>${
                            setting.desc
                        }</div></br>`
                    );
                }
                insertElem.insertAdjacentHTML(
                    "beforeend",
                    `<div style="float: left;">${
                        "食用工具下载: https://greasyfork.org/zh-CN 搜索 [银河奶牛]食用工具"
                    }</div></br>`
                );
                insertElem.addEventListener("change", saveSettings);
            }
        }

    }
    // 保存功能设置
    function saveSettings() {
        for (const checkbox of document.querySelectorAll("div#script_settings_magic_way_idle input")) {
            settingsMap[checkbox.id].isTrue = checkbox.checked;
            localStorage.setItem("magic_script_settings", JSON.stringify(settingsMap));
        }
    }
    // 加载功能设置
    function readSettings() {
        const local_storage = localStorage.getItem("magic_script_settings");
        if (local_storage) {
            const obj = JSON.parse(local_storage);
            for (const option of Object.values(obj)) {
                if (settingsMap.hasOwnProperty(option.id)) {
                    settingsMap[option.id].isTrue = option.isTrue;
                }
            }
        }
    }
    // LOGO替换
    function replaceMagicWayIdleLogo() {
        //本次登录已替换过Logo
        if(!globalVariable.replaceMagicWayIdleLogo.isReplaceable)return;
        //待替换Logo,右侧标题
        const logoDiv = document.querySelector('div.Header_logoContainer__1sCnZ');
        const textDiv = document.querySelector('div.Header_title__5Mj8z');
        //检测玩家总等级是否加载,以判断游戏主界面是否彻底加载完成
        const load_check=document.querySelector('div.Header_totalLevel__8LY3Q');
        //完全加载完毕
        if (load_check && logoDiv && textDiv &&logoDiv.children.length > 0 && textDiv.children.length > 0&& logoDiv.querySelector('svg')&& textDiv.querySelector('svg')) {
            let originalLogo = logoDiv.firstChild;
            const originaltext = textDiv.firstChild;
            //获取原生魔法Logo
            const magicLogoHref = document.querySelector('use[href*=".svg#magic"]')?.getAttribute('href');
            if(magicLogoHref){
                //替换Logo
                originalLogo.querySelector('use')?.setAttribute('href',magicLogoHref);
                //替换右侧标题
                const newtext = document.createElement('img');
                newtext.src = global_url_config.recource.MAGIC_WAY_IDLE_TITLE;
                newtext.width = '64';
                newtext.height = '64';
                originaltext.parentNode.replaceChild(newtext, originaltext);
                globalVariable.replaceMagicWayIdleLogo.isReplaceable=false;
            }
        }
    }
    // 死亡报警
    function notifyDeath(obj){
        if (obj && obj.type === "new_battle"){
            //战斗人员信息初始化
            if(globalVariable.deathNotify.isBattleBegin){
                globalVariable.deathNotify.isBattleBegin=false;
                globalVariable.deathNotify.battleMembers={};
                for(const key in obj.players){
                    globalVariable.deathNotify.battleMembers[key]={
                        name:obj.players[key].character.name,
                        isalive:true
                    };
                }
            }
            for(const key in obj.players){
                if(obj.players[key].isActive){
                    globalVariable.deathNotify.battleMembers[key].isalive=true;
                }else{
                    if(globalVariable.deathNotify.battleMembers[key].isalive){
                        showNotification(`${globalVariable.deathNotify.battleMembers[key].name}死了`);
                    }
                    globalVariable.deathNotify.battleMembers[key].isalive=false;
                }
            }
        }else if (obj && obj.type === "battle_updated") {
            if(obj.pMap){
                for (const key in obj.pMap) {
                    if(obj.pMap[key].cHP==0){
                        if(globalVariable.deathNotify.battleMembers[key].isalive){
                            globalVariable.deathNotify.battleMembers[key].isalive=false;
                            showNotification(`${globalVariable.deathNotify.battleMembers[key].name}死了`);
                        }
                    }else{
                        if(globalVariable.deathNotify.battleMembers[key].isalive!==undefined)globalVariable.deathNotify.battleMembers[key].isalive=true;
                    }
                }
            }
        }
    }
    // 强制刷新市场价格
    function marketPriceUpdate(obj){
        let itemDetailMap=globalVariable.gameRawData.initClientData.itemDetailMap;
        let itemName=itemDetailMap[obj.marketItemOrderBooks.itemHrid].name;
        let ask=-1;
        let bid=-1;
        //读取ask最低报价
        if(obj.marketItemOrderBooks.orderBooks[0].asks.length>0){
            ask=obj.marketItemOrderBooks.orderBooks[0].asks[0].price;
        }
        //读取bid最高报价
        if(obj.marketItemOrderBooks.orderBooks[0].bids.length>0){
            bid=obj.marketItemOrderBooks.orderBooks[0].bids[0].price;
        }
        //读取所有物品价格
        let jsonObj = JSON.parse(localStorage.getItem("MWITools_marketAPI_json"));
        //修改当前查看物品价格
        if(jsonObj.market[itemName]){
            jsonObj.market[itemName].ask=ask;
            jsonObj.market[itemName].bid=bid;
        }
        //将修改后结果写回marketAPI缓存,完成对marketAPI价格的强制修改
        localStorage.setItem("MWITools_marketAPI_json", JSON.stringify(jsonObj));
    }


    // 任务排序
    // Source: MWI TaskManager 0.2
    // Author:微信群 shykai
    // 任务排序:主函数 => 任务自动排序/显示任务价值
    function autoClickTaskManager() {
        const isInTask = document.querySelector("div.TasksPanel_taskSlotCount__nfhgS");
        const isAllTaskAdd = document.querySelector("div.TasksPanel_taskList__2xh4k");
        const isIndexAdd = document.querySelector("span.script_taskMapIndex");
        if (isInTask){
            //进入任务界面
            if(isAllTaskAdd&&globalVariable.task.isTaskSortable&&isIndexAdd){
                globalVariable.task.isTaskSortable=false;
                const list = document.querySelector("div.TasksPanel_taskList__2xh4k");
                const nodes = [...list.querySelectorAll("div.RandomTask_randomTask__3B9fA")];
                if(settingsMap.taskSorting.isTrue)nodes.sort(compareFn).forEach(node => list.appendChild(node));
                //依赖满足计算收益
                if(settingsMap.taskValue.isTrue && globalVariable.dependency.isInstallEdibleTools){
                    function convertKEndStringToNumber(str) {
                        if (str.endsWith('K')||str.endsWith('k')) {
                            return Number(str.slice(0, -1)) * 1000;
                        } else {
                            return Number(str);
                        }
                    }
                    let tokenValue=Number(getTaskTokenValue());
                    nodes.forEach(function (node) {
                    let reward=node.querySelector("div.RandomTask_rewards__YZk7D");
                    let coin=convertKEndStringToNumber(reward.querySelectorAll("div.Item_count__1HVvv")[0].innerText);
                    let token=Number(reward.querySelectorAll("div.Item_count__1HVvv")[1].innerText);
                    let newDiv = document.createElement("div");
                    newDiv.textContent = "期望收益: "+(addCommasToNumber((coin+token*tokenValue).toFixed(0)));
                    newDiv.style.color = 'gold';
                    node.querySelector("div.RandomTask_action__3eC6o").appendChild(newDiv);
                });
                }
            }
        }else{
            //其他界面或没加载按钮
            globalVariable.task.isTaskSortable=true;
        }
    }
    // 支持修改版汉化插件
    function getOriTextFromElement(elem) {
        if (!elem) {
            //console.error("getTextFromElement null elem");
            return "";
        }
        const translatedfrom = elem.getAttribute("script_translatedfrom");
        if (translatedfrom) {
            return translatedfrom;
        }
        return elem.textContent;
    }
    // 兼容MWITools地图编号
    function getMapIndexFromElement(elem) {
        var node = elem.querySelector("span.script_taskMapIndex");
        if (!node) {
            return -1;
        }
        return Number(node.textContent.replace(/\D/ig, ""));
    }
    // 任务排序:任务名称 => 该任务类型序号
    function getTaskOrderIndexByTaskName(taskName) {
        var taskType = -1;
        if (/^(Defeat)( [\S ]+)$/.test(taskName)) {
            //使战斗任务始终处于其他任务后面
            taskType = globalVariable.task.taskBattleIndex;
        } else if (/^(.+) - .+$/.test(taskName)) {
            let res = /^(.+) - .+$/.exec(taskName);
            if (res[1] in globalVariable.task.taskOrderIndex) {
                taskType = globalVariable.task.taskOrderIndex[res[1]];
            }
        }
        //if (taskType == -1) console.log(taskName, taskType);
        return taskType;
    }
    // 任务排序:比较A, B任务顺序
    function compareFn(a, b) {
        var a_name = getOriTextFromElement(a.querySelector("div.RandomTask_name__1hl1b"));
        var b_name = getOriTextFromElement(b.querySelector("div.RandomTask_name__1hl1b"));

        var a_index = getTaskOrderIndexByTaskName(a_name);
        var b_index = getTaskOrderIndexByTaskName(b_name);

        if (a_index === globalVariable.task.taskBattleIndex && b_index === globalVariable.task.taskBattleIndex) {
            var a_MapIndex = getMapIndexFromElement(a);
            var b_MapIndex = getMapIndexFromElement(b);

            if (a_MapIndex != b_MapIndex) {
                return (a_MapIndex > b_MapIndex ? 1 : -1);
            }
        }

        if (a_index == b_index) {
            return a_name == b_name ? 0
                : (a_name > b_name ? 1 : -1);
        }

        return a_index > b_index ? 1 : -1;
    }
    // 任务价值:给任务价值数值千分位打逗号
    function addCommasToNumber(number) {
       return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
    // 任务价值:计算单个任务代币价值
    function getTaskTokenValue(){
        if(!globalVariable.dependency.isInstallEdibleTools)return -1;
        //读取食用工具缓存,计算代币价值
        let obj=JSON.parse(localStorage.getItem("Edible_Tools"));
        //1代币价值 = 1/30陨石箱子 + 1/50牛紫的礼物
        let value=obj.Chest_Drop_Data["Large Meteorite Cache"].期望产出Bid/30.0+obj.Chest_Drop_Data["Purple's Gift"].期望产出Bid/50.0;
        return value;
    }

    //战斗排行
    function addRankButton() {
        const waitForNavi = () => {
            const targetNode = document.querySelector("div.NavigationBar_minorNavigationLinks__dbxh7"); // 确认这个选择器是否适合你的环境
            const navigationLinks = document.querySelectorAll('div.NavigationBar_minorNavigationLink__31K7Y');
            let toolLink;
            for (let link of navigationLinks) {
                if (link.textContent.includes('插件设置')||link.textContent.includes('Script settings')) {
                    toolLink = link;
                    break;
                }
            }
            if (targetNode&&toolLink) {
                let statsButton = document.createElement("div");
                statsButton.setAttribute("class", "NavigationBar_minorNavigationLink__31K7Y");
                statsButton.style.color = toolLink.style.color;
                statsButton.innerHTML = "战斗排行榜";
                statsButton.addEventListener("click", () => {
                    window.open("http://www.ratatatata.ip-ddns.com:43967/cnxp.php", "_blank");
                });
                // 将按钮添加到目标节点
                targetNode.insertBefore(statsButton, toolLink.nextSibling);
            } else {
                setTimeout(addRankButton, 200);
            }
        };
        waitForNavi(); // 开始等待目标节点出现
    }
    //组队情况
    function addPartyButton() {
        const waitForNavi = () => {
            const targetNode = document.querySelector("div.NavigationBar_minorNavigationLinks__dbxh7"); // 确认这个选择器是否适合你的环境
            const navigationLinks = document.querySelectorAll('div.NavigationBar_minorNavigationLink__31K7Y');
            let toolLink;
            for (let link of navigationLinks) {
                if (link.textContent.includes('插件设置')||link.textContent.includes('Script settings')) {
                    toolLink = link;
                    break;
                }
            }
            if (targetNode&&toolLink) {
                let statsButton = document.createElement("div");
                statsButton.setAttribute("class", "NavigationBar_minorNavigationLink__31K7Y");
                statsButton.style.color = toolLink.style.color;
                statsButton.innerHTML = "国人组队情况";
                statsButton.addEventListener("click", () => {
                    window.open("http://www.ratatatata.ip-ddns.com:43967/cnparty.php", "_blank");
                });
                // 将按钮添加到目标节点
                targetNode.insertBefore(statsButton, toolLink.nextSibling);
            } else {
                setTimeout(addPartyButton, 200);
            }
        };
        waitForNavi(); // 开始等待目标节点出现
    }

    //追踪设置,添加头像设置栏
    function addQQshowButton() {
        const targetNode = document.querySelector("div.SettingsPanel_infoGrid__2nh1u");
        const isqqshowFlagExist = document.querySelector("div.qqshow");
        if(targetNode&&!isqqshowFlagExist){
            const nameColor=targetNode.querySelectorAll("div.SettingsPanel_value__2nsKD")[2];
            let qqshowtitlediv = document.createElement("div");
            let qqshowdiv = document.createElement("div");
            let qqshowdivflag = document.createElement("div");
            qqshowtitlediv.setAttribute("class", "SettingsPanel_label__24LRD");
            qqshowtitlediv.innerHTML="更新QQ秀";
            qqshowdiv.setAttribute("class", "SettingsPanel_value__2nsKD");
            qqshowdiv.style=nameColor.style;
            qqshowdivflag.setAttribute("class", "qqshow");
            let qqshowURLInput = document.createElement("input");
            qqshowURLInput.type = "text";
            qqshowURLInput.setAttribute("class", "qqshowURLInput");
            qqshowURLInput.placeholder = "图床url/提交空白视为删除";
            let qqshowSubmitButton = document.createElement("button");
            qqshowSubmitButton.setAttribute("class", "Button_button__1Fe9z");
            qqshowSubmitButton.textContent = "提交";
            qqshowSubmitButton.addEventListener("click", qqshowSubmit);
            qqshowdiv.appendChild(qqshowdivflag);
            qqshowdiv.appendChild(qqshowURLInput);
            qqshowdiv.appendChild(qqshowSubmitButton);
            let readmetitlediv = document.createElement("div");
            let readme = document.createElement("div");
            readmetitlediv.setAttribute("class", "SettingsPanel_label__24LRD");
            readme.setAttribute("class", "SettingsPanel_value__2nsKD");
            readme.innerHTML="先去tupian.li等图床上传图片,再提交url。<br> 直接提交空白将删除QQ秀。刷新后生效。"

            nameColor.parentNode.insertBefore(readme, nameColor.nextSibling);
            nameColor.parentNode.insertBefore(readmetitlediv, nameColor.nextSibling);

            nameColor.parentNode.insertBefore(qqshowdiv, nameColor.nextSibling);
            nameColor.parentNode.insertBefore(qqshowtitlediv, nameColor.nextSibling);
        }
    }
    function qqshowSubmit(){
        let qqshowURLInput=document.querySelector("input.qqshowURLInput");
        let url=qqshowURLInput.value
        function isValidURL(str) {
            try {
                new URL(str);
                return true;
            } catch (err) {
                return false;
            }
        }
        if(url==''){
            showToast("已删除,刷新生效");
            localStorage.setItem("MWIQQshow_timestamp",0);
            updateqqshow(url);
        }else if(isValidURL(url)){
            showToast("已提交,刷新生效");
            localStorage.setItem("MWIQQshow_timestamp",0);
            updateqqshow(url);
        }else{
            showToast("url不合法");
        }
    }

    //更新QQ秀
     function updateqqshow(face_url){
         if (globalVariable.qqShow.characterName == "" || typeof globalVariable.qqShow.characterName === "undefined") {
             showToast("非法更新,请刷新页面");
             return;
         }
         const postData = {
             [globalVariable.qqShow.characterName]: face_url
         };
         return new Promise((resolve, reject) => {
             GM_xmlhttpRequest({
                 method: 'POST',
                 url: global_url_config.magic_api.QQ_SHOW,
                 headers: {
                     "Content-Type": "application/json"
                 },
                 data:JSON.stringify(postData),
                 onload: function (response) {
                     console.log("请求成功,响应状态码: ", response.status);
                     console.log("响应内容: ", response.responseText);
                     resolve();
                 },
                 onerror: function (error) {
                     console.error('QQ秀更新出错:', error);
                     reject(error);
                 }
             });
         });
    }

    //获取所有玩家QQ秀图片链接
    function getQQShowData(){
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'GET',
                url: global_url_config.magic_api.QQ_SHOW,
                headers: {
                     "Content-Type": "application/json"
                 },
                onload: function (response) {
                    try {
                        const data = JSON.parse(response.responseText);
                        globalVariable.qqShow.replacementTargets=data;
                        localStorage.setItem("magic_qqshow_cache_timestamp", Date.now());
                        localStorage.setItem("magic_qqshow_cache",JSON.stringify(globalVariable.qqShow.replacementTargets));
                        resolve();
                    } catch (jsonError) {
                        console.error('Error parsing JSON:', jsonError);
                        reject(jsonError);
                    }
                },
                onerror: function (error) {
                    console.error('获取失败:', error);
                    reject(error);
                }
            });
        });
    }


    // Source: MWI玩家图标替换
    // Author: Ak4r1 ChatGpt Stella bot7420
    function replaceIconsIn(node) {
        const iconElements = node.querySelectorAll(`div.FullAvatar_fullAvatar__3RB2h`);
        for (const elem of iconElements) {
            if (elem.closest("div.CowbellStorePanel_avatarsTab__1nnOY")) {
                continue; // 商店页面
            }

            const playerId = findPlayerIdByAvatarElem(elem);
            if (!playerId) {
                //console.error("ICONS: replaceIconsIn can't find playerId");
                //设置页面下面两个小人会引发异常,不要大惊小怪
                //console.log(elem);
                continue; // 找不到 playerId
            }

            if (!globalVariable.qqShow.replacementTargets.hasOwnProperty(playerId)) {
                continue; // 没有配置图片地址
            }

            const newImgElement = document.createElement("img");
            newImgElement.src = globalVariable.qqShow.replacementTargets[playerId];
            newImgElement.style.width = "100%";
            newImgElement.style.height = "auto";
            elem.innerHTML = "";
            elem.appendChild(newImgElement);
        }
    }
    function findPlayerIdByAvatarElem(avatarElem) {
        // Profile 窗口页
        const profilePageDiv = avatarElem.closest("div.SharableProfile_modal__2OmCQ");
        if (profilePageDiv) {
            return profilePageDiv.querySelector(".CharacterName_name__1amXp")?.textContent.trim();
        }
        // 网页右上角
        const headerDiv = avatarElem.closest("div.Header_header__1DxsV");
        if (headerDiv) {
            return headerDiv.querySelector(".CharacterName_name__1amXp")?.textContent.trim();
        }
        // 战斗页面
        const combatDiv = avatarElem.closest("div.CombatUnit_combatUnit__1m3XT");
        if (combatDiv) {
            return combatDiv.querySelector(".CombatUnit_name__1SlO1")?.textContent.trim();
        }

        // 组队页面
        const partyDiv = avatarElem.closest("div.Party_partySlot__1xuiq");
        if (partyDiv) {
            return partyDiv.querySelector(".CharacterName_name__1amXp")?.textContent.trim();
        }
        return null;
    }

    //初始化观察者,分配替换目标
    function initQQShowObserver(){
        globalVariable.qqShow.observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (
                        node.tagName === "DIV" &&
                        !node.classList.contains("ProgressBar_innerBar__3Z_sf") &&
                        !node.classList.contains("CountdownOverlay_countdownOverlay__2QRmL") &&
                        !node.classList.contains("ChatMessage_chatMessage__2wev4") &&
                        !node.classList.contains("Header_loot__18Cbe") &&
                        !node.classList.contains("script_itemLevel") &&
                        !node.classList.contains("script_key") &&
                        !node.classList.contains("dps-info") &&
                        !node.classList.contains("MuiTooltip-popper")
                    ) {
                        replaceIconsIn(node);
                    }
                });
            });
        });
    }

    // 显示提醒
    // showToast()
    // Source: **助手
    // Author: Trutn_Light Stella
    const toastQueues = Array.from({ length: 5 }, () => []);
    const maxVisibleToasts = Math.floor(window.innerHeight / 2 / 50);
    let isToastVisible = Array(5).fill(false);
    function displayNextToast(queueIndex) {
    if (isToastVisible[queueIndex] || toastQueues[queueIndex].length === 0) return;
    const { message, duration } = toastQueues[queueIndex].shift();
    isToastVisible[queueIndex] = true;
    const toast = createToastElement(message, queueIndex);
    toast.style.opacity = '0';
    requestAnimationFrame(() => {
        toast.style.opacity = '1';
    });
    setTimeout(() => {
        toast.style.opacity = '0';
        setTimeout(() => {
            document.body.removeChild(toast);
            isToastVisible[queueIndex] = false;
            displayNextToast(queueIndex);
        }, 500);
    }, duration);
    }
    function showToast(message, duration = 2000) {
        const queueIndex = toastQueues.findIndex(queue => queue.length < maxVisibleToasts);
        if (queueIndex === -1) return;
        toastQueues[queueIndex].push({ message, duration });
        displayNextToast(queueIndex);
    }
    function createToastElement(message, queueIndex) {
    const toast = document.createElement('div');
    toast.className = 'toast';
    toast.style.position = 'fixed';
    toast.style.bottom = `${20 + queueIndex * 60}px`;
    toast.style.left = '50%';
    toast.style.transform = 'translateX(-50%)';
    toast.style.backgroundColor = '#333';
    toast.style.color = '#fff';
    toast.style.padding = '10px 20px';
    toast.style.borderRadius = '5px';
    toast.style.zIndex = '1000';
    toast.style.textAlign = 'center';
    toast.style.transition = 'opacity 0.5s';
    toast.textContent = message;
    document.body.appendChild(toast);
    return toast;
    }


    function showMarketFreezeFunds(){
        const targetNode = document.querySelector("div.MarketplacePanel_coinStack__1l0UD");
        //const isFreezeFundsExist = document.querySelector("div.FreezeFundsFlag");
        if(targetNode){
            if(globalVariable.market.freezeFundsUpdateFlag){
                const isFreezeFundsExist= document.querySelector("div.FreezeFunds");
                if (isFreezeFundsExist) {
                    isFreezeFundsExist.parentNode.removeChild(isFreezeFundsExist);
                }
                let freezeFunds = targetNode.cloneNode(true);
                const countNode = freezeFunds.querySelector("div.Item_count__1HVvv");
                const textNode = freezeFunds.querySelector("div.Item_name__2C42x");
                if (countNode)countNode.textContent = formatCoinValue(globalVariable.market.freezeFundsValue);
                if (textNode)textNode.textContent = "冻结资金";
                freezeFunds.style.left = "110px";
                freezeFunds.classList.add("FreezeFunds");
                targetNode.parentNode.insertBefore(freezeFunds, targetNode.nextSibling);
                globalVariable.market.freezeFundsUpdateFlag=false;
                //console.log("#######",calculateALLFunds());
            }
         }
    }
    function formatCoinValue(num) {
        if (num >= 1e9) {
            return (num / 1e9).toFixed(0) + "B";
        } else if (num >= 1e6) {
            return (num / 1e6).toFixed(0) + "M";
        } else if (num >= 1e3) {
            return (num / 1e3).toFixed(0) + "K";
        }
        return num.toString();
    }


    function calculateMarketFreezeFunds(ini_marketListings){
        let networth=0;
        for (const item of ini_marketListings) {
            const quantity = item.orderQuantity - item.filledQuantity;
            if (!item.isSell) {
                networth+=quantity * item.price;
            }
        }
        globalVariable.market.freezeFundsUpdateFlag=true;
        return networth;
    }
    function updateMarketFreezeFunds(obj){
        obj.endMarketListings.forEach((item) => {
            if(!item.isSell){
                const quantity = item.orderQuantity - item.filledQuantity;
                if(item.status=="/market_listing_status/active"){
                    if(item.filledQuantity==0&&item.unclaimedItemCount==0){
                        //主动挂单
                        globalVariable.market.freezeFundsValue+=quantity*item.price;
                    }else if(item.unclaimedItemCount>0){
                        //被动撤单(成功买进)
                        globalVariable.market.freezeFundsValue-=item.unclaimedItemCount*item.price;
                    }
                }else if(item.status=="/market_listing_status/cancelled"){
                    //主动撤单
                    globalVariable.market.freezeFundsValue-=quantity*item.price;
                }
                globalVariable.market.freezeFundsUpdateFlag=true;
            }
        });
    }

    function fixPlayerInfoStyle(){
       const allButtons = document.getElementsByTagName('button');
       for (const button of allButtons){
           if (button.innerText == "导出人物到剪贴板") {
               button.style.backgroundColor = '#4357AF';
               button.style.color = 'white';
           }
       }
       const targetDiv = document.getElementById('toggleScores_profile');
        if (targetDiv) {
            const allChildren = targetDiv.parentNode.querySelectorAll('*');
            allChildren.forEach(function (element) {
                element.style.color = '#E7E7E7';
                element.style.fontWeight = '';
                element.style.fontSize = '16px';
            });
        }
    }
    function uploadProfileShared(obj){
        return new Promise((resolve, reject) => {
             GM_xmlhttpRequest({
                 method: 'POST',
                 url: global_url_config.magic_api.PROFILE_SHARED_UPLOAD,
                 headers: {
                     "Content-Type": "application/json"
                 },
                 data:JSON.stringify(obj),
                 onload: function (response) {
                     resolve();
                 },
                 onerror: function (error) {
                     reject(error);
                 }
             });
         });
    }
    function uploadInitCharacterData(obj){
        const fake_profile_shared={}
        fake_profile_shared.type="profile_shared";
        fake_profile_shared.profile={};
        fake_profile_shared.profile.characterSkills=obj.characterSkills;
        fake_profile_shared.profile.combatLevel=obj.combatUnit.combatDetails.combatLevel;
        if(obj.guild){
            fake_profile_shared.profile.guildName=obj.guild.name;
            fake_profile_shared.profile.guildRole=obj.guildCharacterMap[obj.character.id].role;
        }else{
            fake_profile_shared.profile.guildName="";
            fake_profile_shared.profile.guildRole="";
        }
        fake_profile_shared.profile.sharableCharacter=obj.character;
        fake_profile_shared.profile.wearableItemMap={}
        obj.characterItems.forEach(item=>{
            if(item.itemLocationHrid!='/item_locations/inventory'){
                fake_profile_shared.profile.wearableItemMap[item.itemLocationHrid]=item;
            }
        })
        uploadProfileShared(fake_profile_shared);
        uploadPartyInfo(obj);
    }
    function uploadPartyInfo(obj){
        const party_info={};
        party_info.reporter=obj.character.id;
        party_info.is_battle=false;
        if(obj.partyInfo){
            party_info.is_battle=true;
            party_info.partyInfo=obj.partyInfo;
        }
        return new Promise((resolve, reject) => {
             GM_xmlhttpRequest({
                 method: 'POST',
                 url: global_url_config.magic_api.PARTY_INFO,
                 headers: {
                     "Content-Type": "application/json"
                 },
                 data:JSON.stringify(party_info),
                 onload: function (response) {
                     resolve();
                 },
                 onerror: function (error) {
                     reject(error);
                 }
             });
         });
    }
    //修改神圣奶酪系列道具图标
    //IOS失效待修复
    function replaceHolyItemIcon(){
        const holySvgs = document.querySelectorAll('svg:has(use[href*="holy"])');
        if(globalVariable.gameRawData.oldSvgBlobUrl){
            holySvgs.forEach(svg => {
                const useElement = svg.querySelector('use');
                if (useElement) {
                    const oldHref = useElement.getAttribute('href');
                    if (oldHref&&oldHref.startsWith("/static")&& oldHref.indexOf("#holy_cow") === -1) {
                        const newHref =globalVariable.gameRawData.oldSvgBlobUrl + '#' + oldHref.split('#')[1];
                        useElement.setAttribute('href', newHref);
                    }
                }
            });
        }else{
            loadCrossDomainSvg().then(() => {
                holySvgs.forEach(svg => {
                    const useElement = svg.querySelector('use');
                    if (useElement) {
                        const oldHref = useElement.getAttribute('href');
                        if (oldHref&&oldHref.startsWith("/static")&& oldHref.indexOf("#holy_cow") === -1) {
                            const newHref =globalVariable.gameRawData.oldSvgBlobUrl + '#' + oldHref.split('#')[1];
                            useElement.setAttribute('href', newHref);
                        }
                    }
                });
            });
        }
    }
    //加载老SVG到blob解决资源跨域问题
    async function loadCrossDomainSvg() {
        try {
            const response = await fetch(global_url_config.recource.OLD_SVG_URL);
            const blob = await response.blob();
            globalVariable.gameRawData.oldSvgBlobUrl = URL.createObjectURL(blob);
        } catch (error) {
            console.log("Error:", error);
        }
    }
    //other
    //工具函数:发送弹窗 => 死亡报警
    function showNotification(textToPrint){
        let notification = new Notification('Magic Way Idle', {
            body: textToPrint,
        });
    }
    //工具函数:市场API => (暂未使用)
    async function fetchMarketJSON(forceFetch = false) {
        let sendRequest = GM.xmlHttpRequest || GM_xmlhttpRequest;
        if (typeof sendRequest != 'function') {
            //console.error("fetchMarketJSON null function");
            globalVariable.market.isUsingLocalMarketBackup = true;
            const jsonStr = global_url_config.market.LOCAL_BACKUP;
            const jsonObj = JSON.parse(jsonStr);
            if (jsonObj && jsonObj.time && jsonObj.market) {
                jsonObj.market.Coin.ask = 1;
                jsonObj.market.Coin.bid = 1;
                //console.log(jsonObj);
                localStorage.setItem("MWITools_marketAPI_timestamp", Date.now());
                localStorage.setItem("MWITools_marketAPI_json", JSON.stringify(jsonObj));
                return jsonObj;
            }
        }

        if (
            !forceFetch &&
            localStorage.getItem("MWITools_marketAPI_timestamp") &&
            Date.now() - localStorage.getItem("MWITools_marketAPI_timestamp") < 900000
        ) {
            return JSON.parse(localStorage.getItem("MWITools_marketAPI_json"));
        }

        //console.log("fetchMarketJSON fetch github start");
        let jsonStr = null;
        jsonStr = await new Promise((resolve, reject) => {
            sendRequest({
                url: global_url_config.market.API_URL,
                method: "GET",
                synchronous: true,
                timeout: 5000,
                onload: async (response) => {
                    if (response.status == 200) {
                        //console.log("fetchMarketJSON fetch github success 200");
                        resolve(response.responseText);
                    } else {
                        //console.error("fetchMarketJSON fetch github onload with HTTP status failure " + response.status);
                        resolve(null);
                    }
                },
                onabort: () => {
                    //console.error("fetchMarketJSON fetch github onabort");
                    resolve(null);
                },
                onerror: () => {
                    //console.error("fetchMarketJSON fetch github onerror");
                    resolve(null);
                },
                ontimeout: () => {
                    //console.error("fetchMarketJSON fetch github ontimeout");
                    resolve(null);
                },
            });
        });

        if (jsonStr === null) {
            //console.log("fetchMarketJSON fetch backup start");
            jsonStr = await new Promise((resolve, reject) => {
                sendRequest({
                    url: global_url_config.market.API_URL_BACKUP,
                    method: "GET",
                    synchronous: true,
                    timeout: 5000,
                    onload: async (response) => {
                        if (response.status == 200) {
                            //console.log("fetchMarketJSON fetch backup success 200");
                            resolve(response.responseText);
                        } else {
                            //console.error("fetchMarketJSON fetch backup onload with HTTP status failure " + response.status);
                            resolve(null);
                        }
                    },
                    onabort: () => {
                        //console.error("fetchMarketJSON fetch backup onabort");
                        resolve(null);
                    },
                    onerror: () => {
                        //console.error("fetchMarketJSON fetch backup onerror");
                        resolve(null);
                    },
                    ontimeout: () => {
                        console.error("fetchMarketJSON fetch backup ontimeout");
                        resolve(null);
                    },
                });
            });
        }

        if (!jsonStr) {
            //console.error("fetchMarketJSON network error, using local version");
            globalVariable.market.isUsingLocalMarketBackup = true;
            jsonStr = global_url_config.market.LOCAL_BACKUP;
        } else {
            globalVariable.market.isUsingLocalMarketBackup = false;
        }

        const jsonObj = JSON.parse(jsonStr);
        if (jsonObj && jsonObj.time && jsonObj.market) {
            jsonObj.market.Coin.ask = 1;
            jsonObj.market.Coin.bid = 1;
            //console.log(jsonObj);
            localStorage.setItem("MWITools_marketAPI_timestamp", Date.now());
            localStorage.setItem("MWITools_marketAPI_json", JSON.stringify(jsonObj));
            return jsonObj;
        }
        //console.error("MWITools: fetchMarketJSON JSON.parse error");
        localStorage.setItem("MWITools_marketAPI_timestamp", 0);
        localStorage.setItem("MWITools_marketAPI_json", "");
        return null;
    }


})();