尝试使用Discordia和Lua hasRole()构建Discord bot使其崩溃

时间:2020-06-28 10:33:25

标签: lua bots discord luajit luvit

所以我让我的机器人与hasRole()一起工作,但是我向它添加了音乐播放功能,现在每次调用hasRole()时,它返回nil并使机器人崩溃。它在kick,ban和unban命令中使用它。我不知道发生了什么事。无论如何,这是我得到的错误:

Uncaught Error: .../Documents/Lua Projects/DiscordBot/deps/coro-channel.lua:62: ...rojects/DiscordBot/deps/discordia/libs/utils/Emitter.lua:105: C:\Users\willb\Documents\Lua Projects\DiscordBot\bot.lua:200: attempt to call local 'mem' (a table value)
stack traceback:
        [C]: in function 'assert'
        .../Documents/Lua Projects/DiscordBot/deps/coro-channel.lua:62: in function 'onPlain'
        ...s/Lua Projects/DiscordBot/deps/secure-socket/biowrap.lua:76: in function <...s/Lua Projects/DiscordBot/deps/secure-socket/biowrap.lua:61>
        [C]: in function 'run'
        [string "bundle:/init.lua"]:52: in function <[string "bundle:/init.lua"]:47>
        [C]: in function 'xpcall'
        [string "bundle:/init.lua"]:47: in function 'fn'
        [string "bundle:deps/require.lua"]:310: in function <[string "bundle:deps/require.lua"]:266>

这是我的机器人脚本:

local discordia = require("discordia")
local coro = require("coro-http")
local json = require("json")
local spawn = require('coro-spawn')
local parse = require('url').parse
local client = discordia.Client()

modid = "726406258730598451"
adminid = "726444986786381834"

discordia.extensions()

local connections = { }

local commands = {
    {Command = "Admin Commands", Description = ""};
    {Command = "  -kick [user]", Description = "Kicks a user"};
    {Command = "  -ban [user]", Description = "Bans a user"};
    {Command = "  -unban [user]", Description = "Unbans a user"};
    {Command = "  -myid", Description = "Replies with your member ID"};
    {Command = "Fun Commands!", Description = ""};
    {Command = "  -ping", Description = "Replies with pong"};
    {Command = "  -norris", Description = "Replies with a Chuck Norris fact"};
    {Command = "  -cool [user]", Description = "Says how cool the mentioned user is! If no one is mentioned it replies with how cool you are"};
}

local function getStream(url)
    local child = spawn('youtube-dl', {
        args = {'-g', url},
        stdio = { nil, true, 2 }
    })

    local stream
    for chunk in child.stdout.read do
        local urls = chunk:split('\n')

        for _, yturl in pairs(urls) do
            local mime = parse(yturl, true).query.mime

            if mime and mime:find('audio') == 1 then
                stream = yturl
            end
        end
    end

    return stream
end

function err()
    message:reply("Sorry something went wrong. Please try again!")
end

function chuckNorris(message)
    coroutine.wrap(function()
        local link = "https://api.chucknorris.io/jokes/random"
        local result, body = coro.request("GET", link)
        body = json.parse(body)
        message:reply("<@!"..message.member.id.."> "..body["value"])
    end)()
end


