CORS issue on ESP32 with nodemcu lua - lua

I want to create Esp32 based server and wanted to implement local REST api's so I took https://github.com/abobija/api32 help and written some api's everything working with chrome/postman but when tried to use with my mobile app not able to get the response but can able to post the data to esp32.
I'm getting this error
Access to XMLHttpRequest at 'http://192.168.0.10/' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
my code is
Title : Library for easy way of creating HTTP JSON Api Service for ESP32
Author : Alija Bobija
Author-Website : https://abobija.com
GitHub Repo : https://github.com/abobija/api32
Dependencies:
- sjson
- encoder
]]
local Api32 = {}
local function str_starts_with(haystack, needle)
return haystack:sub(1, #needle) == needle
end
local function str_ends_with(str, ending)
return ending == "" or str:sub(-#ending) == ending
end
local function str_split(inputstr, sep)
if sep == nil then sep = "%s" end
local result = {}
for str in inputstr:gmatch("([^"..sep.."]+)") do table.insert(result, str) end
return result
end
local function json_parse(json_str)
local ok
local result
ok, result = pcall(sjson.decode, json_str)
if ok then return result end
return nil
end
local function json_stringify(table)
local ok
local json
ok, json = pcall(sjson.encode, table)
if ok then return json end
return nil
end
local function get_http_header_value(hname, hlines)
for _, hline in pairs(hlines) do
if str_starts_with(hline:lower(), hname:lower()) then
local colon_index = hline:find(':')
if colon_index ~= nil then
return hline:sub(colon_index + 2)
end
end
end
return nil
end
local function get_auth_from_http_header(hlines)
local auth_line = get_http_header_value('Authorization', hlines)
if auth_line == nil then return nil end
local parts = str_split(auth_line)
if #parts == 2 and parts[1]:lower() == 'basic' then
local key = parts[2]
parts = nil
local ok
local decoded_key
ok, decoded_key = pcall(encoder.fromBase64, key)
key = nil
if ok then
parts = str_split(decoded_key, ':')
decoded_key = nil
if #parts == 2 then
return {
user = parts[1],
pwd = parts[2]
}
end
end
end
return nil
end
local function parse_http_header(request, params)
local options = {
parse_auth = false
}
if params ~= nil then
if params.parse_auth ~= nil then options.parse_auth = params.parse_auth end
end
local hlines = str_split(request, "\r\n")
if #hlines > 0 then
local hline1_parts = str_split(hlines[1])
if #hline1_parts == 3 and hline1_parts[3] == 'HTTP/1.1' then
local result = {
method = hline1_parts[1],
path = hline1_parts[2],
std = hline1_parts[3]
}
hline1_parts = nil
result.content_length = get_http_header_value('Content-Length', hlines)
if options.parse_auth then
result.auth = get_auth_from_http_header(hlines)
end
hlines = nil
if result.content_length ~= nil then
result.content_length = tonumber(result.content_length)
end
return result
end
end
return nil
end
-- Extends one level only
local function extend(tbl, with)
if with ~= nil then
for k, v in pairs(with) do
if tbl[k] == nil then
tbl[k] = with[k]
end
end
end
return tbl
end
Api32.create = function(conf)
local self = extend({
http_body_min = 10,
http_body_max = 512,
port = 80,
auth = nil
}, conf)
local endpoints = {}
self.on = function(method, path, handler)
table.insert(endpoints, {
method = method,
path = path,
handler = handler
})
return self
end
self.on_get = function(path, handler)
return self.on('GET', path, handler)
end
self.on_post = function(path, handler)
return self.on('POST', path, handler)
end
local get_endpoint = function(method, path)
for _, ep in pairs(endpoints) do
if ep.method == method and ep.path == path then return ep end
end
return nil
end
local srv = net.createServer(net.TCP, 30)
local sending = false
local http_header = nil
local http_req_body_buffer = nil
local function stop_rec()
sending = false
http_header = nil
http_req_body_buffer = nil
end
local is_authorized = function()
return self.auth == nil or (
http_header ~= nil
and http_header.auth ~= nil
and self.auth.user == http_header.auth.user
and self.auth.pwd == http_header.auth.pwd
)
end
local function parse_http_request(sck)
local res = {}
local stream_file = nil
local send = function(_sck)
sending = true
local close_socket = false
if #res > 0 then
_sck:send(table.remove(res, 1))
elseif stream_file ~= nil then
local line = stream_file:readline()
if line ~= nil then
_sck:send(line)
else
stream_file:close()
stream_file = nil
close_socket = true
end
else
close_socket = true
end
if close_socket then
sending = false
_sck:close()
res = nil
end
end
sck:on('sent', send)
local response_status = '200 OK'
local content_type = 'application/json'
local response_body = nil
res[1] = 'HTTP/1.1 '
res[2] = 'Content-Type: CTYPE; charset=UTF-8\r\n'
if http_header == nil then
response_status = '400 Bad Request'
else
if not is_authorized() then
response_status = '401 Unauthorized'
res[#res + 1] = 'WWW-Authenticate: Basic realm="User Visible Realm", charset="UTF-8"\r\n'
else
local ep = get_endpoint(http_header.method, http_header.path)
if ep == nil then
response_status = '404 Not Found'
else
http_header = nil
if type(ep.handler) == 'function' then -- custom handler
local jreq = json_parse(http_req_body_buffer)
http_req_body_buffer = nil
local jres = ep.handler(jreq)
jreq = nil
response_body = json_stringify(jres)
jres = nil
elseif type(ep.handler) == 'string' then -- static file
-- ep.handler is filename in this case
http_req_body_buffer = nil
if not file.exists(ep.handler) then
response_status = '404 Not Found'
else
if str_ends_with(ep.handler, 'html') then
content_type = 'text/html'
end
stream_file = file.open(ep.handler)
end
end
end
end
end
res[1] = res[1] .. response_status .. "\r\n"
res[2] = res[2]:gsub('CTYPE', content_type)
res[#res + 1] = "\r\n"
if response_body ~= nil then
res[#res + 1] = response_body
response_body = nil
end
stop_rec()
send(sck)
end
local on_receive = function(sck, data)
if sending then return end
if http_header == nil then
local eof_head = data:find("\r\n\r\n")
local head_data = nil
if eof_head ~= nil then
head_data = data:sub(1, eof_head - 1)
http_req_body_buffer = data:sub(eof_head + 4)
end
data = nil
if head_data ~= nil then
http_header = parse_http_header(head_data, {
parse_auth = self.auth ~= nil
})
head_data = nil
end
if http_header ~= nil then
if http_header.content_length == nil
or http_header.content_length < self.http_body_min
or http_header.content_length > self.http_body_max then
-- It seems like request body is too short, too big or does not exist at all.
-- Parse request immediatelly
return parse_http_request(sck)
end
else
-- Received some data which does not represent the http header.
-- Let's parse it anyway because error 400 shoud be sent back to the client
return parse_http_request(sck)
end
end
if data ~= nil and http_header ~= nil then
-- Buffering request body
if http_req_body_buffer == nil then
http_req_body_buffer = data
else
http_req_body_buffer = http_req_body_buffer .. data
end
end
-- Check if body has received
if http_req_body_buffer ~= nil then
local http_body_len = http_req_body_buffer:len()
if (http_header.content_length ~= nil and http_body_len >= http_header.content_length)
or http_body_len >= self.http_body_max then
-- Received enough bytes of request body.
return parse_http_request(sck)
end
end
end
srv:listen(self.port, function(conn)
stop_rec()
conn:on('receive', on_receive)
conn:on('disconnection', stop_rec)
end)
return self
end
return Api32
and another module api32local
local M = {}
_G[moduleName] = M
if api == nil then
api = require('api32')
.create()
.on_get('/', function() return{message = 'Welcome to the API32!'} end)
.on_post("/house_lamp",function(jreq,raw_data)
if jreq==nil or raw_data==nil then return end
gpio.write(BLUE_LED, jreq.state)
print("led Post Command")
return{"lamp_status updated"}
end)
end
return M
for wifi
wifi.mode(wifi.SOFTAP)
cfg={}
cfg.ip='192.168.0.10'
cfg.netmask='255.255.255.0'
cfg.gateway='192.168.0.1'
cfg.dns='8.8.8.8'
wifi.ap.setip(cfg)
wifi.ap.config({
ssid = "****",
pwd = "*123456#",
auth=wifi.AUTH_OPEN,
auto = false
})
Myapi32_init=require'api32local'
wifi.ap.on("sta_connected", function(event, info) Myapi32_init.init_api32() print("MAC_id"..info.mac,"Name"..info.id) end)
wifi.start()
please help me debugging issue. Can't able to understand where to use cross origin headers and how, and about preflight concept which are importent for angular based android app to communicate locally(without internet) through http with ESP32

Related

attempt to call a nil value (field 'Draw3DText')

i have this "function" in cl_main.lua:
Citizen.CreateThread(function()
for i = 1, #Config.SpecialStores do
local Blip = AddBlipForCoord(Config.SpecialStores[i].Coords);
SetBlipSprite (Blip, Config.SpecialStores[i].Blip[1]);
SetBlipDisplay(Blip, 4);
SetBlipScale (Blip, Config.SpecialStores[i].Blip[3]);
SetBlipColour (Blip, Config.SpecialStores[i].Blip[2]);
SetBlipAsShortRange(Blip, true);
BeginTextCommandSetBlipName('STRING');
AddTextComponentString(Config.SpecialStores[i].Label);
EndTextCommandSetBlipName(Blip)
end
while true do
local sleepThread, Player = 1500, PlayerPedId();
while not Stores.Interiors do
Citizen.Wait(100)
end
if (GetInteriorFromEntity(Player) ~= 0) then
for _, Data in pairs(Stores.Interiors) do
if (GetInteriorFromEntity(Player) == Data.InteriorId) then
sleepThread = 5;
local Dst = #(GetEntityCoords(Player) - Data.Checkout);
if Dst < 15.0 then
Utils.Draw3DText(Data.Checkout,'~g~E~w~ ');
if Dst < 1.0 and IsControlJustReleased(0, 38) then
Stores.OpenStore()
end
end
if IsPedArmed(Player, 7) and Data.Robbable then
if IsPlayerFreeAiming(PlayerId()) then
local Retval, Entity = GetEntityPlayerIsFreeAimingAt(PlayerId());
if Retval and GetEntityModel(Entity) == GetHashKey('mp_m_shopkeep_01') then
Stores.StartRobbing({
InteriorId = Data.InteriorId,
Cashier = Entity
})
end
else
local Retval, Entity = GetPlayerTargetEntity(PlayerId());
if Retval and GetEntityModel(Entity) == GetHashKey('mp_m_shopkeep_01') then
Stores.StartRobbing({
InteriorId = Data.InteriorId,
Cashier = Entity
})
end
end
end
end
end
end
And then i get back in f8 "attempt to call a nil value (field 'Draw3DText')"
I have tried to make on the top like "Utils = {}" since i understand ish that its the "utils" that return a nil. Does someone know how to fix this?

Not iterating contacts through ipairs properly

I have got the following code:
local Enemy = Enemy
local g = {}
local contactList = {}
local groupChats = {L"Solo", L"Party", L"Warband"}
local chatPrefix = {L"/s", L"/p", L"/wb"}
local function getGroupType()
if (IsWarBandActive()) then
return 3
end
if (GetNumGroupmates() > 0) then
return 2
end
return 1
end
local function getChatPrefix()
local gtype = getGroupType()
return chatPrefix[gtype]
end
local function getChatType()
local gtype = getGroupType()
return groupChats[gtype]
end
local function getGroupNames()
local names = {}
local group = GetGroupData()
for _, member in ipairs(group) do
if (member.name ~= nil) then
names[#names+1] = member.name
end
end
return names
end
local function getWarbandNames()
local names = {}
local warband = GetBattlegroupMemberData()
for _, party in ipairs(warband) do
for a = 1, 6 do
if (party.players[a] ~= nil) then
if (party.players[a].name ~= Enemy.playerName) then
names[#names+1] = party.players[a].name
end
end
end
end
return names
end
function Enemy.getChatPrefix()
return getChatPrefix()
end
function Enemy.IntercomInitialize ()
Enemy.intercom = g
g.queue = {}
RegisterEventHandler(SystemData.Events.BATTLEGROUP_UPDATED, "Enemy.intercomGroupUpdated")
RegisterEventHandler(SystemData.Events.GROUP_UPDATED, "Enemy.intercomGroupUpdated")
RegisterEventHandler (SystemData.Events.GROUP_PLAYER_ADDED, "Enemy.intercomGroupUpdated")
-- events
Enemy.AddEventHandler ("Intercom", "ChatTextArrived", Enemy.Intercom_OnChatTextArrived)
Enemy.AddEventHandler ("Intercom", "BroadcastMessageAsk", Enemy.Intercom_OnBroadcastMessageAsk)
Enemy.AddEventHandler ("Intercom", "BroadcastMessageInvite", Enemy.Intercom_OnBroadcastMessageInvite)
if (Enemy.CanSendIntercomMessage ()) then
--table.insert (data, L"You're currently in '"..g.name..L"' intercom channel with subId: '"..g.subId..L"'")
table.insert (data, L"You're currently in intercom channel: '"..g.subId..L"'")
else
table.insert (data, L"You're currently not in any intercom channel.")
end
table.insert (data, L"Left-click to open intercom channel dialog.")
end )
Enemy.TriggerEvent ("IntercomInitialized")
end
function Enemy.intercomGroupUpdated()
local gtype = getGroupType()
--d(gtype)
contactList = {}
if (gtype == 2) then
contactList = getGroupNames()
elseif (gtype == 3) then
contactList = getWarbandNames()
end
--d(contactList)
end
function Enemy.Intercom_OnChatTextArrived (t, from, text)
local data = Enemy.Split(towstring(text), L":")
if (text:find(L"EnemyAddon")) then
local commandFlag = true
-- .alert someone Scatterpack:Scatterpack:EnemyAddon:Mark:Neborhest Bat:N:474:
-- address from :subId :EnemyAddon:command
if (text:find(L":Ask:")) then
Enemy.Intercom_OnBroadcastMessageAsk (data[2], data[1])
end
if (text:find(L":Invite:")) then
Enemy.Intercom_OnBroadcastMessageInvite(L"", data[1], data[2])
end
if (data[2] == g.subId) then
Enemy.TriggerEvent ("IntercomMessage"..Enemy.toString (data[4]), data[2], unpack (data, 5))
end
end
end
function Enemy.IntercomJoin (name, pChannel)
g.name = pChannel
g.subId = name
g.isReady = true
Enemy.UI_Icon_Switch (true)
--Enemy.JoinChannel (g.name, function (name, channel, channelId)
--[[
Enemy.JoinChannel (name, function (name, channel, channelId)
g.channel = channel
g.channelId = channelId
g.isReady = true
Enemy.UI_Icon_Switch (true)
end)
]]--
end
function Enemy.CanSendIntercomMessage ()
return (g.isReady == true)
end
function Enemy.IntercomSendMessage (key, text)
if (not Enemy.CanSendIntercomMessage ()) then return end
g.queue[key] =
{
key = key,
text = text,
t = Enemy.time
}
local task_name = "intercom "..Enemy.toString (key)
if (Enemy.GetTask (task_name) ~= nil) then return end
Enemy.AddTaskAction (task_name, function ()
local q = g.queue[key]
-- abort if intercom not ready
if (q == nil or not Enemy.CanSendIntercomMessage ()) then return true end
-- wait if can't send chat message
if (not Enemy.CanSendChatMessage ()) then return false end
-- sending
local text = q.text
local sendText = L""
if (type (text) == "function") then text = text () end
local gtype = getGroupType()
local data = Enemy.Split(text, L":")
if (data[2] == L"Mark") then
Enemy.TriggerEvent ("IntercomMessage"..Enemy.toString(data[2]), Enemy.playerName, unpack (data, 3))
end
--local testText = L".alert !someContact! "..Enemy.playerName..L":"..Enemy.toWString(g.subId)..L":"..Enemy.toWString (text)
--d(testText)
if (getGroupType() ~= 1) then
for index, contact in ipairs(contactList) do
sendText = L".alert "..Enemy.toWString(contact)..L" "..Enemy.playerName..L":"..Enemy.toWString(g.subId)..L":"..Enemy.toWString (text)
SendChatText (sendText, L"")
--d(sendText)
end
end
g.queue[key] = nil
return true
end)
end
My problem is at the very bottom of the code in
for index, contact in ipairs(contactList) do
sendText = L".alert "..Enemy.toWString(contact)..L" "..Enemy.playerName..L":"..Enemy.toWString(g.subId)..L":"..Enemy.toWString (text)
SendChatText (sendText, L"")
where contactList doesn't seem to get iterated through properly.
On issuing relevant command the message is sent properly, but only to one other person in the group instead of sending it to everyone one-by-one.
Person 1 in group sends message to person 2 only
Person 2 to person 1 only
Person 3 to person 1 only
Expected behavior is message is sent in order to contact[1],contact[2] etc.
I'm a bit lost as to why and I've tried throttling the messages as I thought maybe that's why it only sends to one, but that does not seem to be the case.

Lua self method call attempt (a nil value)

I wrote a small class to receive data over TCP, but periodically (not constantly, sometimes the script runs long enough and receives data) I get an error:
.\modules\tcp.lua:83: attempt to call method '_parsing' (a nil value)
I can't figure out why the object loses the method that it had in the self and which worked. When creating the class I am using the module https://github.com/kikito/middleclass
After creating an object, I call in while loop:
feed:receive()
Class sample
os.setlocale("C")
package.path = package.path .. ";./libs/?.lua";
package.path = package.path .. ";./libs/luasocket/lua/?.lua";
package.cpath = package.cpath .. ";./libs/luasocket/?.dll";
package.cpath = package.cpath .. ";./libs/luasocket/mime/?.dll";
package.cpath = package.cpath .. ";./libs/luasocket/socket/?.dll";
local class = require "middleclass";
local socket = require "socket";
local struct = require "struct";
local msgpack = require "msgpack";
local type = type
local table = table
local string = string
local TCP = class("TCP")
function TCP:initialize(address, port, logger, onOpen, onClose, onMessages)
self.address = address
self.port = port
self.logger = logger
self.onOpen = onOpen
self.onClose = onClose
self.onMessages = onMessages
self.socket = nil
self.connected = false
self.seq_in = 0
self.chunk_in = ""
self.seq_out = 0
self.chunk_out = ""
end
function TCP:_connection_made()
if not self.socket then
self.socket = socket.tcp()
local status, _ = self.socket:connect(self.address, self.port)
if status then
self.socket:setoption("reuseaddr", true)
self.socket:setoption("tcp-nodelay", true)
self.socket:setoption("keepalive", true)
self.socket:settimeout(0)
self.logger:info("Connection open "..self.address..":"..self.port.."")
self.connected = true
if self.onOpen then
self.onOpen()
end
else
self.socket = nil
end
end
end
function TCP:_connection_close()
self.logger:info("Connection close "..self.address..":"..self.port.."")
self.socket = nil
self.connected = false
self.seq_in = 0
self.chunk_in = ""
self.seq_out = 0
self.chunk_out = ""
if self.onClose then
self.onClose()
end
end
function TCP:_receive()
local data, error, partial = self.socket:receive("*a")
if (not data) and (error ~= "timeout") then
self.logger:error("Connection error "..error)
self:_connection_close()
return nil, error
end
data = data or partial
if not data then
return nil, error
else
return self:_parsing(data)
end
end;
function TCP:_parsing(data)
local messages = {}
if self.chunk_in ~= "" then
data = self.chunk_in..data
self.chunk_in = ""
end
while string.len(data) ~= 0 do
if string.len(data) >= 10 then
local size, seq = struct.unpack("<HL", data)
if string.len(data) >= size + 10 then
if seq ~= self.seq_in + 1 then
self.logger:warn("Connection expected seq: "..(self.seq_in + 1)..", received seq: "..seq)
end
self.seq_in = seq
local msg = msgpack.unpack(string.sub(data, 11, 10 + size))
data = string.sub(data, 11 + size)
table.insert(messages, msg)
else
self.chunk_in = self.chunk_in..data
data = ""
end
else
self.chunk_in = self.chunk_in..data
data = ""
end
end
if self.onMessages then
self.onMessages(messages)
else
return messages, ""
end
end;
function TCP:_send(msg)
self.logger:debug("Try to send message", msg)
if type(msg) == "table" then
local data = msgpack.pack(msg)
self.seq_out = self.seq_out + 1
local frame = struct.pack("<HL", string.len(data), self.seq_out)
local index, error = self.socket:send(frame..data)
if error then
self.logger:error("Connection send error "..error)
if error == "closed" then
self:_connection_close()
end
end
end
end
function TCP:open()
if not self.connected then
self:_connection_made()
end
end
function TCP:close()
if self.connected then
self:_connection_close()
end
end
function TCP:receive()
if not self.connected then
self:_connection_made()
else
return self:_receive()
end
end
function TCP:send(msg)
if not self.connected then
return nil
else
return self:_send(msg)
end
end
return TCP

Trying to build a Discord bot with Discordia and Lua hasRole() crashes it

So I got my bot working with hasRole() but I added a music playing functionality to it and now every time I call hasRole() it returns nil and crashes the bot. It uses it in the kick, ban, and unban commands. I have no clue what is happening. Anyways here's the error I'm getting:
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>
And here is my bot script:
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())
Anyways thanks guys. I don't really know what is happening and it's very frustrating. Any help would be appreciated.
You can try to replace member:hasRole(modid) with the permission variant (aka message.member:hasPermission(...))
I would suggest reading about that function before trying anything tho, as i am no professional at discordia myself ;)
Useful links:
Lua documentation:
https://github.com/SinisterRectus/Discordia/wiki/
Discordia wiki on member class:
https://github.com/SinisterRectus/Discordia/wiki/Member
All permision's enums: https://github.com/SinisterRectus/Discordia/wiki/Enumerations#permission

Lua: attempt to index local '' (a nil value)

Please help: I am attempting to index local firstClipArr (a nil value) but I cannot figure out how to solve it for the life of me. Here's the code:
function updateRemoteAmmo( ammoTable )
if not client or getElementData(client,"loggedin") ~= 1 then
return
end
local items = getItems( client )
local weaponCheck = { }
for _, itemCheck in ipairs( items ) do
if (itemCheck[1] == 115) then -- Weapon item
local weaponItemDetails = explode(':', itemCheck[2])
local weaponAmmoCountValid = 0
local firstClip = 0
local firstClipInventorySlot = 0
local firstClipArr = nil
for itemCheckBulletsSlot, itemCheckBullets in ipairs( items ) do
if (itemCheckBullets[1] == 116) then
local weaponBulletDetails = explode(':', itemCheckBullets[2])
if tonumber(weaponBulletDetails[1]) == tonumber(weaponItemDetails[1]) then
if (firstClip == 0 and tonumber(weaponBulletDetails[2]) > 0) then
firstClip = tonumber(weaponBulletDetails[2])
firstClipInventorySlot = itemCheckBulletsSlot
firstClipArr = weaponBulletDetails
end
weaponAmmoCountValid = weaponAmmoCountValid + weaponBulletDetails[2]
end
end
end
local weaponSyncPacket = false
for _, tableValue in ipairs(ammoTable) do
if tonumber(tableValue[1]) == tonumber(weaponItemDetails[1]) then
weaponSyncPacket = tableValue
end
end
if not weaponSyncPacket then
return
end
local fakebullet = false
if (getElementData(client, "cf:"..weaponItemDetails[1])) then
fakebullet = true
weaponAmmoCountValid = weaponAmmoCountValid + 1
end
if (weaponAmmoCountValid > weaponSyncPacket[2]) then -- There has been shot with this gun
local totalBulletsShot = weaponAmmoCountValid - weaponSyncPacket[2]
local update = updateItemValue(client, firstClipInventorySlot,firstClipArr[1] ..":"..weaponSyncPacket[3] ..":".. firstClipArr[3])
if not update then
outputDebugString("fail")
end
weaponAmmoCountValid = weaponAmmoCountValid - totalBulletsShot
end
table.insert(weaponCheck, {weaponItemDetails[1], weaponAmmoCountValid, fakebullet} )
end
end

Resources