Command Line Simple Triggers and Aliases Script

Share your scripts and packages with other Mudlet users.
Post Reply
Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Command Line Simple Triggers and Aliases Script

Post by Jor'Mox »

Someone asked on Discord about making triggers/aliases in the command line, so here is a script I made a while back that implements something along those lines. Just copy/paste it in, and you can use '/alias help' or '/trigger help' to see how to make it work.
Code: [show] | [select all] lua
-- Jor'Mox's Command Line Simple Triggers and Aliases Script
-- 
-- use /alias pattern >> commands to send    to create an alias
-- use /trigger pattern >> commands to send   to create a trigger
-- 
-- use * to indicate an argument or word(s) that must be provided
-- use ? to indicate an argument or word(s) that is optional
-- use %# to indicate the appropriately numbered argument or captured words
-- use wait # to wait that many seconds, including decimal seconds, before continuing to the next command
--
-- use /alias or /trigger to show a list of all aliases or triggers managed by this script
-- use /delete alias # or /delete trigger # to delete that alias or trigger, using the number matching that shown on the list
-- 

cmd_line = cmd_line or {data = {}}
cmd_line.data.triggers = cmd_line.triggers or {}
cmd_line.data.aliases = cmd_line.aliases or {}
local script_aliases = script_aliases or {}

local runQueue
function runQueue(fnc,tbl)
    local info = table.remove(tbl,1)
    if info then
        local run = function()
                fnc(info[2])
                runQueue(fnc,tbl)
            end
        if info[1] ~= 0 then
            tempTimer(info[1], run)
        else
            run()
        end
    end
end

local function doQueue(fnc,...)
    local tbl = {}
    local args = arg
    if type(arg[1]) == "table" then args = arg[1] end
    for k,v in ipairs(args) do
        if k % 2 == 1 and type(v) ~= "number" then
            table.insert(args,k,0)
        end
    end
    for k = 1,#args,2 do
        tbl[(k + 1) / 2] = {args[k],args[k+1]}
    end
    runQueue(fnc,tbl)
end

function sendQueue(...)
    doQueue(send,...)
end

function expandQueue(...)
    doQueue(expandAlias,...)
end

local function parse_pattern(ptrn)
    ptrn = string.gsub(ptrn,"([^/])%*","%1(.*)")
    ptrn = string.gsub(ptrn,"^%*","(.*)")
    ptrn = string.gsub(ptrn,"([^/])%?","%1\\s*(.*)")
    ptrn = string.gsub(ptrn,"^%?%s*","(.-)\s*")
    ptrn = string.gsub(ptrn,"%s+\\s%*","\\s*")
    ptrn = "^" .. ptrn .. "$"
    return ptrn
end

local function parse_cmds(cmds)
    cmds = string.split(cmds,"%s*;%s*")
    local str = "expandQueue("
    local start, match, stop, tmp
		local comma = ""
    for k,v in ipairs(cmds) do
        if string.match(v,"wait [%d%.]+") then
            str = str .. comma .. string.match(v,"^wait ([%d%.]+)$")
        elseif string.match(v,"%%%d+") then
            tmp = ""
			for start, match, stop in string.gmatch(v,"(.-)%%(%d+)([^%%]*)") do
                tmp = tmp .. string.format([[%s" .. matches[%s] .. "%s]], start, match + 1, stop)
            end
            str = str .. comma .. [["]] .. tmp .. [["]]
        else
            str = str .. comma .. [["]] .. v .. [["]]
        end
		comma = ","
    end
    str = str .. ")"
    return str
end

local function save_cmd()
    table.save(getMudletHomeDir().."/mycmd_data.lua", cmd_line.data)
end

local function check_duplicate(ptrn, is_trigger)
    local tbl
    local func
    if is_trigger then
        tbl = cmd_line.data.triggers
        func = killTrigger
    else
        tbl = cmd_line.data.aliases
        func = killAlias
    end
    
    for i,v in ipairs(tbl) do
        if v[2] == ptrn then
            func(v[1])
            print(string.format("Existing %s with identical pattern has been replaced.",is_trigger and "trigger" or "alias"))
            table.remove(tbl,i)
            break
        end
    end
end

local function make_item(ptrn, cmds, is_trigger, is_config)
    local pattern = parse_pattern(ptrn)
    local commands = parse_cmds(cmds)
    if not is_config then
        check_duplicate(ptrn,is_trigger)
    end
    if is_trigger then
        table.insert(cmd_line.data.triggers,{tempRegexTrigger(pattern,commands),ptrn,cmds})
    else
        table.insert(cmd_line.data.aliases,{tempAlias(pattern,commands),ptrn,cmds})
    end
    if not is_config then
        save_cmd()
        print(string.format("New %s with pattern %s has been created.",is_trigger and "trigger" or "alias",ptrn))
    end
end

local function show_items(triggers)
    local tbl
    local str, strs = "alias", "aliases"
    if triggers then
        tbl = cmd_line.data.triggers
        str, strs = "trigger", "triggers"
    else
        tbl = cmd_line.data.aliases
    end
    if not tbl or table.is_empty(tbl) then
        print("Sorry, you don't have any " .. strs .. ".\n")
        print("Syntax for " .. strs .. ": /" .. str .. " pattern >> commands to send")
        print("You can type '/" .. str .. " help' for additional information.")
    else
        for i,v in ipairs(tbl) do
            print(string.format("%3s: %s  >>  %s",i,v[2],v[3]))
        end
    end
end

local function delete_item(number, is_trigger)
    local info, func
    if is_trigger then
        info = table.remove(cmd_line.data.triggers,number)
        func = killTrigger
    else
        info = table.remove(cmd_line.data.aliases,number)
        func = killAlias
    end
    if info then
        func(info[1])
        save_cmd()
        print(string.format("%s number %s has been deleted.",is_trigger and "Trigger" or "Alias",number))
    end
end

local function load_cmd()
    local file = getMudletHomeDir().."/mycmd_data.lua"
	local tmp = {}
	cmd_line.data = {aliases = {}, triggers = {}}
    if io.exists(file) then
        table.load(file, tmp)
		for i,v in ipairs(tmp.triggers) do
        	make_item(v[2],v[3],true,true)
    	end
    	for i,v in ipairs(tmp.aliases) do
        	make_item(v[2],v[3],false,true)
    	end
    end
end

local function disp_help(cmd)
    if cmd == "trigger" then
        print([[Syntax for triggers: /trigger pattern >> commands to send
Example: /trigger You are thirsty. >> drink decanter
/trigger * walks in * >> strangle %1 ; wait 1.5 ; zap %1]])
    else
        print([[Syntax for aliases: /alias pattern >> commands to send
Example: /alias dt >> cast 'detect hidden' ; cast 'detect invis'
Example: /alias ff ? >> cast 'fireball' %1]])
    end
    print([[--------------------------------------------------------------------------------------------
use * to indicate an argument or word(s) that must be provided
use ? to indicate an argument or word(s) that is optional
use %# to indicate the appropriately numbered argument or captured words
use wait # to wait that many seconds, including decimal seconds, before continuing to the next command

use /alias or /trigger to show a list of all aliases or triggers managed by this script
use /delete alias # or /delete trigger # to delete that alias or trigger, using the number matching that shown on the list

NOTE: If you're having issues with multiple commands not working, please check your Settings > Input line and make sure your Command Separator is not a single ;
]])
end

local function config()
    for i,v in ipairs(cmd_line.data.triggers) do
        killTrigger(v[1])
    end
    for i,v in ipairs(cmd_line.data.aliases) do
        killAlias(v[1])
    end
    for i,v in ipairs(script_aliases) do
        killAlias(v)
    end
    load_cmd()
    
    script_aliases = {}
    table.insert(script_aliases,tempAlias([[^/(alias|trigger) (.*) >> (.*)$]],[[raiseEvent("cmdMakeItem",matches[2],matches[3],matches[4])]]))
    table.insert(script_aliases,tempAlias([[^/(alias|trigger)$]],[[raiseEvent("cmdShowList",matches[2])]]))
    table.insert(script_aliases,tempAlias([[^/(alias|trigger) help$]],[[raiseEvent("cmdShowHelp",matches[2])]]))
    table.insert(script_aliases,tempAlias([[^/delete (alias|trigger) (\d+)$]],[[raiseEvent("cmdDeleteItem",matches[2],matches[3])]]))
end

function cmd_line.event_handler(event,...)
    if event == "sysConnectionEvent" or event == "sysInstall" then
        config()
    elseif event == "cmdMakeItem" then
        make_item(arg[2],arg[3],arg[1] == "trigger")
    elseif event == "cmdShowList" then
        show_items(arg[1] == "trigger")
    elseif event == "cmdDeleteItem" then
        delete_item(arg[2], arg[1] == "trigger")
    elseif event == "cmdShowHelp" then
        disp_help(arg[1])
    end
end

registerAnonymousEventHandler("sysConnectionEvent", "cmd_line.event_handler")
registerAnonymousEventHandler("sysInstall", "cmd_line.event_handler")
registerAnonymousEventHandler("cmdMakeItem", "cmd_line.event_handler")
registerAnonymousEventHandler("cmdShowList", "cmd_line.event_handler")
registerAnonymousEventHandler("cmdDeleteItem", "cmd_line.event_handler")
registerAnonymousEventHandler("cmdShowHelp", "cmd_line.event_handler")

Post Reply