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?
Related
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
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
I tried to fix some Garry's Mod addon and this is what happens. I tried to fix it for long time, but I'm not the best in Lua coding :/ . What is wrong with this code? I get this error:
[ERROR] addons/garrys_bombs_5_base_528449144/lua/entities/gb5_shockwave_sound_lowsh.lua:80: bad argument #1 to 'SetPhysicsAttacker' (Entity expected, got nil)
1. SetPhysicsAttacker - [C]:-1
2. unknown - addons/garrys_bombs_5_base_528449144/lua/entities/gb5_shockwave_sound_lowsh.lua:80
And the code is pretty long. I have every file working fine, but this file is not working
AddCSLuaFile()
DEFINE_BASECLASS( "base_anim" )
if (SERVER) then
util.AddNetworkString( "gb5_net_sound_lowsh" )
end
ENT.Spawnable = false
ENT.AdminSpawnable = false
ENT.PrintName = ""
ENT.Author = ""
ENT.Contact = ""
ENT.GBOWNER = nil
ENT.MAX_RANGE = 0
ENT.SHOCKWAVE_INCREMENT = 0
ENT.DELAY = 0
ENT.SOUND = ""
net.Receive( "gb5_net_sound_lowsh", function( len, pl )
local sound = net.ReadString()
LocalPlayer():EmitSound(sound)
end );
function ENT:Initialize()
if (SERVER) then
self.FILTER = {}
self:SetModel("models/props_junk/watermelon01_chunk02c.mdl")
self:SetSolid( SOLID_NONE )
self:SetMoveType( MOVETYPE_NONE )
self:SetUseType( ONOFF_USE )
self.Bursts = 0
self.CURRENTRANGE = 0
self.GBOWNER = self:GetVar("GBOWNER")
self.SOUND = self:GetVar("SOUND")
end
end
function ENT:Think()
if (SERVER) then
if not self:IsValid() then return end
local pos = self:GetPos()
self.CURRENTRANGE = self.CURRENTRANGE+(self.SHOCKWAVE_INCREMENT*10)
if(GetConVar("gb5_realistic_sound"):GetInt() >= 1) then
for k, v in pairs(ents.FindInSphere(pos,self.CURRENTRANGE)) do
if v:IsPlayer() then
if not (table.HasValue(self.FILTER,v)) then
net.Start("gb5_net_sound_lowsh")
net.WriteString(self.SOUND)
net.Send(v)
v:SetNWString("sound", self.SOUND)
if self:GetVar("Shocktime") == nil then
self.shocktime = 1
else
self.shocktime = self:GetVar("Shocktime")
end
if GetConVar("gb5_sound_shake"):GetInt()== 1 then
util.ScreenShake( v:GetPos(), 5555, 555, self.shocktime, 500 )
end
table.insert(self.FILTER, v)
end
end
end
else
if self:GetVar("Shocktime") == nil then
self.shocktime = 1
else
self.shocktime = self:GetVar("Shocktime")
end
local ent = ents.Create("gb5_shockwave_sound_instant")
ent:SetPos( pos )
ent:Spawn()
ent:Activate()
ent:SetPhysicsAttacker(ply)
ent:SetVar("GBOWNER", self.GBOWNER)
ent:SetVar("MAX_RANGE",50000)
ent:SetVar("DELAY",0.01)
ent:SetVar("Shocktime",self.shocktime)
ent:SetVar("SOUND", self:GetVar("SOUND"))
self:Remove()
end
self.Bursts = self.Bursts + 1
if (self.CURRENTRANGE >= self.MAX_RANGE) then
self:Remove()
end
self:NextThink(CurTime() + (self.DELAY*10))
return true
end
end
function ENT:OnRemove()
if SERVER then
if self.FILTER==nil then return end
for k, v in pairs(self.FILTER) do
if not v:IsValid() then return end
v:SetNWBool("waiting", true)
end
end
end
function ENT:Draw()
return false
end
Is there a chance someone fix this for me? Or even just telling me what's wrong? I would be pleased. If needed I can send all files. Well... It's not my addon but I'm trying to fix an existing one. Someone tried to fix it too but he didn't (actually he broke it even more).
What the error means
Inside your ENT:Think() function, you are calling ent:SetPhysicsAttacker(ply)
ply is not defined anywhere inside that function, so is nil (Entity expected, got nil)
How to fix this
If no player is responsible for the damage caused by this entity, delete the line ent:SetPhysicsAttacker(ply).
Otherwise, assign an Owner to the entity at the point of creation, using SetOwner.
This would then allow you to use self:GetOwner() inside your Think hook
Example
hook.Add("PlayerSay", "SpawnEntity", function(ply, text)
if string.lower(text) == "!spawnentity" then
-- Create your entity
local myEntity = ents.Create("gb5_shockwave_sound_lowsh")
myEntity:SetPos(ply:GetPos())
myEntity:SetAngles(ply:GetAngles())
myEntity:Spawn()
-- Sets the owner to the player that typed the command
myEntity:SetOwner(ply)
return ""
end
end)
-- Inside your entity code
function ENT:Think()
print("My owner is: " .. tostring(self:GetOwner()))
-- ...
ent:SetPhysicsAttacker(self:GetOwner())
end
Hello I have 2 functions one to return a value
function AddPlayer(steamID, source)
for i,p in ipairs(players) do
if steamID == p[1] then
players[i] = {p[1], p[2], source}
return
end
end
local initialPoints = GetInitialPoints(steamID)
print(initialPoints)
table.insert(players, {steamID, initialPoints, source})
end
function GetInitialPoints(steamID)
local points = 0
print(steamID)
MySQL.Async.fetchAll("Select priority FROM queue where `identifier`= #identifier",
{
['#identifier'] = steamID,
},
function(resp)
points = resp[1].priority
print(points)
end)
return points
end
so the print actually prints the correct value (10,000)
but in the return on function AddPlayer where I print the initial points it is printing 0 which is what I set the variable when declared. When it needs to be printing what I set points to.
function AddPlayer(steamID, source)
for i,p in ipairs(players) do
if steamID == p[1] then
players[i] = {p[1], p[2], source}
return
end
end
print(steamID)
MySQL.Async.fetchAll(
"Select priority FROM queue where `identifier`= #identifier",
{
['#identifier'] = steamID,
},
function(resp)
local initialPoints = resp[1].priority
print(initialPoints)
table.insert(players, {steamID, initialPoints, source})
end
)
end
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