client:on("messageCreate", function(message)

    local content = message.content
    local member = message.author
    local memberid = message.author.id
    
    if message.author == client.user then return end
    if not message.guild then return end
    if message.author.bot then return end
    
    local args = message.content:split('%s+')
    local cmd = table.remove(args, 1)
    
    if cmd == '-join' then
        local member = message.guild:getMember(message.author)
        local channel = member.voiceChannel

        if channel then
            if connection and connection.channel ~= channel or not connection then
                print('joining')
                connection = channel:join()
                connections[message.guild.id] = connection
            end
        end
    elseif cmd == '-leave' then
        if connection then
            print('leaving')
            connection:close()
        end
    elseif cmd == '-play' then
        if connection then
            local requested = args[1]
            local url = getStream(requested)

            print('fetching', requested)
            if url then
                print('playing', url)
                connection:playFFmpeg(url)
            else
                message:reply('could not fetch the audio for that video.')
            end
        elseif not connection then
            local member = message.guild:getMember(message.author)
            local channel = member.voiceChannel
            print('joining')
            connection = channel:join()
            connections[message.guild.id] = connection
            local requested = args[1]
            local url = getStream(requested)
            print('fetching', requested)
            if url then
                print('playing', url)
                connection:playFFmpeg(url)
            else
                message:reply('could not fetch the audio for that video.')
            end
        end
    elseif cmd == '-pause' then
        print('pausing')
        connection:pauseStream()
    elseif cmd == '-resume' then
        print('resuming')
        connection:resumeStream()
    elseif cmd == '-skip' then
        print('stopping')
        connection:stopStream()
    elseif cmd == '-stop' then
        print('stopping')
        connection:stopStream()
    elseif cmd == '-leave' then
        print('leaving')
        connection:close()
    end
    
    if cmd == "-ping" then
        message:reply("pong")
    end
    
    if cmd == "-test" then
        message:reply("-ping")
    end
    
    if cmd == "-norris" then
        chuckNorris(message)
    end 
    
    if cmd == "-cool" then
        local mentioned = message.mentionedUsers
        if #mentioned == 1 then
            message:reply("<@!"..mentioned[1][1].."> is "..math.random(1,100).."% cool.")
        elseif #mentioned == 0 then
            message:reply("<@!"..memberid.."> is "..math.random(1,100).."% cool.")
        end
    end
    
    if cmd == "-help" then
        local c = member:getPrivateChannel()
        local list = ""
        for i,v in pairs(commands) do
            list = list.."   "..v.Command..": "..v.Description.."\n"
        end
        c:send(list)
    end
    
    if cmd == "-ban" then
        local mentioned = message.mentionedUsers
        if member:hasRole(modid) then
            if #mentioned == 1 then
                message:reply("<@!"..mentioned[1][1].."> has been banned.")
                member.guild:banUser(mentioned[1][1],_,_)
            elseif #mentioned == 0 then
                message:reply("Error: Incorrect Syntax = -ban [user]")
                
            elseif #mentioned >= 1 then
                message:reply("Sorry that operation isn't supported yet.")
            end
        else
            message:reply("You do not have permission to run that command.")
        end
    end
    
    if cmd == "-unban" then
        local mentioned = message.mentionedUsers
        if member:hasRole(modid) then
            if #mentioned <= 1 then
                message:reply("<@!"..mentioned[1][1].."> has been unbanned.")
                member.guild:unbanUser(mentioned[1][1],_)
            elseif #mentioned >= 1 then
                message:reply("Sorry that operation isn't supported yet.")
            end
        else
            message:reply("You do not have permission to run that command.")
        end
    end
    
    if cmd == "-kick" then
        local mentioned = message.mentionedUsers
        if member:hasRole(modid) then
            if #mentioned <= 2 then
                message:reply("<@!"..mentioned[1][1].."> has been kicked for ")
                member.guild:kickUser(mentioned[1][1],_)
            elseif #mentioned == 0 then
                message:reply("Error: Incorrect Syntax = -kick [user]")
            elseif #mentioned >= 2 then
                message:reply("Sorry that operation isn't supported yet.")
            end
        else
            message:reply("You do not have permission to run that command.")
        end
    end
    
    if cmd == "-myid" then
        message:reply(""..memberid.."")
    end
     
    if cmd == "-bulkdel" then
        local messages = message.channel:getMessages(100)
        local new = messages:toArray(function(a)
            if a.content:find('$') or a.author.bot then
                return true
            end
        end)
        message.channel:bulkDelete(new)
        message:reply("The last 100 messages have been deleted!")
    end
end)



client:run("Bot "..io.open("./login.txt"):read())

无论如何,谢谢大家。我真的不知道发生了什么,这非常令人沮丧。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以尝试将member:hasRole(modid)替换为权限变体(也称为message.member:hasPermission(...)) 我建议您在尝试任何操作之前先阅读一下该功能,因为我本人不是Discordia的专业人员;)

有用的链接:

Lua文档: https://github.com/SinisterRectus/Discordia/wiki/

member类的Discordia Wiki: https://github.com/SinisterRectus/Discordia/wiki/Member

所有渗透的枚举:https://github.com/SinisterRectus/Discordia/wiki/Enumerations#permission