I am trying to edit a script in LUA but I couldn't get access of a local defined in a function
LUA Code
function getSafeMoney()
local SafeMoney = nil
QBCore.Functions.ExecuteSql(false, 'SELECT * FROM `moneysafes` WHERE `safe` = "mechanic"', function(result)
SafeMoney = json.decode(json.encode(result[1])).money;
end)
return SafeMoney
end
print(getSafeMoney())
Result :
nil
here's the sql function as sysdevs asked
QBCore.Functions.ExecuteSql = function(wait, query, cb)
local rtndata = {}
local waiting = true
exports['ghmattimysql']:execute(query, {}, function(data)
if cb ~= nil and wait == false then
cb(data)
end
rtndata = data
waiting = false
end)
if wait then
while waiting do
Citizen.Wait(5)
end
if cb ~= nil and wait == true then
cb(rtndata)
end
end
return rtndata
end
Your second function is not holding the main function I assume, I am bad at lua aswell, but I think that changing
QBCore.Functions.ExecuteSql(false, ............
to
QBCore.Functions.ExecuteSql(true, ............
This will probably fix your problem, still your code is ambiguous and needs concentration if you could provide more information I might be able to help more
Related
I have tried to fix this script, but i cannot.
It is the primary script which maintains most server side stuff.
I tried to make an DataStore handler, but it returns nil.
Code:
local rep = game:GetService("ReplicatedStorage")
local DrawingData = game:GetService("DataStoreService"):GetDataStore("DrawingData")
rep.SendToRandom.OnServerEvent:Connect(function(plr,data)
end)
rep.LoadFromDatastore.OnServerInvoke = function(plr,...)
local success,gotten =pcall(DrawingData.SetAsync,DrawingData,...)
if not success then
gotten = {}
warn("Failure with DataStore get, replacing with placeholder.")
end
return gotten
end
rep.SaveToDatastore.OnServerInvoke =function(plr,data:string)
local a = {DrawingData:GetAsync("GM")}
local gotten = tonumber(a[1])
DrawingData:SetAsync(tostring(gotten + 1),data)
DrawingData:SetAsync("GM",tostring(gotten + 1))
return gotten + 1
end
Output:
Failure with DataStore get, replacing with placeholder.
Saving works, and loading should work.
But, loading doesn't.
Looks like you're using SetAsync and GetAsync without actual UserId to store it to, you should save and load the data to a UserId unless the data is meant to be accessed by everyone (which I do NOT recommend).
From what I can tell you are trying to save data for individual players, but you are storing their data or their data I suppose to a singular DataStore, which will only make it more difficult for the game to load once it is prompted to load again.
Here is what I wrote based on what I believe you are trying to accomplish
local rep = game:GetService("ReplicatedStorage")
local DrawingData = game:GetService("DataStoreService"):GetDataStore("DrawingData")
rep.LoadFromDatastore.OnServerInvoke = function(plr,...)
local success, response = pcall(function(...)
return DrawingData:SetAsync(plr.UserId, ...)
end, ...)
if success ~= true or type(response) ~= "table" or table.getn(response) == 0 then
return {}, type(response) == "string" and warn(response)
end
return response
end
rep.SaveToDatastore.OnServerInvoke =function(plr, data)
local success, response = pcall(function()
return DrawingData:GetAsync(plr.UserId)
end)
if success ~= true or type(response) ~= "table" or table.getn(response) == 0 then
response = {}
end
table.insert(response, data)
local success, response
while success ~= true do
success, response = pcall(function()
return DrawingData:SetAsync(plr.UserId, response)
end)
if success ~= true then
warn(response)
end
end
end
I'm trying to make a DB and I'm still in testing phrase, but it doesn't work.
Basically the error is, I want it so if I type: ModuleScript:GetDB("salvage").Set("key", "value"), it would return a value, but it doesn't due to an error.
Any help is highly appreciated.
Error:
Photo
Server Script:
local ModuleScript = require(game.ServerStorage.ModuleScript)
game.Players.PlayerAdded:Connect(function(p)
p.Chatted:Connect(function(msg)
if msg == "t" then
print("lol")
print(ModuleScript:GetDB("salvage"))
ModuleScript:GetDB("salvage").Set("key", "value")
end
end)
end)
Module script:
--Variables
local dss = game:GetService("DataStoreService")
-- Tables
local greenwich = {}
local dbFunctions = {}
--Functions
function greenwich:GetDB(name)
local db = dss:GetDataStore(name)
local new = {}
new.store = db
coroutine.resume(coroutine.create(function()
for k, v in ipairs(dbFunctions) do
new[k] = function(...)
local args = { ... }
v(new.store, unpack(args))
end
end
end))
print(new.store.Name, name)
return new
end
function dbFunctions:Set(store, key, value)
print(value)
return value
end
--Returning everything.
return greenwich
Thanks in advance.
ModuleScript:GetDB("salvage") returns new which does not have a field Set so you cannot call ModuleScript:GetDB("salvage").Set("key", "value)
Set is a field of dbFunctions. You run a generic for loop over it using the ipairs iterator. dbFunctions is not a seqence, hence ipairs does not work for it. Use pairs instead.
I'm writing a function for Nodemcu (esp8266) Lua to build command strings from UART (someone typing). When it finishes capturing characters, it's supposed to return the string to the calling function, but the calling function only gets nil. I'm new to Lua, What am I missing?
local function getcmd()
local t = { }
local cmd
-- Callback function
uart.on("data", 0, function(data)
if data~='\r' then
--Echo input
t[#t+1] = data
uart.write(0,t[#t])
-- BACKSPACE/DEL
if t[#t] == '' then
t[#t] = nil
t[#t] = nil
end
-- NEED <TAB> handling here too
else
--Disables callback
--uart.on("data")
-- Print table, convert to string.
for i = 1, #t do
uart.write(0, t[i])
if i==1 then
cmd = tostring(t[i])
else
cmd = cmd .. tostring(t[i])
end
end
t = { }
if cmd ~= nil then
uart.write(0, "Before Return> "..cmd)
-- type() String
return cmd
end
end
end,0)
end
local function config()
local cmdstr
-- Testing
cmdstr = getcmd()
print("func() "..getcmd())
if cmdstr ~= nil then
uart.write(0, cmdstr.."> ")
end
end
Thanks to #EgorSkriptunoff for helping me understand what was happening.
Below is the code that works (so far). What I tried was a While loop around the event handler inside of getcmd(). This fails because it stops execution of all the background events that keep things like wifi and other essential functions that keep the ESP8266 running, so it crashes/reboots repeatedly.
What I did instead of returning from getcmd() was call config() directly and pass it the input I collected in the event handler, like this: config(cmd)
The potential problem is, the event handler is still running since it never reached the end and that could cause some stack/memory issues if I don't return from config() before calling another function.
Anyway, here is the code that is working for the moment:
function getcmd()
local t = { }
cmd=nil
uart.on("data", 0, function(data)
if data~='\r' then
--Echo input
t[#t+1] = data
uart.write(0,t[#t])
-- BACKSPACE/DEL
if t[#t] == 'BS' then
t[#t] = nil
t[#t] = nil
end
else
--uart.on("data")
if #t ~= nil then
uart.write(0,"\r\n"..#t.."\r\n")
end
for i = 1, #t do
uart.write(0, t[i])
if i==1 then
cmd = tostring(t[i])
else
cmd = cmd .. tostring(t[i])
end
end
t = { }
if cmd ~= nil then
-- Calling config() here doesn't allow event handler on.uart() to end.
config(cmd)
end
end
end,0)
end
------------------------------------------------------
function config(cmd)
print("\r<<"..cmd..">>\r")
-- Now parse cmd and return.
end
I am trying to set up a toy example for threading in torch but I am getting an error from running the code below. I think it might just be the way I set up the table but I am not sure.
Threads = require 'threads'
Threads.serialization('threads.sharedserialize')
DataThreads = {}
DataThreads.__index = DataThreads
local result = {}
local unpack = unpack and unpack or table.unpack
function DataThreads.new(nThreads,opt_)
local self = {}
opt_ = opt_ or {}
self.threads = Threads(nThreads,
function()
print("background stuff")
end
)
self.threads:synchronize()
-- The below for loop is causing the error but the same :addjob() works later on
for i=1, nThreads do
self.threads:addjob(self._getFromThreads, self._pushResult)
end
return setmetatable(self,DataThreads)
end
function DataThreads._getFromThreads()
x,y = torch.uniform(),torch.uniform()
return x,y
end
function DataThreads._pushResult(...)
local res = {...}
if res == nil then
self.threads:synchronize()
end
result[1] = res
end
function DataThreads:getBatch()
self.threads:addjob(self._getFromThreads, self._pushResult)
self.threads:dojob()
local res = result[1]
result[1] = nil
if torch.type(res) == 'table' then
return unpack(res)
end
print(type(res))
return res
end
d = DataThreads.new(4)
The error occurs in :addjob() in the .new function. However calling the same :addjob() later on in the :getBatch() function works. Am I not allowed to call the ._getFromThreads(), ._getFromThreads() functions before the metatable is set? Here is the error, which I think means ._getFromThreads() is not returning anything;
/home/msmith/torch/install/bin/luajit: ...e/msmith/torch/install/share/lua/5.1/threads/threads.lua:215: function callback expected
stack traceback:
[C]: in function 'assert'
...e/msmith/torch/install/share/lua/5.1/threads/threads.lua:215: in function 'addjob'
threads.lua:21: in function 'new'
threads.lua:54: in main chunk
When the code in your new function runs the metatable hasn't been set up yet so when you use self._getFromThreads and self._pushResult there's nothing there and you get nil back and that's not valid.
It works after the new function returns because at that point the metatable has been added so the lookups use the __index metamethod to look the entries up.
You can do
local self = setmetatable({}, DataThreads)
to set the metatable up immediately and then just
return self
at the end.
I have a ComputerCraft program set to turn on a siren when any non-whitelisted players are near:
sensor = peripheral.wrap("top")
function arraysubset(a, b)
local s = set(b)
for _, el in pairs(a)
if not s[el] then
return false
end
end
return true
end
function sirenOn() rs.setBundledOutput("back",colors.blue) end
function sirenOff() rs.setBundledOutput("back",0) end
while 1 do
playersNear = sensor.getPlayerNames()
allowedPlayers = {"VirtualDXS","jettrom","Shad0wlurker16","Demonicmobster","FireFang0113","riggs135","DaisySnow123","MasterAlex930"}
if playersNear[1] ~= nil then
if arraysubset(playersNear,allowedPlayers) then sirenOff() else sirenOn() end
else sirenOff() end
end
However, on line 3 I get an attempt to call nil. This makes me think that the set() function is not present on computercraft. I'm wondering:
Is there another (maybe better) way to find if array a is a subset of array b and
If not where can I get an API with the set() function?
Rereading the source for the subset() code, I am seeing that the code I used required more code from earlier in the answer:
function set(list)
local t = {}
for _, item in pairs(list) do
t[item] = true
end
return t
end