Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local moduleManip = peripheral.wrap("top") -- Fix this
- if moduleManip ~= nil then
- moduleManip.capture("^!")
- end
- local mName = "&h(bagel 'n roger wuz here.)&i(https://www.youtube.com/watch?v=ByC8sRdL-Ro)<&r&dAllium&r>" --bot title
- local color = require("color") --Sponsored by roger109z
- local allium = {} -- API table
- local plugins = {} -- Plugin table
- allium.assert = function(condition, message, level)
- if not condition then error(message, level) end
- end
- allium.register = function(name)
- assert(type(name) == "string", "Invalid argument #1 (string expected, got "..type(name)..")", 2)
- assert(plugins[name:lower()] == nil, "Invalid argument #1 (plugin exists under name "..name:lower()..")")
- plugins[name:lower()] = {threads = {}, commands = {}, info = {}, name = name}
- local funcs = {}
- local this = plugins[name:lower()]
- funcs.command = function(name, command, info)
- assert(type(name) == "string", "Invalid argument #1 (string expected, got "..type(name)..")", 2)
- assert(type(command) == "function", "Invalid argument #2 (function expected, got "..type(command)..")", 2)
- assert(this.commands[name:lower()] == nil, "Invalid argument #2 (command exists under name "..name:lower().." for plugin "..this.name..")", 2)
- assert(type(info) == "string", "Invalid argument #3 (string expected, got "..type(info)..")", 2)
- this.commands[name:lower()] = command
- this.info[name:lower()] = info
- end
- funcs.thread = function(thread)
- assert(type(thread) == "function", "Invalid argument #1 (function expected, got "..type(thread)..")", 2)
- this.threads[#this.threads+1] = thread
- end
- return funcs
- end
- allium.tell = function(name, message, hidetag, botname) --allium.tell as documented in README
- local m
- if type(message) == "string" then
- m = message
- else
- m = ""
- end
- if type(botname) ~= "string" then
- botname = mName
- end
- local _, test = commands.tellraw(name, color.format((function(hidetag)if hidetag then return "" else return botname.."&r " end end)(hidetag)..m))
- if type(message) == "table" then
- for k, v in pairs(message) do
- local _, l = commands.tellraw(name, color.format(v))
- end
- end
- return textutils.serialise(test)
- end
- allium.getPlayers = function()
- local didexec, input = commands.exec("list")
- if not didexec then
- local _, users = commands.testfor("@a")
- local out = {}
- for i = 1, #users do
- out[#out+1] = string.sub(users[i], 7, -1)
- end
- return out
- end
- local out = {}
- for user in string.gmatch(input[2], "%S+") do
- local comma = string.find(user, ",")
- if not comma then comma = -1 else comma=comma-1 end
- out[#out+1] = string.sub(user, 0, comma)
- end
- return out
- end
- allium.getPersistence = function(name) --allium.getPersistence as documented in README
- if fs.exists("persistence.json") then
- local fper = fs.open("persistence.json", "r")
- local tpersist = textutils.unserialize(fper.readAll())
- fper.close()
- if not tpersist[origin] then
- tpersist[origin] = {}
- end
- if type(name) == "string" then
- return tpersist[origin][name]
- end
- end
- return false
- end
- allium.setPersistence = function(name, data) --allium.setPersistence as documented in README
- local tpersist
- if fs.exists("persistence.json") then
- local fper = fs.open("persistence.json", "r")
- tpersist = textutils.unserialize(fper.readAll())
- fper.close()
- end
- if not tpersist[origin] then
- tpersist[origin] = {}
- end
- if type(name) == "string" then
- tpersist[origin][name] = data
- local fpers = fs.open("persistence.json", "w")
- fpers.write(textutils.serialise(tpersist))
- fpers.close()
- return true
- end
- return false
- end
- allium.getInfo = function(plugin, command) -- Get the information of all plugins, a single plugin, or a single command from a plugin
- assert(plugin == nil or type(plugin) == "string", "Invalid argument #1 (string expected, got"..type(plugin)..")", 2)
- assert(command == nil or type(command) == "string", "Invalid argument #2 (string expected, got"..type(command)..")", 2)
- if command then
- assert(plugin, "Invalid argument #1 (string expected, got"..type(plugin)..")", 2)
- end
- if plugin then
- assert(plugins[plugin], "Invalid argument #1 (plugin "..plugin.." does not exist)", 2)
- if command then
- assert(plugins[plugin].command[command], "Invalid argument #2 (command "..command.." does not exist in plugin "..plugin..")")
- end
- end
- if command then
- return plugins[plugin].info[command]
- elseif plugin then
- local res = {}
- for k, v in pairs(plugins[plugin].info) do
- res[k] = v
- end
- return res
- else
- local res = {}
- for p_name, plugin in pairs(plugins) do
- res[p_name] = {}
- for c_name, info in pairs(plugin.info) do
- res[p_name][c_name] = info
- end
- end
- return res
- end
- end
- local function is_require() -- This function was elegantly made by SquidDev
- -- See: https://discordapp.com/channels/477910221872824320/477911902152949771/536123240154660864
- if not shell then return("os.loadAPI") end
- if not package then return "shell.run" end -- Compat for old versions of CC
- -- Locate the sentinel value, and check that it's currently within the table
- -- somewhere.
- package.preload["__sentinel"] = function() return package.loaded["__sentinel"] end
- local sentinel = require("__sentinel")
- for k, v in pairs(package.loaded) do
- if k ~= "__sentinel" and v == sentinel then return "require" end
- end
- return "shell.run"
- end
- package.loaded["__sentinel"] = nil
- local is_it = is_require()
- if is_it == "require" then
- return allium
- elseif is_it == "os.loadAPI" then -- Please for the love of god never use os.loadAPI
- _G.allium = allium
- end
- do -- Plugin loading process
- print("Loading plugins...")
- local dir = shell.dir()
- if fs.exists(dir.."plugins") then
- for _, plugin in pairs(fs.list(dir.."plugins")) do
- if not fs.isDir(dir.."plugins/"..plugin) then
- local file = loadfile(dir.."plugins/"..plugin)
- local suc, err = pcall(file)
- if not suc then
- printError(err)
- end
- end
- end
- end
- end
- local main = function()
- while true do
- local _, message, _, name = os.pullEvent("chat_capture") --Pull chat messages
- if string.find(message, "!") == 1 then --are they for allium?
- args = {}
- for k in string.gmatch(message, "%S+") do --put all arguments spaced out into a table
- args[#args+1] = k
- end
- local cmd = args[1]:sub(2, -1) -- Strip the !
- table.remove(args, 1) --remove the first parameter given (!command)
- local p_cmds = {} -- List of possible commands if there's more than one that matches the "!command" standard
- if not string.find(cmd, ":") then --did they not specify the plugin source?
- print(#plugins)
- for p_name, plugin in pairs(plugins) do --nope... gonna have to find it for them.
- print(p_name)
- for c_name, command in pairs(plugin) do
- print(c_name)
- if c_name == cmd then --well I found it, but there may be more...
- p_cmds[#p_cmds+1] = {command, p_name} --split into command function, source
- end
- end
- end
- else --hey they did! +1 karma.
- local splitat = string.find(cmd, ":")
- if plugins[string.sub(cmd, 1, splitat-1)] then --check plugin existence
- if plugins[string.sub(cmd, 1, splitat-1)].commands[string.sub(cmd, splitat+1, -1)] then --check command existence
- p_cmds[#p_cmds+1] = {plugins[string.sub(cmd, 1, splitat-1)].commands[string.sub(cmd, splitat+1, -1)], string.sub(cmd, 1, splitat-1)} --split it into the function, and then the source
- end
- end
- end
- if #p_cmds == 1 and p_cmds[1][1] then --is it really a command, and is there only one that is titled this?
- local stat, err = pcall(p_cmds[1][1], name, args) --Let's execute the command in a safe environment that won't kill allium
- if stat == false then--it crashed...
- allium.tell(name, "&4"..cmd.." crashed! This is likely not your fault, but the developer's. Please contact the developer of &a"..p_cmds[1][2].."&4. Error:\n&c"..err)
- print(cmd.." errored. Error:\n"..err)
- end
- elseif #p_cmds > 1 then --WHAT MORE THAN ONE OUTCOME!?!?
- local colstr = ""
- for i = 1, #p_cmds do --idiot, I'm going to have to list them out for you...
- if i ~= #p_cmds then
- colstr = colstr.."&a&g(!"..p_cmds[i][2]..":"..cmd..")&h(Click to run !"..p_cmds[i][2]..":"..cmd..")"..p_cmds[i][2].."&r&e, "
- else
- colstr = colstr.."and &a&g(!"..p_cmds[i][2]..":"..cmd..")&h(Click to run !"..p_cmds[i][2]..":"..cmd..")"..p_cmds[i][2].."&r&e."
- end
- end --how dare you inconvenience me...
- allium.tell(name, "&eCommand collision beween "..colstr.." Click on the plugin that you want to run the command from. Optionally specify the command you want to use by prefixxing the plugin name followed by a colon, and then the command name. Ex: &c&g(!allium:github)!allium:github&r&e.") --REEEEEEEE
- else --this isn't even a valid command...
- allium.tell(name, "&6Invalid Command, use &c&g(!allium:help)!help&r&6 for assistance.") --bleh!
- end
- end
- end
- end
- local threads = {} -- Temporary
- threads[#threads+1] = coroutine.create(main) --Add main to the thread table
- if not fs.exists("persistence.json") then --In the situation that this is a first installation, let's add persistence.json
- local fpers = fs.open("persistence.json", "w")
- fpers.write("{}")
- fpers.close()
- end
- print("allium started.")
- allium.tell("@a", "allium loaded.")
- --This clump is pulled and adapted for what I need it for, parallel.waitForAll, for a table of coroutines. Its origin is in /rom/apis/parallel.lua in CraftOS.
- local count = #threads
- local living = count
- local tFilters = {}
- local eventData = { n = 0 }
- while true do
- for n=1,count do
- local r = threads[n]
- if r then
- if tFilters[r] == nil or tFilters[r] == eventData[1] or eventData[1] == "terminate" then
- local ok, param = coroutine.resume( r, table.unpack( eventData, 1, eventData.n ) )
- if not ok then
- error( param, 0 )
- else
- tFilters[r] = param
- end
- if coroutine.status( r ) == "dead" then
- threads[n] = nil
- living = living - 1
- if living <= 0 then
- return n
- end
- end
- end
- end
- end
- for n=1,count do
- local r = threads[n]
- if r and coroutine.status( r ) == "dead" then
- threads[n] = nil
- living = living - 1
- if living <= 0 then
- return n
- end
- end
- end
- eventData = table.pack( os.pullEventRaw() )
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement