Not returning correct value - lua

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

Related

Setting multiplication operator through metatable in specific environment in Lua

local names = setmetatable({},
{__mul = function(a,b) return a|b end}
)
names={i=0,j=1}
tr=load("return i*j",nil,"t",names)()
print(tr)
It prints tr as 0. The expected answer is 1 as 0|1 results to 1. Where is the code wrong?
Try:
local mt_obj = {
__tostring = function(o) return tostring(o[1]) end,
}
local function get(o)
if type(o) == "table" then return o[1] else return o end
end
local function new(v)
return setmetatable({v}, mt_obj)
end
function mt_obj.__mul(a,b)
return new(get(a)|get(b))
end
local mt_env = {
__index = function(t,k) return new(t.variables[k]) end,
__newindex = function(t,k,v) t.variables[k] = v end,
}
local names = {i=0,j=1}
local env = setmetatable({variables = names}, mt_env)
tr=get(load("return i*j*8",nil,"t",env)())
print(tr)

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.

How to implement the exercise 15.5 in pil4?

I am working on this exercise in pil4.
Exercise 15.5:
The approach of avoiding constructors when saving tables with cycles is too radical. It is
possible to save the table in a more pleasant format using constructors for the simple case, and to use
assignments later only to fix sharing and loops. Reimplement the function save (Figure 15.3, “Saving
tables with cycles”) using this approach. Add to it all the goodies that you have implemented in the previous
exercises (indentation, record syntax, and list syntax).
I have tried this with the code below, but it seems not to work on the nested table with a string key.
local function basicSerialize(o)
-- number or string
return string.format("%q",o)
end
local function save(name,value,saved,indentation,isArray)
indentation = indentation or 0
saved = saved or {}
local t = type(value)
local space = string.rep(" ",indentation + 2)
local space2 = string.rep(" ",indentation + 4)
if not isArray then io.write(name," = ") end
if t == "number" or t == "string" or t == "boolean" or t == "nil" then
io.write(basicSerialize(value),"\n")
elseif t == "table" then
if saved[value] then
io.write(saved[value],"\n")
else
if #value > 0 then
if indentation > 0 then io.write(space) end
io.write("{\n")
end
local indexes = {}
for i = 1,#value do
if type(value[i]) ~= "table" then
io.write(space2)
io.write(basicSerialize(value[i]))
else
local fname = string.format("%s[%s]",name,i)
save(fname,value[i],saved,indentation + 2,true)
end
io.write(",\n")
indexes[i] = true
end
if #value > 0 then
if indentation > 0 then io.write(space) end
io.write("}\n")
else
io.write("{}\n")
end
saved[value] = name
for k,v in pairs(value) do
if not indexes[k] then
k = basicSerialize(k)
local fname = string.format("%s[%s]",name,k)
save(fname,v,saved,indentation + 2)
io.write("\n")
end
end
end
else
error("cannot save a " .. t)
end
end
local a = { 1,2,3, {"one","Two"} ,5, {4,b = 4,5,6} ,a = "ddd"}
local b = { k = a[4]}
local t = {}
save("a",a,t)
save("b",b,t)
print()
And I got the wrong ouput.
a = {
1,
2,
3,
{
"one",
"Two",
}
,
5,
{
4,
5,
6,
}
a[6]["b"] = 4
,
}
a["a"] = "ddd"
b = {}
b["k"] = a[4]
How could I make the text ' a[6]["b"] = 4 ' jump out of the table constructor?

lua variable name from user input

I am trying to make a "shell" in lua.
But the main problem is, I can not define the variable name from user input.
Here is the core of what I currently have. I am having an issue with the what[2] = what[3] line with the comment below.
How can I better implement this?
function lsplit(inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
t[i] = str
i = i + 1
end
return t
end
function def(what)
if (what[1] == "end") then
os.exit(0)
elseif (what[1] == "help") then
print("Commander version 0.0")
elseif (what[1] == "var") then
what[2] = what[3] --Can not define
else
print("[ERR] not a command!")
end
end
while(true) do
io.write("-->")
local usr = io.read("*l")
local cmd = lsplit(usr, " ")
def(cmd)
end
you are overwriting you first parameter with you second one, and not creating a new var... try this code! Should work but it is untested!
local userdefinedVars = { }
function lsplit(inputstr)
words = {}
for word in s:gmatch("%w+") do
table.insert(words, word)
end
end
function def(what)
if (what[1] == "end") then
os.exit(0)
elseif (what[1] == "help") then
print("Commander version 0.0")
elseif (what[1] == "var") then
-- This is how you get your things done!
userdefinedVars[what[2]] = what[3]
else
print("[ERR] not a command!")
end
end
while(true) do
io.write("--> ")
local usr = io.read("*line")
local cmd = lsplit(usr)
def(cmd)
end

Resources