User:Umiven/UmivenVault.xml
From Discworld MUD Wiki
Check for new versions at: Vault Tracker
To use, copy the text in the box below inside a file named UmivenVault.xml in your MUSHclient/quow_plugins/ directory. You need to save the file using a simple text editor like Notepad++, nano, kate, gedit, etc., but not a words processor like word, write or libreoffice.
<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE muclient> <!-- Vault Tracker created by Umiven --> <muclient> <plugin name="UmivenVault" author="Umiven" id="556d6976656e000000000002" language="Lua" purpose="Vault Tracker" date_written="2022-05-27" date_modified="2023-05-01" save_state="y" requires="5.06" version="1.09" > <description trim="y"> <![CDATA[ ******************************************************************** ***** Vault Tracker ***** ***** For Discworld ***** ***** ***** ***** !! REQUIRES COWBAR (https://quow.co.uk/minimap.php) !! ***** ***** ***** ***** Keeps track of the all items in your vaults. To use ***** ***** this plugin, go to each vault and look at the items in ***** ***** each vault. The items will then be stored per vault. ***** ***** 'vault' or 'vaults' returns a list of vaults, along ***** ***** with options to see its contents (if it has any) and a ***** ***** button to speedwalk to it. ***** ***** 'vault <item>' or 'vaults <item>' will return a list of ***** ***** vaults that contain the specified item. ***** ***** 'vaultall' or 'vaultsall' will return a combined list ***** ***** of every item and the amount of it you have across all ***** ***** vaults. ***** ***** ***** ***** 'vaultusers' will show you all recorder character and ***** ***** allow you to switch between them, copy and paste the ***** ***** vault contents between characters, and delete ***** ***** characters. ***** ***** 'vaultuser <username>' will add a new character whose ***** ***** vault can be recorded. ***** ***** Note: you needd to look at the contents of at least one ***** ***** vault before the new character and its information will ***** ***** be saved. ***** ******************************************************************** ]]> </description> </plugin> <script> <![CDATA[ require "json" --#region global variables local configColour = { ["error"] = "red", ["blue"] = "#478be9", ["red"] = "#e978a6", ["green"] = "#92c402", ["cyan"] = "#90e4e0", ["yellow"] = "#fed093", } local colourArmount = configColour["yellow"] local colourCityName = configColour["red"] local colourCurrentUser = configColour["cyan"] local colourFullStart = configColour["cyan"] local colourFullEnd = configColour["red"] local colourHyperlink = configColour["yellow"] local colourItem = configColour["cyan"] local colourUser = configColour["red"] local colourVaultName = configColour["green"] local colourVaultCost = configColour["blue"] --#endregion --#region database local vaultsInfo = { ["Nella's vault"] = { order = 1, city = "Ankh-Morpork", location = "Barbican Plaza", cost = "30p", container = "large wooden drawer", containerDescription = "This is a large drawer made of dark brown wood. It has a rectangular frame. The wood looks old and used, but the handles that operate the drawer's double doors are polished - or well used." }, ["opulent office"] = { order = 2, city = "Ankh-Morpork", location = "The Ridings", cost = "30p", container = "cubby hole", containerDescription = "The cubby hole is just a cube of empty space in the stone of the wall behind one of the doors." }, ["small garden"] = { order = 3, city = "Bes Pelargic", location = "Way of the Dragon", cost = "50s", container = "clean nest", containerDescription = "The nests appear to be deep enough to store things in." }, ["Thella's vault"] = { order = 4, city = "Djelibeybi", location = "Scarab Walk", cost = "DjToon 0.50", container = "drawer", containerDescription = "The single open drawer is sticking straight out of the wall like... well, like a drawer sticking straight out of the wall. It is in excellent condition." }, ["cool, dry basement"] = { order = 5, city = "Ephebe", location = "Logical Lane", cost = "50de", container = "octiron tesseract", containerDescription = "This floating, four-dimensional cuboid appears to have been fixed in place in the very centre of the room. It would be able to keep a large number of objects safe for their owner, although exactly where they are stored is uncertain. Maybe that's the point." }, ["safety deposit waiting room"] = { order = 6, city = "Genua", location = "Royal Avenue", cost = "66Gc", container = "steel locker", containerDescription = "A steel-lined hollow in the stone wall, with a sturdy door." }, ["office in Ohulan-Cutash"] = { order = 7, city = "Ohulan Cutash", location = "Dock Street", cost = "Lp 10", container = "cubby hole", containerDescription = "The cubby hole is just a cube of empty space in the stone of the wall behind one of the doors." }, } local vaultFullStates = { ["contains"] = { percentage = "5", hexColour = "#00FFFF", }, ["almost empty except for"] = { percentage = "10", hexColour = "#00bfff", }, ["about one-quarter full with"] = { percentage = "25", hexColour = "#007fff", }, ["about half full with"] = { percentage = "50", hexColour = "#0040ff", }, ["about three-quarters full with"] = { percentage = "75", hexColour = "#0000ff", }, ["almost full with"] = { percentage = "90", hexColour = "#4000ff", }, ["almost completely full with"] = { percentage = "95", hexColour = "#7f00ff", }, ["completely full with"] = { percentage = "100", hexColour = "#bf00ff", }, ["over-full with"] = { percentage = "110", hexColour = "#ff00ff", }, } local itemsEndingInES = { "breezes", "daisies", "dentures", "edges", "eyes", "leaves", "mcnoodles", "noodles", "misshapes", "nightshades", "peonies", "rushes", "sauternes", "spangles", "speckles", "squares", "supplies", } local itemsEndingInS = { "abacus", "accents", "adventurers", "aegis", "albatross", "almonds", "ambergris", "arms", "atlas", "aulos", "balloons", "balls", "bass", "beads", "beans", "bears", "beets", "beginners", "bells", "bits", "blocks", "bolognas", "bolts", "breasts", "burnous", "buttons", "cactus", "candyfloss", "cards", "carrots", "cereus", "chains", "chestnuts", "chews", "chickpeas", "chips", "chlamys", "cigars", "clams", "claws", "clematis", "cocktails", "compass", "couscous", "crackers", "crayons", "crisps", "cross", "croutons", "cuirass", "cupboards", "cushions", "cutlass", "cypress", "daffodils", "drawers", "dress", "droppings", "ducks", "dumplings", "earflaps", "ears", "eggs", "entrails", "escargots", "exomis", "famous", "feathers", "fields", "filings", "fingers", "flanchards", "floris", "floss", "flowers", "forests", "fours", "freesias", "fruits", "gibus", "gladiolus", "gladius", "glass", "goddess", "grass", "guinness", "haggis", "haikus", "handcuffs", "hands", "harness", "headdress", "hourglass", "iris", "jewels", "kalasiris", "kopis", "labels", "legs", "lens", "lentils", "lights", "liqueurs", "llamedos", "lotus", "lumps", "madness", "mantis", "mass", "mess", "minidress", "moons", "moss", "mushrooms", "mussels", "nails", "neckirons", "nightdress", "nuts", "oats", "obolus", "octopus", "orchids", "overalls", "oysters", "pants", "papers", "papyrus", "pass", "peanuts", "pecans", "peplos", "petticoats", "plains", "poems", "quilters", "rags", "ramtops", "ravens", "realms", "ribbons", "ribs", "rinds", "rocks", "roots", "sagaris", "sarcophagus", "schnapps", "scraps", "scratchings", "sequins", "sheets", "shells", "shepherdess", "shoots", "shotglass", "shreddings", "spirits", "starflowers", "sticks", "streamers", "stylus", "sundress", "sunflowers", "swampgas", "tacticus", "tails", "tears", "tickets", "tongs", "tools", "twigs", "underdress", "veils", "violets", "waders", "walnuts", "washers", "weeds", "whelks", "whiskers", "wings", "worms", "wristlets", "xiphos", } local itemsEndingInE = { "abalone", "absinthe", "adhesive", "akome", "ale", "ankhstone", "apple", "applique", "armoire", "artichoke", "attire", "aubergine", "axe", "axle", "badge", "bagpipe", "balance", "bangle", "bathrobe", "bauble", "beagle", "beanie", "beetle", "bite", "blade", "bloodstone", "blouse", "blowpipe", "blue", "bodice", "bolognese", "bone", "bookcase", "bootlace", "borage", "bottle", "bouteille", "boutonniere", "brassiere", "breastplate", "breeze", "brie", "briefcase", "brochure", "brulee", "bubble", "buckle", "buttonhole", "cabbage", "cage", "cake", "camisole", "candle", "cane", "cape", "capsule", "carapace", "case", "castle", "catalogue", "cervilliere", "champagne", "cheese", "cheesecake", "cheesewire", "chime", "chocolate", "choice", "cigarette", "claymore", "cobble", "cockle", "coffee", "colichemarde", "collie", "cone", "cookie", "cookstove", "corniche", "corpse", "corsage", "costume", "crane", "crate", "crepe", "crinoline", "crocodile", "crumble", "cube", "cupcake", "cure", "custome", "date", "device", "dice", "die", "drawknife", "drynke", "duckie", "dune", "dye", "engine", "ensemble", "envelope", "epee", "ephebe", "escritoire", "eztope", "face", "femme", "figure", "figurine", "file", "finale", "fire", "fireplace", "fleece", "flute", "folle", "foxglove", "frame", "frankincense", "frisbee", "frittole", "fromage", "fudge", "fumee", "fuse", "game", "garbage", "gargoyle", "gauche", "girdle", "glaive", "globe", "glove", "glue", "gnameplate", "gnome", "goose", "gote", "grape", "grenouille", "guide", "handle", "headpiece", "hellebore", "hinge", "hive", "hoe", "horse", "horseshoe", "hose", "impie", "incense", "indulgence", "ire", "jasmine", "juice", "kamikaze", "kelpie", "kettle", "kite", "knife", "kosode", "kote", "kourambiethe", "lace", "ladle", "landscape", "lasagne", "lecture", "lemonade", "lettuce", "licence", "lime", "line", "lingerie", "linzerauge", "longue", "lozenge", "luggage", "lure", "lute", "lyre", "mace", "machine", "magazine", "mantelpiece", "maple", "marble", "marionette", "mcrice", "me", "measure", "megaphone", "meringue", "milkshake", "mistletoe", "mitre", "mixture", "mole", "monocle", "moonshine", "moose", "mouse", "mousse", "moustache", "mussie", "muzzle", "necklace", "nectarine", "needle", "negligee", "newbie", "nightie", "nose", "note", "numberplate", "office", "oilstone", "oinochoe", "olive", "olpe", "orange", "ore", "package", "palette", "pancake", "panpipe", "pebble", "penible", "perfume", "periwinkle", "pestle", "philtre", "pickaxe", "pickle", "picture", "pie", "piece", "pinafore", "pine", "pineapple", "pipe", "pipette", "pishe", "plaque", "plate", "ploughshare", "plume", "pole", "pomegranate", "pomperiposse", "poodle", "porridge", "porthole", "praline", "preserve", "protective", "purse", "rake", "range", "ratatouille", "reticule", "rice", "ricecake", "robe", "rope", "rose", "rosette", "royale", "sabre", "saddle", "safe", "sage", "sake", "sandstone", "sandwhitche", "sauce", "sausage", "saxophone", "scale", "scene", "sceptre", "sconce", "scone", "sculpture", "scumble", "scuttle", "scythe", "seahorse", "settee", "shake", "shingle", "shortcake", "sickle", "sidetable", "significance", "slate", "slice", "slide", "sludge", "slumpie", "snake", "snausage", "snowflake", "snowflare", "snowglobe", "sode", "solitaire", "sphere", "spike", "sponge", "square", "stake", "statue", "statuette", "stile", "stole", "stone", "stove", "suitcase", "sundae", "suneate", "sunrise", "sunshine", "surplice", "surprise", "swede", "swine", "switchblade", "sycamore", "table", "tambourine", "tangerine", "tape", "tease", "tee", "tempscire", "tentacle", "terre", "thimble", "thingie", "thobe", "thyme", "tickle", "tie", "tile", "timepiece", "tipple", "tissue", "toffee", "toie", "toothpaste", "tortoise", "toupee", "tree", "triangle", "trireme", "trombone", "truffle", "tube", "turpentine", "turtle", "ukulele", "vampire", "vase", "ve", "verge", "waffle", "wallpiece", "wardrobe", "wedge", "whale", "whalebone", "wheelhouse", "whine", "whipple", "whistle", "white", "wildride", "wine", "winkle", "wire", "withe", "wizzie", "womble", "wossname", } local itemsWithComma = { "battered, black tricorn", "Bes Pelargic Blue tobacco, special import", "Buffalo tobacco, the people's choice", "cigar baklava, perfect for a late night sugar crash", "delicious kebab, fast and cheap", "Grims tobacco, for the hardened smoker", "hard, pink mass", "large, wide-brimmed black hat", "long, sharp hatpin", "Long, Slow Fish Against A Wall", "long, thin needle", "old, worn-out broomstick", "open, empty briefcase", "pair of filmy, clinging, billowing harem trousers", "pair of sheer, red silk stockings", "paper cup of stewed, cold tea", "plain, grey suit jacket", "Quirm Red, last year's", "Quirm Red, this year's", "small, salt-encrusted peanut", "sparkling, bejewelled anklet", "Two-Hump tobacco, that special taste of Klatch", } local numberWords = { ["zero"] = 0, ["half"] = 0.5, ["one"] = 1, ["two"] = 2, ["three"] = 3, ["four"] = 4, ["five"] = 5, ["six"] = 6, ["seven"] = 7, ["eight"] = 8, ["nine"] = 9, ["ten"] = 10, ["eleven"] = 11, ["twelve"] = 12, ["thirteen"] = 13, ["fourteen"] = 14, ["fifteen"] = 15, ["sixteen"] = 16, ["seventeen"] = 17, ["eighteen"] = 18, ["nineteen"] = 19, ["twenty"] = 20, ["twenty-one"] = 21, ["twenty-two"] = 22, ["twenty-three"] = 23, ["twenty-four"] = 24, ["twenty-five"] = 25, ["twenty-six"] = 26, ["twenty-seven"] = 27, ["twenty-eight"] = 28, ["twenty-nine"] = 29, ["thirty"] = 30, ["thirty-one"] = 31, ["thirty-two"] = 32, ["thirty-three"] = 33, ["thirty-four"] = 34, ["thirty-five"] = 35, ["thirty-six"] = 36, ["thirty-seven"] = 37, ["thirty-eight"] = 38, ["thirty-nine"] = 39, ["forty"] = 40, ["forty-one"] = 41, ["forty-two"] = 42, ["forty-three"] = 43, ["forty-four"] = 44, ["forty-five"] = 45, ["forty-six"] = 46, ["forty-seven"] = 47, ["forty-eight"] = 48, ["forty-nine"] = 49, ["fifty"] = 50, ["fifty-one"] = 51, ["fifty-two"] = 52, ["fifty-three"] = 53, ["fifty-four"] = 54, ["fifty-five"] = 55, ["fifty-six"] = 56, ["fifty-seven"] = 57, ["fifty-eight"] = 58, ["fifty-nine"] = 59, ["sixty"] = 60, ["sixty-one"] = 61, ["sixty-two"] = 62, ["sixty-three"] = 63, ["sixty-four"] = 64, ["sixty-five"] = 65, ["sixty-six"] = 66, ["sixty-seven"] = 67, ["sixty-eight"] = 68, ["sixty-nine"] = 69, ["seventy"] = 70, ["seventy-one"] = 71, ["seventy-two"] = 72, ["seventy-three"] = 73, ["seventy-four"] = 74, ["seventy-five"] = 75, ["seventy-six"] = 76, ["seventy-seven"] = 77, ["seventy-eight"] = 78, ["seventy-nine"] = 79, ["eighty"] = 80, ["eighty-one"] = 81, ["eighty-two"] = 82, ["eighty-three"] = 83, ["eighty-four"] = 84, ["eighty-five"] = 85, ["eighty-six"] = 86, ["eighty-seven"] = 87, ["eighty-eight"] = 88, ["eighty-nine"] = 89, ["ninety"] = 90, ["ninety-one"] = 91, ["ninety-two"] = 92, ["ninety-three"] = 93, ["ninety-four"] = 94, ["ninety-five"] = 95, ["ninety-six"] = 96, ["ninety-seven"] = 97, ["ninety-eight"] = 98, ["ninety-nine"] = 99, ["one hundred"] = 100, ["two hundred"] = 200, ["three hundred"] = 300, ["four hundred"] = 400, ["five hundred"] = 500, ["six hundred"] = 600, ["seven hundred"] = 700, ["eight hundred"] = 800, ["nine hundred"] = 900, ["one thousand"] = 1000, ["two thousand"] = 2000, ["three thousand"] = 3000, ["four thousand"] = 4000, ["five thousand"] = 5000, ["six thousand"] = 6000, ["seven thousand"] = 7000, ["eight thousand"] = 8000, ["nine thousand"] = 9000, ["many"] = 20, } --#endregion --#region general functions function DecToHex(decimal) if type(decimal) == "number" then return string.format("%x", decimal) end return "0" end function HexToDec(hex) return tonumber(hex, 16) end function HexToRGB(hex) if IsHexColor(hex) then hex = string.gsub(hex, "%#", "") local r = tonumber(string.sub(hex, 1, 2), 16) local g = tonumber(string.sub(hex, 3, 4), 16) local b = tonumber(string.sub(hex, 5, 6), 16) return {r = r, g = g, b = b} end return {r = 255, g = 255, b = 255} end function IsHexColor(str) return string.match(str, "^#?[%da-fA-F][%da-fA-F][%da-fA-F][%da-fA-F][%da-fA-F][%da-fA-F]$") ~= nil end function Round(num) local decimal = num - math.floor(num) if decimal >= 0.5 then return math.ceil(num) else return math.floor(num) end end function string.addLeadingTrailing(str, max, fill, trailing) if type(str) ~= "string" or type(max) ~= "number" or type(fill) ~= "string" then Note("One of the entered variables is of the incorrect type") else local amountToAdd = max - #str if trailing then return str .. string.rep(fill, amountToAdd) else return string.rep(fill, amountToAdd) .. str end end end function string.isEmpty(s) local success, msg = pcall(function() assert(type(s) == "string") end) if not success then Note(msg) end return s == nil or #s == 0 end function string.replaceLast(originalString, matchString, replaceString) if type(originalString) == "string" and type(matchString) == "string" and type(replaceString) then local searchString = string.reverse(matchString) local stringReversed = string.reverse(originalString) local stringIndex = string.find(stringReversed, searchString) local editedReveresString = string.sub(stringReversed, 0, stringIndex) .. replaceString .. string.sub(stringReversed, stringIndex + string.len(searchString)) return string.reverse(editedReveresString) else ColourNote(configColour["error"], "", "string.replaceLast error: one or more of the inputs were not of type string.") return originalString end end function string.toTable(s, delimiter) local result = {} if type(s) == "string" and type(delimiter) == "string" then for match in (s..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match) end else ColourNote(configColour["error"], "", "string.toTable error: one or more of the inputs were not of type string.") end return result end function string.trim(s) if type(s) == "string" then return string.gsub(s, "^%s*(.-)%s*$", "%1") else ColourNote(configColour["error"], "", "string.trim error: input was not of type string.") end return s end function table.contains(t, match) for i = 1, #t, 1 do if t[i] == match then return true end end return false end function table.filter(table,prop,val) local returnTable = {} for key, value in pairs(table) do if string.lower(value[prop]) == string.lower(val) then returnTable[key] = value end end return returnTable end function table.isEmpty(t) if type(t) == "table" then if not next(t) then return true end end return false end function table.keyToIndexTable(t) local result if type(t) == "table" then result = {} for k, v in pairs(t) do local insertTable = {} insertTable["key"] = k if type(v) == "table" then for key, value in pairs(v) do insertTable[key] = value end end table.insert(result, insertTable) end elseif type(t) == "string" then result = t end return result end function table.length(t) local total = 0 for x in pairs(t) do total = total + 1 end return total end function table.print(t, a) if type(t) == "table" then local indentAmount = a or 0 for k,v in pairs(t) do local vType = type(v) for i = 1, indentAmount, 1 do Tell(" ") end if vType == "table" then Note(k) table.print(v, indentAmount + 1) else ColourTell("#0080FF", "", k .. ": ") ColourTell("#7DE800", "", v) Note("") end end else ColourNote(configColour["error"], "", "table.print error: input is not of type table.") end end function table.valueList(t, val) local returnTable = {} if string.lower(val) == "key" then for k, v in pairs(t) do table.insert(returnTable, k) end else for k, v in pairs(t) do table.insert(returnTable, v[val]) end end return returnTable end function table.valueMaxStringLength(t) local maxStringLength = 0 for key, value in pairs(t) do if string.len(value) > maxStringLength then maxStringLength = string.len(value) end end return maxStringLength end --#endregion --#region global functions function VaultCheckCompanionPluginsEnabled() local bankPluginEnabled = GetPluginInfo("556d6976656e000000000001", 17) return bankPluginEnabled end --#endregion --#region plugin functions function OnPluginListChanged() VaultClearBadVariables() end function OnPluginConnect() VaultClearBadVariables() end function OnPluginInstall() VaultClearBadVariables() end function OnPluginEnable() VaultClearBadVariables() end --#endregion --#region vault functions function VaultConvertItemNamePluralToSingle(s) if type(s) == "string" and s ~= "" then local result = s or "" result = result:gsub("pairs of", "pair of") result = result:gsub("chunks", "chunk") result = result:gsub("sides", "side") result = result:gsub("knives", "knife") result = result:gsub("pirates'", "pirate's") if not string.find(result, "pair of") then local lastWord = result if string.find(result, " ") then local fooTable = string.toTable(result, " ") lastWord = fooTable[#fooTable] end local isSingularWord = false local singularWordEndsInE = false local removeES = false local removeS = false -- plural word (ending in s or es) is actually a singular word if (string.sub(lastWord, string.len(lastWord)-1) == "es") and (isSingularWord == false) then for i = 1, #itemsEndingInES, 1 do if itemsEndingInES[i] == lastWord then isSingularWord = true i = #itemsEndingInES end end end if (string.sub(lastWord, string.len(lastWord)) == "s") and (isSingularWord == false) then for i = 1, #itemsEndingInS, 1 do if itemsEndingInS[i] == lastWord then isSingularWord = true i = #itemsEndingInS end end end -- Is singular word ending with e? if (string.sub(lastWord, string.len(lastWord)-1) == "es") and (isSingularWord == false) then local lastWordEndingInE = string.sub(lastWord, 0, string.len(lastWord)-1) for i = 1, #itemsEndingInE, 1 do if itemsEndingInE[i] == lastWordEndingInE then singularWordEndsInE = true i = #itemsEndingInE end end end if (string.sub(lastWord, string.len(lastWord)-1) == "es") and (isSingularWord == false) and (singularWordEndsInE == false) then removeES = true end if (string.sub(lastWord, string.len(lastWord)) == "s") and (isSingularWord == false) and (singularWordEndsInE == false) and (removeES == false) then removeS = true end if isSingularWord then result = result elseif singularWordEndsInE then result = string.sub(result, 0, string.len(result)-1) elseif removeES then result = string.sub(result, 0, string.len(result)-2) elseif removeS then result = string.sub(result, 0, string.len(result)-1) end end --ColourNote("yellow", "", "VaultContenItemNamePluralToSingle end") return result end --ColourNote("yellow", "", "VaultContenItemNamePluralToSingle end") return s end function VaultConvertContentStringToArray(s) if type(s) == "string" and s ~= "" then s = ", " .. s if string.match(s, " and ") then s = string.replaceLast(s, " and ", ", ") end -- Find unique Items with capital letters and quantify them while s.find(s, ", %u") do local matchIndex = string.find(s, ", %u") s = string.sub(s, 1, matchIndex) .. " a" .. string.sub(s, matchIndex+1, string.len(s)) end -- quantify non-numeric quantifiers s = string.gsub(s, ", some ", ";, 1*") s = string.gsub(s, ", the ", ";, 1*") s = string.gsub(s, ", an ", ";, 1*") s = string.gsub(s, ", a ", ";, 1*") s = string.gsub(s, ", many ", ";, 20*") -- prepare string to be split for key, value in pairs(numberWords) do s = string.gsub(s, ", " .. key .. " ", ";, " .. value .. "*") end -- unprepare items with a comma for _, value in ipairs(itemsWithComma) do local seatchString = string.gsub(value, ", ", ";, ") s = string.gsub(s, seatchString, value) end s = string.gsub(s, "^;, ", "", 1) local contentTable = string.toTable(s, ";,") local contentArray = {} for i = 1, #contentTable, 1 do contentTable[i] = string.trim(contentTable[i]) local fooTable = string.toTable(contentTable[i],"*") local singleItem = VaultConvertItemNamePluralToSingle(fooTable[2]) contentArray[singleItem] = fooTable[1] end return contentArray else ColourNote(configColour["error"], "", "VaultConvertContentStringToArray error: input was not of type string") return {} end end function VaultCaptureLastContentString() local currentVaultNameString = VaultGetCurrentVault() local vaultContentsArray = VaultGetCurrentUserVaultContents() local vaultInfo = vaultsInfo[currentVaultNameString] local recentLinesTable = string.toTable(GetRecentLines(100), "\n") local vaultFullStateString = "" local vaultContentsString = "" local matchIndex = -1 for i = 1, #recentLinesTable do if string.find(recentLinesTable[i], vaultInfo.container) then matchIndex = i end end if matchIndex > -1 then vaultFullStateString = "" vaultContentsString = "" for index = 0, 5, 1 do local nextLine = recentLinesTable[matchIndex+index] if type(nextLine) == "string" then if string.find(nextLine, vaultInfo.container) then -- The steel locker is about half full with eight pieces of white ambergris, an aerodynamic silver broomstick, five Creator Collector Cards, a darkened trident, Klang, a Heliodeliphilodelphiboschrome candle, a silver bamboo hairpin, an oiled leather thigh holster, Red Scare, Royal Wart, Outer Innie, Bite Marker, two green obbles, three small sticks, Painbox, a twisted vine ring, a flat cap, Sportscarf, a pair of tongs, a set of fire tongs, a Grflx scale, a lamp, a white mineral rock, some white mineral powder, a small canteen, a Klein bottle, a blue funnel and Man Reaper. -- The steel locker contains eight pieces of white ambergris, an aerodynamic silver broomstick, five Creator Collector Cards, a darkened trident, Klang, a Heliodeliphilodelphiboschrome candle, a silver bamboo hairpin, an oiled leather thigh holster, Red Scare, Royal Wart, Outer Innie, Bite Marker, two green obbles, three small sticks, Painbox, a twisted vine ring, a flat cap, Sportscarf, a pair of tongs, a set of fire tongs, a Grflx scale, a lamp, a white mineral rock, some white mineral powder, a small canteen, a Klein bottle, a blue funnel and Man Reaper. nextLine = string.gsub(nextLine, "%.$", "", 1) for key, value in pairs(vaultsInfo) do nextLine = string.gsub(nextLine, "^The " .. value.container .. " ", "", 1) nextLine = string.gsub(nextLine, "^is ", "", 1) end for key, value in pairs(vaultFullStates) do local matchString = string.gsub(key, "%-", "%%-") nextLine = string.gsub(nextLine, matchString .. " ", key .. ";;;", 1) end if string.find(nextLine, ";;;") then local fooTable = string.toTable(nextLine, ";;;") vaultFullStateString = string.trim(fooTable[1]) vaultContentsString = string.trim(fooTable[2]) break end end end end end -- Set vault contents and vault full if type(vaultContentsString) == "string" and vaultContentsString ~= "" then vaultContentsArray[currentVaultNameString].contents = VaultConvertContentStringToArray(vaultContentsString) else vaultContentsArray[currentVaultNameString].contents = {} end if type(vaultFullStateString) == "string" and vaultFullStateString ~= "" then vaultContentsArray[currentVaultNameString].full = vaultFullStateString else vaultContentsArray[currentVaultNameString].full = "" end VaultSetCurrentUserVaultContents(vaultContentsArray) end function VaultCheckVaultArrayStructure(t) -- check if table is not nil and has at least one user key if t == nil or next(t) == nil then return false end -- iterate through user keys for _, userValue in pairs(t) do -- check if userValue is a table if type(userValue) ~= "table" then return false end -- iterate through vault keys for _, vaultValue in pairs(userValue) do -- check if vaultValue is a table if type(vaultValue) ~= "table" then return false end -- check if vaultValue has keys "full" and "contents" if vaultValue["full"] == nil or vaultValue["contents"] == nil then return false end -- check if "contents" is a table if type(vaultValue["contents"]) ~= "table" then return false end end end -- if all checks passed, return true return true end function VaultClearBadVariables() if not VaultCheckVaultArrayStructure(VaultGetVaultContents()) then DeleteVariable("vaultContents") ColourNote(configColour["error"], "", "The structure of the vaultContents variable was incorrect and has been deleted. Please visit vaults again to store their contents in the vaultContents variable.") end end function VaultGetHexColourByFill(fill) -- convert string key table into index table local vaultFullStatesIndex = table.keyToIndexTable(vaultFullStates) table.sort(vaultFullStatesIndex, function (k1,k2) return tonumber(k1.percentage) < tonumber(k2.percentage) end) local lookIndex = 0 for index, value in ipairs(vaultFullStatesIndex) do if value["key"] == fill then lookIndex = index break end end local rgbHex if lookIndex > 0 then local rgbStart = HexToRGB(colourFullStart) local rgbEnd = HexToRGB(colourFullEnd) local rgb = {r = 0, g = 0, b = 0} for key, _ in pairs(rgbStart) do local perStage = (rgbEnd[key] - rgbStart[key]) / #vaultFullStatesIndex rgb[key] = rgbStart[key] + Round(lookIndex * perStage) end rgbHex = "#" .. DecToHex(rgb["r"]) .. DecToHex(rgb["g"]) .. DecToHex(rgb["b"]) else rgbHex = "#ffffff" end return rgbHex end function VaultShowUsers() ColourNote(colourVaultName, "", "Vault users:") for _, value in pairs(VaultGetKnownUsers()) do if value == VaultGetCopyUser() then NoteStyle(4) end if value == VaultGetUser() then ColourTell(colourCurrentUser, "", value) else ColourTell(colourUser, "", value) end NoteStyle(0) Tell(" ") Tell("[") if value == VaultGetUser() then ColourTell(colourArmount, "", "Change") else Tell(Hyperlink("VaultUser " .. value, "Change", "Change to vault data of " .. value, colourHyperlink, "black", 0)) end Tell(" | ") Tell(Hyperlink("VaultDeleteUser " .. value, "Delete", "Delete vault data of " .. value, colourHyperlink, "black", 0)) Tell(" | ") Tell(Hyperlink("VaultCopy " .. value, "Copy", "Copy vault data of " .. value, colourHyperlink, "black", 0)) if value == VaultGetCopyUser() or string.isEmpty(VaultGetCopyUser()) then else Tell(" | ") Tell(Hyperlink("VaultPaste " .. value, "Paste", "Paste vault data to " .. value, colourHyperlink, "black", 0)) end Tell("]") Note() end end --#region trigger function VaultTriggerContents(name, output, wildcards) local vaultContentsString = wildcards[5] local currentVaultString = VaultGetCurrentVault() if type(currentVaultString) == "string" and currentVaultString ~= "" then local vaultContentsArray = VaultGetCurrentUserVaultContents() local vaultFullStateString = string.trim(wildcards[3]) local contentsArray = VaultConvertContentStringToArray(vaultContentsString) vaultContentsArray[currentVaultString].contents = contentsArray vaultContentsArray[currentVaultString].full = vaultFullStateString VaultSetCurrentUserVaultContents(vaultContentsArray) else ColourNote(configColour["error"], "", "VaultTriggerContents error: currentVaultString is either not of type string or is empty") ColourNote("blue", "", "currentVaultString: " .. currentVaultString) end end function VaultTriggerSetInsideVault(name, output, wildcards) local locationName = wildcards[1] if locationName == "vault" or locationName == "inside the vault" or locationName == "inside the shed" or locationName == "octiron-lined strongroom" then VaultSetInVaultWaitingRoom(false) VaultSetInVault(true) EnableTrigger("lblVaultTriggerSetInsideVault", false) elseif locationName == "Nella's vault" or locationName == "cool, dry basement" or locationName == "safety deposit waiting room" or locationName == "Thella's vault" or locationName == "small garden" or locationName == "opulent office" or locationName == "office in Ohulan-Cutash" then VaultSetInVaultWaitingRoom(true) VaultSetInVault(false) EnableTrigger("lblVaultTriggerSetInsideVault", true) else EnableTrigger("lblVaultTriggerSetInsideVault", false) VaultSetInVaultWaitingRoom(false) VaultSetInVault(false) VaultSetCurrentVault("") end end function VaultTriggerSetCurrentVault(name, output, wildcards) local currentVault = wildcards[1] if type(currentVault) == "string" and currentVault ~= "" then VaultSetCurrentVault(currentVault) EnableTrigger("lblVaultTriggerSetInsideVault", true) if VaultGetInVault() then VaultCaptureLastContentString() VaultSetInVault(false) end VaultSetInVaultWaitingRoom(true) else ColourNote(configColour["error"], "", "VaultTriggerSetCurrentVault error: match is not of type string or is empty") end end --#endregion --#region alias function VaultAliasChangeUser(name, output, wildcards) local bankPluginId = "556d6976656e000000000001" if VaultCheckCompanionPluginsEnabled() then local errorCode, bankKnownUsersJson = CallPlugin(bankPluginId, "BankGetKnownUsers", "json") local bankKnownUsersTable = json.decode(bankKnownUsersJson) local vaultKnownUsersTable = VaultGetKnownUsers() table.sort(vaultKnownUsersTable, function (k1,k2) return string.lower(k1) < string.lower(k2) end) for _, value in ipairs(vaultKnownUsersTable) do if table.contains(bankKnownUsersTable, value) then ColourTell(colourVaultName, "", value) Tell(" ") Tell("[") Tell(Hyperlink("changeuser " .. value, "Change", "Change to bank and vault data to " .. value, colourArmount, "black", 0)) Tell("]") Note() end end end end function VaultAliasVaultCheckAll(name, output, wildcards) VaultPrintConsolidatedVaultContents() end function VaultAliasVaultCheckAllVaults(name, output, wildcards) VaultPrintAllVaults() end function VaultAliasVaultCheckAnyHasItem(name, output, wildcards) local item = wildcards[1] VaultPrintAnyHasItem(item) end function VaultAliasVaultContent(name, output, wildcards) local vaultName = wildcards[1] for vaultInfoKey, vaultInfoValue in pairs(vaultsInfo) do if vaultInfoKey == vaultName then VaultPrintVaultContents(vaultInfoKey) return end end ColourNote(configColour["error"], "", "VaultAliasVaultContent error: Input vault name is unknown") end function VaultAliasVaultCopy(name, output, wildcards) local fromUser = wildcards[1] VaultSetCopyUser(fromUser) Tell("Copied the vaults from ") if (VaultGetUser() == string.lower(fromUser)) then ColourTell(colourCurrentUser, "", fromUser) else ColourTell(colourCityName, "", fromUser) end Tell(".") Note() VaultShowUsers() end function VaultAliasVaultDeleteUser(name, output, wildcards) local user = string.lower(wildcards[1]) local currentUser = VaultGetUser() VaultDeleteUser(user) Tell("Deleted vault data for ") ColourTell(colourUser, "", user) Tell(".") if currentUser == user then SetVariable("vaultUser", "default") Tell(" Reverted back to ") ColourTell(colourCurrentUser, "", "default") Tell(" user.") end Note() end function VaultAliasVaultPaste(name, output, wildcards) local toUser = string.lower(wildcards[1]) local fromUser = VaultGetCopyUser() VaultCopyContentsToUser(toUser, fromUser) Tell("Placed vault data from ") if (VaultGetUser() == string.lower(fromUser)) then ColourTell(colourCurrentUser, "", fromUser) else ColourTell(colourCityName, "", fromUser) end Tell(" into ") if (VaultGetUser() == string.lower(toUser)) then ColourTell(colourCurrentUser, "", toUser) else ColourTell(colourCityName, "", toUser) end Tell(".") Note() end function VaultAliasVaultShowUsers(name, output, wildcards) VaultShowUsers() end function VaultAliasVaultSetUser(name, output, wildcards) local user = string.lower(wildcards[1]) VaultSetCurrentUser(user) Tell("Changed to the vault data of ") ColourTell(colourCurrentUser, "", user) Tell(".") Note() end --#endregion --#region variable functions --#region delete function VaultDeleteUser(user) user = string.lower(user) local vaultArray = VaultGetVaultContents() if vaultArray[user] then vaultArray[user] = nil VaultSetVaultContents(vaultArray) end end --#endregion --#region get function VaultGetAllVaultContentItemsArray() local vaultContentsArray = VaultGetCurrentUserVaultContents() local returnArray = {} for _, vaultValue in pairs(vaultContentsArray) do for contentKey, contentValue in pairs(vaultValue.contents) do if returnArray[contentKey] then returnArray[contentKey] = returnArray[contentKey] + contentValue else returnArray[contentKey] = contentValue end end end return returnArray end function VaultGetCopyUser() return GetVariable("vaultCopyUser") or "" end function VaultGetCurrentVault() return GetVariable("vaultCurrent") or "" end function VaultGetKnownUsers() local vaultArray = VaultGetVaultContents() local userList = table.valueList(vaultArray, "key") table.sort(userList, function (k1,k2) return string.lower(k1) < string.lower(k2) end) return userList end function VaultGetInVault() return GetVariable("vaultInVault") == "true" end function VaultGetInVaultWaitingRoom() local inVault = GetVariable("vaultInVaultWaitingRoom") local returnBoolean = false if inVault == "true" then returnBoolean = true end return returnBoolean end function VaultGetUser() return GetVariable("vaultUser") or "default" end function VaultGetVaultContents() local user = VaultGetUser() local vaultContentsString = GetVariable("vaultContents") or "" local data = json.decode(vaultContentsString) or {} data[user] = data[user] or {} for vaultsInfoKey, _ in pairs(vaultsInfo) do data[user][vaultsInfoKey] = data[user][vaultsInfoKey] or {full = "", contents = {}} end if type(GetVariable("vaultContents")) == "nil" then VaultSetVaultContents(data) end return data end function VaultGetCurrentUserVaultContents() local user = VaultGetUser() return VaultGetVaultContents()[user] end function VaultGetVaultsContainingItem(item) local contentsArray = VaultGetCurrentUserVaultContents() local matchVaults = {} for contentsArrayKey, contentsArrayValue in pairs(contentsArray) do for contentKey, contentValue in pairs(contentsArrayValue.contents) do if string.find(string.lower(contentKey), string.lower(item)) then table.insert(matchVaults, contentsArrayKey) break end end end return matchVaults end --#endregion --#region set function VaultCopyContentsToUser(toUser, fromUser) local vaultContents = VaultGetVaultContents() or {} vaultContents[toUser] = vaultContents[fromUser] VaultSetVaultContents(vaultContents) VaultSetCopyUser("") end function VaultSetCopyUser(user) SetVariable("vaultCopyUser", string.lower(user)) end function VaultSetCurrentVault(currentVaultString) if type(currentVaultString) == 'string' then SetVariable("vaultCurrent", currentVaultString) else ColourNote(configColour["error"], "", "VaultSetCurrentVault error: input is not of type string") end end function VaultSetCurrentUser(user) SetVariable("vaultUser", string.lower(user)) end function VaultSetInVaultWaitingRoom(inVaultWaitingRoomBoolean) if type(inVaultWaitingRoomBoolean) == 'boolean' then SetVariable("vaultInVaultWaitingRoom", tostring(inVaultWaitingRoomBoolean)) else ColourNote(configColour["error"], "", "VaultSetInVaultWaitingRoom error: input is not of type boolean") end end function VaultSetInVault(inVaultBoolean) if type(inVaultBoolean) == 'boolean' then SetVariable("vaultInVault", tostring(inVaultBoolean)) else ColourNote(configColour["error"], "", "VaultSetInVault error: input is not of type boolean") end end function VaultSetCurrentUserVaultContents(currentUserVaultContents) local user = VaultGetUser() local vaultContents = VaultGetVaultContents() vaultContents[user] = currentUserVaultContents VaultSetVaultContents(vaultContents) end function VaultSetVaultContents(vaultContentsArray) if type(vaultContentsArray) == 'table' then SetVariable("vaultContents", json.encode(vaultContentsArray)) else ColourNote(configColour["error"], "", "VaultSetVaultContents error: input is not of type table") end end --#endregion --#endregion --#region print functions function VaultPrintAllVaults() local vaultContentsArray = VaultGetCurrentUserVaultContents() local fullTable = {} for key, value in pairs(vaultContentsArray) do if not string.isEmpty(value.full) then table.insert(fullTable, vaultFullStates[value.full].percentage) end end local fullTableMax = table.valueMaxStringLength(fullTable) or 0 local cityTable = {} for key, value in pairs(vaultsInfo) do table.insert(cityTable, value.city) end local cityTableMax = table.valueMaxStringLength(cityTable) local showContentsMax = 0 if not table.isEmpty(VaultGetAllVaultContentItemsArray()) then showContentsMax = string.len("[Show contents] ") end local totalAmount = table.length(vaultsInfo) for i = 1, totalAmount, 1 do for vaultKey, vaultValue in pairs(vaultsInfo) do if vaultValue["order"] == i then local vault = vaultsInfo[vaultKey] -- Show if has contents in vault local vaultFull = vaultContentsArray[vaultKey].full if vaultFull ~= "" then -- Show hyperlink to get content details Tell("[") Tell(Hyperlink("vaultcontent " .. vaultKey, "Show contents", "Show contents of " .. vaultKey, colourHyperlink, "black", 0)) Tell("]") Tell(" ") else Tell(string.addLeadingTrailing("", showContentsMax, " ")) end if vaultFull ~= "" then -- Get hexcolour from vaultFullStates and use that. Tell("(") ColourTell(VaultGetHexColourByFill(vaultFull), "", string.addLeadingTrailing(vaultFullStates[vaultFull].percentage .. "%", fullTableMax, " ")) Tell(")") Tell(" ") else if fullTableMax ~= 0 then Tell(string.addLeadingTrailing("", fullTableMax + 4, " ")) end end ColourTell(colourCityName, "", vault.city) Tell(string.addLeadingTrailing("", cityTableMax - string.len(vault.city) + 1, " ", true)) Tell(Hyperlink("minimap " .. vaultKey, vaultKey, "Automove to " .. vaultKey, colourHyperlink, "black", 0)) Tell(" (costs ") ColourTell(colourVaultCost, "", vault.cost) Tell(")") Note("") end end end end function VaultPrintAnyHasItem(item) if type(item) ~= "string" then Note("item is not a string") elseif string.len(item) < 3 then Note("Enter at least 3 letters to get more accurate results.") else local vaultContentsArray = VaultGetCurrentUserVaultContents() local matchVaultTable = VaultGetVaultsContainingItem(item) local fullTable = {} for key, value in pairs(vaultContentsArray) do table.insert(fullTable, value.full) end local fullTableMax = table.valueMaxStringLength(fullTable) local cityTable = {} for key, value in pairs(vaultsInfo) do table.insert(cityTable, value.city) end local cityTableMax = table.valueMaxStringLength(cityTable) local showContentsMax = 0 if not table.isEmpty(VaultGetAllVaultContentItemsArray()) then showContentsMax = string.len("[Show contents] ") end if(#matchVaultTable == 0) then ColourTell(colourVaultName, "", "No vault contains ") ColourTell(colourItem, "", item) ColourTell(colourVaultName, "", ".") Note() else for i = 1, #matchVaultTable, 1 do local vaultKey = matchVaultTable[i] local vault = vaultsInfo[vaultKey] -- Show if has contents in vault local vaultFull = vaultContentsArray[vaultKey].full if vaultFull ~= "" then -- Show hyperlink to get content details Tell("[") Tell(Hyperlink("vaultcontent " .. vaultKey, "Show contents", "Show contents of " .. vaultKey, colourHyperlink, "black", 0)) Tell("]") Tell(" ") else Tell(string.addLeadingTrailing("", showContentsMax, " ")) end if vaultFull ~= "" then -- Get hexcolour from vaultFullStates and use that. Tell("(") ColourTell(VaultGetHexColourByFill(vaultFull), "", string.addLeadingTrailing(vaultFullStates[vaultFull].percentage .. "%", 4, " ")) Tell(")") Tell(" ") else Tell(string.addLeadingTrailing("", 7, " ")) end ColourTell(colourCityName, "", vault.city) Tell(string.addLeadingTrailing("", cityTableMax - string.len(vault.city) + 1, " ", true)) Tell(Hyperlink("minimap " .. vaultKey, vaultKey, "Automove to " .. vaultKey, colourHyperlink, "black", 0)) Tell(" (costs ") ColourTell(colourVaultCost, "", vault.cost) Tell(")") Note("") local vaultContents = vaultContentsArray[matchVaultTable[i]].contents for key, value in pairs(vaultContents) do if string.match(string.lower(key), string.lower(item)) then Tell("- ") ColourTell(colourItem, "", key) Tell(": ") ColourTell(colourArmount, "", value) Tell(" [") ColourTell(Hyperlink("\nwait\ntake 1 " .. key .. " from " .. vault.container .. "\nlook " .. vault.container, "take one", "take one " .. key .. " from " .. vault.container, colourHyperlink, "black", 0)) Tell("] ") Note() end end end end end end function VaultPrintConsolidatedVaultContents() local allVaultContentItemsArray = VaultGetAllVaultContentItemsArray() if not table.isEmpty(allVaultContentItemsArray) then local title = "All vaults' contents" ColourNote(colourVaultName, "", string.upper(title)) VaultPrintContentsArray(VaultGetAllVaultContentItemsArray(), true) else ColourNote(colourVaultName, "", "No vault contains any item.") end end function VaultPrintVaultContents(vaultName) if type(vaultName) == "string" and vaultName ~= "" then local vaultContentsArray = VaultGetCurrentUserVaultContents() ColourNote(colourVaultName, "", string.upper(vaultName)) VaultPrintContentsArray(vaultContentsArray[vaultName].contents, true) else ColourNote(configColour["error"], "", "VaultPrintVaultContents error: input is empty or not of type string") end end function VaultPrintContentsArray(array, toSort) if type(array) == "table" then local sortArray = false if toSort then sortArray = toSort end local contentsTable = {} for key, value in pairs(array) do table.insert(contentsTable, {name = key, amount = value}) end if sortArray then table.sort(contentsTable, function (k1,k2) return string.lower(k1.name) < string.lower(k2.name) end) end for _, value in ipairs(contentsTable) do ColourTell(colourItem, "", value.name) Tell(": ") ColourTell(colourArmount, "", value.amount) Note("") end else ColourNote(configColour["error"], "", "VaultPrintContentsArray error: input array is not of type table") end end --#endregion --#endregion ]]> </script> <!-- Triggers --> <triggers> <trigger enabled="y" regexp="y" group="VaultTrigger" match="^\[(Nella\'s vault)\]$" script="VaultTriggerSetCurrentVault" sequence="100" > </trigger> <trigger enabled="y" regexp="y" group="VaultTrigger" match="^\[(cool, dry basement)\]$" script="VaultTriggerSetCurrentVault" sequence="100" > </trigger> <trigger enabled="y" regexp="y" group="VaultTrigger" match="^\[(safety deposit waiting room)\]$" script="VaultTriggerSetCurrentVault" sequence="100" > </trigger> <trigger enabled="y" regexp="y" group="VaultTrigger" match="^\[(Thella\'s vault)\]$" script="VaultTriggerSetCurrentVault" sequence="100" > </trigger> <trigger enabled="y" regexp="y" group="VaultTrigger" match="^\[(small garden)\]$" script="VaultTriggerSetCurrentVault" sequence="100" > </trigger> <trigger enabled="y" regexp="y" group="VaultTrigger" match="^\[(opulent office)\]$" script="VaultTriggerSetCurrentVault" sequence="100" > </trigger> <trigger enabled="y" regexp="y" group="VaultTrigger" match="^\[(office in Ohulan-Cutash)\]$" script="VaultTriggerSetCurrentVault" sequence="100" > </trigger> <trigger regexp="y" group="VaultTrigger" match="^\[(.+)\]$" name="lblVaultTriggerSetInsideVault" script="VaultTriggerSetInsideVault" sequence="10" > </trigger> <trigger enabled="y" regexp="y" name="lblVaultSetContent" group="VaultTrigger" match="The (drawer|large wooden drawer|steel locker|cubby hole|octiron tesseract|clean nest) (is )?(contains|almost empty except for|about (.+) full with|almost full with|almost completely full with|completely full with|over-full with) (.+)\." script="VaultTriggerContents" sequence="100" > </trigger> </triggers> <!-- Aliases --> <aliases> <alias enabled="y" regexp="y" ignore_case="y" name="lblVaultCheckAllVaults" group="VaultAlias" match="^vaults?$" script="VaultAliasVaultCheckAllVaults" sequence="100" > </alias> <alias enabled="y" regexp="y" ignore_case="y" name="lblVaultCheckAnyHasItem" group="VaultAlias" match="^vaults? (.*)$" script="VaultAliasVaultCheckAnyHasItem" sequence="100" > </alias> <alias enabled="y" regexp="y" ignore_case="y" name="lblVaultCheckAll" group="VaultAlias" match="^vaults?all$" script="VaultAliasVaultCheckAll" sequence="100" > </alias> <alias enabled="y" regexp="y" ignore_case="y" name="lblVaultContent" group="VaultAlias" match="^vaults?content (.+)$" script="VaultAliasVaultContent" sequence="100" > </alias> <alias enabled="y" ignore_case="y" regexp="y" keep_evaluating="y" match="^VaultUsers?$" group="VaultAlias" script="VaultAliasVaultShowUsers" sequence="100" > </alias> <alias enabled="y" ignore_case="y" regexp="y" keep_evaluating="y" match="^VaultUsers? (\w+).*$" group="VaultAlias" script="VaultAliasVaultSetUser" sequence="100" > </alias> <alias enabled="y" ignore_case="y" regexp="y" keep_evaluating="y" match="^VaultDeleteUser (\w+).*$" group="VaultAlias" script="VaultAliasVaultDeleteUser" sequence="100" > </alias> <alias enabled="y" ignore_case="y" regexp="y" keep_evaluating="y" match="^VaultCopy (\w+)" group="VaultAlias" script="VaultAliasVaultCopy" sequence="100" > </alias> <alias enabled="y" ignore_case="y" regexp="y" keep_evaluating="y" match="^VaultPaste (\w+)$" group="VaultAlias" script="VaultAliasVaultPaste" sequence="100" > </alias> <alias enabled="y" ignore_case="y" regexp="y" keep_evaluating="y" match="^ChangeUsers?$" group="VaultAlias" script="VaultAliasChangeUser" sequence="100" > </alias> <alias enabled="y" ignore_case="y" regexp="y" keep_evaluating="y" match="^ChangeUsers? (\w+)$" group="VaultAlias" script="VaultAliasVaultSetUser" sequence="100" > </alias> </aliases> <!-- Timers --> <timers> </timers> </muclient>