// ==UserScript== // @name MouseHunt Enhanced Search (Beta) // @description Improve the search logic of search bars in the game // @author LethalVision // @version 1.2.0 // @match https://www.mousehuntgame.com/* // @match https://apps.facebook.com/mousehunt/* // @icon https://www.google.com/s2/favicons?domain=mousehuntgame.com // @grant none // @license MIT // @namespace https://greasyfork.org/en/users/683695-lethalvision // @downloadURL none // ==/UserScript== // reference dictionaries in the format of : - item names *must* be exact // search tags are case insensitive, set tags to empty to indicate that the item should be skipped // only exceptions/special cases need to be defined here, the script automatically generates the acronyms otherwise const CHEESE = { "Bonefort Cheese":"BF","Checkmate Cheese":"CMC","Cloud Cheesecake":"CCC","Dragonvine Cheese":"DVC","Empowered SUPER|brie+":"ESB","First Draft Derby Cheese":"FDDC#1D", "Fusion Fondue":"M400#FF ","Second Draft Derby Cheese":"SDDC#2D ","Galleon Gouda":"GGC","Limelight Cheese":"LLC","Nian Gao'da Cheese":"NGD","Polter-Geitost":"PG", "SUPER|brie+":"SB","Wildfire Queso":"WF"} const CHARMS = { "Baitkeep Charm":"BKC","Festive Anchor Charm":"FAC#EAC","EMP400 Charm":"M400#EC","Timesplit Charm":"TSC","Dragonbane Charm":"DBC","Super Dragonbane Charm":"SDBC", "Extreme Dragonbane Charm":"EDBC","Ultimate Dragonbane Charm":"UDBC","Party Charm":"PaC","Super Party Charm":"SPaC","Extreme Party Charm":"EPaC", "Ultimate Party Charm":"UPaC","Rift Vacuum Charm":"RVC#Calcified Rift Mist#CRM","Rift Super Vacuum Charm":"RSVC#Calcified Rift Mist#CRM" } const CRAFTING = { "Chrome Celestial Dissonance Upgrade Kit":"CCDT","Chrome Circlet of Pursuing Upgrade Kit":"CCOP#CA2","Chrome MonstroBot Upgrade Kit":"CMBT", "Chrome Oasis Upgrade Kit":"COWNT#CPOT","Chrome School of Sharks Upgrade Kit":"CSOS","Chrome Sphynx Wrath Upgrade Kit":"CSW", "Chrome Storm Wrought Ballista Upgrade Kit":"CSWBT","Chrome Temporal Turbine Upgrade Kit":"CTT","Chrome Thought Obliterator Upgrade Kit":"CTOT#CTHOT#CF2", "Ful'Mina's Tooth":"Fulmina","Sandblasted Metal":"SBM","Stale SUPER brie+":"stale SB" } const SPECIAL = { "Ful'Mina's Gift":"fulmina","Ful'mina's Charged Toothlet":"fulmina","SUPER|brie+ Supply Pack":"SB","Timesplit Rune":"TSR","Sky Sprocket":"HAL#high altitude loot", "Skysoft Silk":"HAL#high altitude loot","Enchanted Wing":"HAL#high altitude loot","Cloudstone Bangle":"HAL#high altitude loot","Sky Glass":"glore","Sky Ore":"glore" } const WEAPON = { "Biomolecular Re-atomizer Trap":"BRAT#BRT","Birthday Party PiƱata Bonanza":"BPPB#Pinata","Blackstone Pass Trap":"BPT#BSP","Brain Extractor":"BE #Brain Bits", "Charming PrinceBot":"CPB","Christmas Crystalabra Trap":"CCT#Calcified Rift Mist#CRM","Chrome Circlet of Pursuing Trap":"CCOP#CA2","Chrome MonstroBot":"CMB", "Chrome RhinoBot":"CRB","Chrome Thought Obliterator Trap":"CTOT#CTHOT#CF2","Circlet of Pursuing Trap":"A2","Circlet of Seeking Trap":"A1","Enraged RhinoBot":"ERB", "Glacier Gatler":"GG#Charm","Ice Blaster":"IB#Charm","Icy RhinoBot":"IRB","Interdimensional Crossbow":"IDCT#ICT","Maniacal Brain Extractor":"MBE#Brain Bits", "Multi-Crystal Laser":"MCL","Mysteriously unYielding Null-Onyx Rampart of Cascading Amperes":"MYNORCA","RhinoBot":"RB ","Rift Glacier Gatler":"RGG#Charm", "S.A.M. F.E.D. DN-5":"SAMFED DN5#SAM FED DN5","S.L.A.C.":"SLAC","S.L.A.C. II":"SLAC2#SLAC 2","S.S. Scoundrel Sleigher Trap":"SSSST#S4T","S.T.I.N.G. Trap":"STING#L1", "S.T.I.N.G.E.R. Trap":"STINGER#L2","Sandstorm MonstroBot":"SMB","Sleeping Stone Trap":"SST#T1","Slumbering Boulder Trap":"SBT#T2","Snow Barrage":"SNOB", "Steam Laser Mk. I":"SLM1#SLMK1#SLMK 1#MARK 1","Steam Laser Mk. II":"SLM2#SLMK2#SLMK 2#MARK 2","Steam Laser Mk. II (Broken!)":"SLM2#SLMK2#SLMK 2#MARK 2", "Steam Laser Mk. III":"SLM3#SLMK3#SLMK 3#MARK 3","Surprise Party Trap":"SPT#Party Charm","Tarannosaurus Rex Trap":"TREX","The Forgotten Art of Dance":"TFAOD#FART#FAD", "The Haunted Manor Trap":"THMT#Charm","The Holiday Express Trap":"THET#Charm","Thought Manipulator Trap":"TMT#F1","Thought Obliterator Trap":"TOT#THOT#F2", "Timesplit Dissonance Trap":"TDT#TDW#TSD#TSW" } const BASE = { "10 Layer Birthday Cake Base":"Ten Layer#Charm","Clockwork Base":"CWB#CB ","Condemned Base":"CB #Charm","Cupcake Birthday Base":"CBB#Charm", "Extra Sweet Cupcake Birthday Base":"ESCBB#Charm","Rift Mist Diffuser Base":"RMDB#Charm","Skello-ton Base":"SB #Brain Bits", "Sprinkly Sweet Cupcake Birthday Base":"SSCBB#Charm","All Season Express Track Base":"ASETB#Charm" } // special merged list - potion outputs, needs both cheese and charms const POTION = Object.assign({}, CHEESE, CHARMS); // tag identifier - tags generated by this script have this identifier so that the script can remove it during rendering const TAG_ID = '#'; // piggyback on Mousehunt's jQuery // this is a smart thing to do that will never backfire on me var $ = $ || window.$; // one-time init functions go here function init() { initMp(); initTrap(); initInv(); initSupplyTransfer(); } // == Marketplace Search == function initMp() { // extend templateutil.render to inject desired search terms const _parentRender = hg.utils.TemplateUtil.render; hg.utils.TemplateUtil.render = function(templateType, templateData) { if (templateType == 'ViewMarketplace_search') { // only edit marketplace search templateData.search_terms.forEach(category => updateMpSearch(category)); } return _parentRender(templateType, templateData); } } function updateMpSearch(category) { var refDict = getDict(category.name); if (!refDict) { // invalid name return; } category.terms.forEach(function(listing) { var tag = getInitials(listing.value, refDict); if (tag && !listing.value.includes('hidden')) { // skip if the listing already has "hidden" tag added listing.value += ``; } }); } // == Trap Setup Search == function initTrap() { // hook into ajax calls to inject search tags into trap data // trap data is refreshed on trap change, hook into changetrap calls to reinject tags var callback = function(options, originalOptions, jqXHR) { const componentUrl = 'managers/ajax/users/gettrapcomponents.php'; const changeTrapUrl = 'managers/ajax/users/changetrap.php'; if (options.url.includes(componentUrl) || options.url.includes(changeTrapUrl)) { var _parentSuccess = options.success || originalOptions.success; var _parentAjax = options.ajax; var _extendedSuccess = function (data) { if (data.components && data.components.length > 0) { // components data.components.forEach(component => updateTrapSearch(component)); } else if (data.inventory) { // changetrap for (var item in data.inventory) { updateTrapSearch(data.inventory[item]); } } if (_parentAjax) { // changetrap // changetrap uses some unhinged wrapper for successhandler that doesn't resolve properly // so this calls the success function (ondone) directly return _parentAjax.ondone(data); } else if (typeof _parentSuccess === 'function') { // components return _parentSuccess(data); } }; options.success = originalOptions.success = _extendedSuccess; } } $.ajaxPrefilter(callback); // hook into renderFromFile to hide the injected search tags const _parentRenderFile = hg.utils.TemplateUtil.renderFromFile; hg.utils.TemplateUtil.renderFromFile = function(TemplateGroupSource,templateType,templateData) { if (TemplateGroupSource == 'TrapSelectorView' && templateType == 'tag_groups') { modifyTemplateData(templateData); // ugly timeout delay here because cleanup should only run after renderFromFile returns setTimeout(cleanTrapSelector, 5); } return _parentRenderFile(TemplateGroupSource,templateType,templateData); } } // inject search tags into trap data function updateTrapSearch(component) { var refDict = getDict(component.classification); if (!refDict) { // invalid name return; } var tag = getInitials(component.name, refDict); if (!tag) { return; // item not in refDict and getInitials fails to generate an acronym for it } tag += TAG_ID; // Tag the trap component with its acronym if (!component.tag_types) { component.tag_types = []; } // count number of non-hidden tags var count = component.tag_types.length; const hiddenTagList = ['draconic', 'tactical', 'shadow', 'physical', 'rift', 'hydro', 'arcane', 'forgotten', 'law', 'charm_weak', 'charm_strong', 'charm_epic', 'charm_rare', 'trap_parts', 'bait_standard', 'event']; for (var i=0; i