Jump to content

Tables


Karoffe

Recommended Posts

Well, i wanted to practice more about tables, i understand everything but, idk what's wrong in here, i have seen many examples on how to do it but still nothing works... What i am doing in the script is that i am trying to get all the resources exists in the server copying them in another table, and use the table in the client side script and output it in the chat...

local serverResources = {} 
function ress(resources) 
    serverResources = resources 
    for ke,resources in ipairs(serverResources) do 
    outputChatBox(""..serverResources.."") 
    end 
end 
addEvent("ResourcesTable", true) 
addEventHandler("ResourcesTable", root, ress) 
addCommandHandler("restest", ress) 

function resourcese() 
    local resources = {} 
    local res = getResources() 
    for k,resource in ipairs(res) do 
        if getResourceInfo(resource, "type") ~= map then 
        table.insert(resources,getResourceName(resource)) 
    end 
    triggerClientEvent(source,"ResourcesTable",getRootElement(),resources) 
end 
end 

Debug: Bad argument #1 to 'ipairs' (table expected, got string)

Link to comment
local serverResources = { "mta", "cows" } 
function ress( ) 
    for k,resources in ipairs(serverResources) do 
    outputChatBox(""..resources.."") 
    end 
end 
addEvent("ResourcesTable", true) 
addEventHandler("ResourcesTable", root, ress) 
addCommandHandler("restest", ress) 

Link to comment
  • Moderators
if getResourceInfo(resource, "type") ~= map then 

map is not defined, maybe did you want to write "map" instead ?

Also source isn't defined in the code you pasted here.

server:

function resourcese( thePlayer ) 
    local resources = {} 
    local res = getResources() 
    for k, resource in ipairs(res) do 
        if getResourceInfo(resource, "type") ~= "map" then 
            table.insert(resources, getResourceName(resource)) 
        end 
        -- here it's a good practice to not use getRootElement() as source (avoid it as much as you can) 
        triggerClientEvent(thePlayer, "ResourcesTable", thePlayer, resources) -- idk what was source in your script. 
    end 
end 
-- I put the command here and not on the client side so I can know who asked for the list without using an extra triggerServerEvent from the client side 
addCommandHandler("restest", resourcese) 

client:

local serverResources = {} 
function ress( resources ) 
    serverResources = resources 
    for k, resource in ipairs(serverResources) do -- why 'ke' ? 
        outputChatBox( resource ) -- no need to add empty strings before and after a string 
    end 
end 
addEvent("ResourcesTable", true) 
addEventHandler("ResourcesTable", root, ress) 

Link to comment
  • Moderators

No you didn't, he wanted to get the list of the resources which aren't of type maps on the client side.

Your code does nothing more that looping your hardcoded table.

I fixed his code (and you didn't) because I get the list of resources, get their name, store them in a table, send that table using triggerClientEvent and then receive that table on the client side.

So now he can use serverResources to do a panel an admin panel for example.

Link to comment

I think you meant this:

function resourcese() 
    local resources = {} 
    local res = getResources() 
    for k,resource in ipairs(res) do 
        local t = tostring ( getResourceInfo(resource, "type") ):lower ( ) 
        if ( t ~= "map" ) then 
            table.insert(resources,getResourceName(resource)) 
        end 
    end 
    triggerClientEvent(source,"ResourcesTable",getRootElement(),resources) 
end 

Link to comment
if getResourceInfo(resource, "type") ~= map then 

map is not defined, maybe did you want to write "map" instead ?

Also source isn't defined in the code you pasted here.

server:

function resourcese( thePlayer ) 
    local resources = {} 
    local res = getResources() 
    for k, resource in ipairs(res) do 
        if getResourceInfo(resource, "type") ~= "map" then 
            table.insert(resources, getResourceName(resource)) 
        end 
        -- here it's a good practice to not use getRootElement() as source (avoid it as much as you can) 
        triggerClientEvent(thePlayer, "ResourcesTable", thePlayer, resources) -- idk what was source in your script. 
    end 
end 
-- I put the command here and not on the client side so I can know who asked for the list without using an extra triggerServerEvent from the client side 
addCommandHandler("restest", resourcese) 

client:

local serverResources = {} 
function ress( resources ) 
    serverResources = resources 
    for k, resource in ipairs(serverResources) do -- why 'ke' ? 
        outputChatBox( resource ) -- no need to add empty strings before and after a string 
    end 
end 
addEvent("ResourcesTable", true) 
addEventHandler("ResourcesTable", root, ress) 

Really thanks. never expected the prob is comming from the triggering...(sorry for the late response wasn't at home ) I have another question..

I tried to do it this way.. cause i didn't know how to table.insert the resource name and the resource state

function resourcese( thePlayer ) 
    local resources = {} 
    local maps = {} 
    local rese = getResources() 
    for i=1, #rese do 
       if getResourceInfo(rese[i], "type") ~= "map" then 
        resources[i] = {getResourceName(rese[i]), getResourceState(rese[i])} 
        end 
        end 
        triggerClientEvent("ResourcesTable", getRootElement(), resources)  
end 

but it doesn't work by adding this line

       if getResourceInfo(rese[i], "type") ~= "map" then 
  

when i tried to remove this line it worked good.. but it includes the maps...

Link to comment
  • Moderators
cause i didn't know how to table.insert the resource name and the resource state
table.insert(resources, {name=getResourceName(resource), state=getResourceState(resource)}) 

So you can do it like this:

server:

function resources() 
    local resources = {} 
    local res = getResources() 
    for k, resource in ipairs(res) do 
        if getResourceInfo(resource, "type") ~= "map" then 
            table.insert(resources, {name=getResourceName(resource), state=getResourceState(resource)}) 
        end 
        triggerClientEvent("ResourcesTable", root, resources) 
    end 
end 

client:

local serverResources = {} 
function ress( resources ) 
    serverResources = resources 
    for k, resource in ipairs(serverResources) do 
        outputChatBox( "Name: "..resource.name..", State: "..tostring(resource.state) ) 
    end 
end 
addEvent("ResourcesTable", true) 
addEventHandler("ResourcesTable", root, ress) 

Link to comment

Sorry for double posting... I have another question

What if i want to get the state of a specific resource using the table(resources)..

will i have to prevent using table.insert ?

i actually tried to do it this way but it doesn't work...

table.insert(resources[resource].... 

Link to comment
  • Moderators

You say that you want to GET the resource state but you are pasting a code that tries to INSERT. In don't understand how you could end with that.

Based on this only sentence:

What if i want to get the state of a specific resource using the table(resources)..

Here is how to do it:

local state = resources[resource].state 

Link to comment
  • Moderators

Myeah lol my bad:

local resser = nil 
local resname = "admin" 
for k, res in ipairs (resources) do 
    if res.name == resname then 
        resser = res.state 
    end 
end 
if resser ~= nil then 
    outputChatBox(resser) 
else 
    outputChatBox("Resource "..resname.." not found in the table.") 
end 

Because we filled the table using table.insert and this functions make this table to use the number of the row as index.

If you want to use the resource element as index, we had to fill our table this way:

function resources() 
    local resources = {} 
    for k, resource in ipairs(getResources()) do 
        if getResourceInfo(resource, "type") ~= "map" then 
            resources[resource] = {name=getResourceName(resource), state=getResourceState(resource)}) 
        end 
        triggerClientEvent("ResourcesTable", root, resources) 
    end 
end 

Like this I explecitly use the resource element as index.

So now I can use this table like I wrote you in my previous post:

local resource = getResourceFromName ( "admin" ) 
local state = resources[resource].state 
outputChatBox(state) 

Sorry for the mistake

Link to comment
function RSgetinfo(resourcesinfo) 
    if guiGridListGetSelectedItem (RS_gridlist) ~= -1 then 
    local RSinfores = getResourceFromName(guiGridListGetItemText ( RS_gridlist, guiGridListGetSelectedItem ( RS_gridlist ), Rsnamecol )) 
    RSresourcesinfo = resourcesinfo 
    outputChatBox(RSresourcesinfo[RSinfores].author) --> That's the line which has the error 
    --local author = RSresourcesinfo[RSinfores].author 
    guiSetText(RSIauthor_lab, "Author: "..author.."") 
    --guiSetText(RSIfullname_lab, "Full name: "..fullnameRS.."") 
    --guiSetText(RSIversion_lab, "Version: "..versionRS.."") 
end 
end 

Actually it worked on server side.. but when i tried to apply it on client side.. it didn't work

Attempt to index field '?' ( a nil value )

Link to comment
  • Moderators

Seems like we can't because the elements aren't the same on the server and the client (which was pretty obvious but idk why I thought it would work). Basically the pointers aren't the same at all so we can't use the element as key for the index.

To make it work, I had to use the name of the resource instead:

function resources() 
    local resources = {} 
    for k, resource in ipairs(getResources()) do 
        if getResourceInfo(resource, "type") ~= "map" then 
            resources[getResourceName(resource)] = {state=getResourceState(resource)} 
        end 
    end 
end 

(I removed name from the datas because we don't need it twice. If you want to add the author, do it in the brackets where state is).

So on the client side, just use the resource name instead of the resource element:

resources["admin"].state --> "running" 

Link to comment

pff.... it did work on the server side script but in the client side it still doesn't work.. i don't really wanna give up with this code...

--Server Side 
local resourcesinfo = {} 
function GLresRS() 
    local resources = {} 
    local RSres = getResources() 
    for k, resource in ipairs(RSres) do 
        if getResourceInfo(resource, "type") ~= "map" then 
            table.insert(resources, {name=getResourceName(resource), state=getResourceState(resource)}) 
            resourcesinfo[getResourceName(resource)] = {author=getResourceInfo(resource ,"author"), version=getResourceInfo(resource, "version"), fullname=getResourceInfo(resource, "name")} 
        end 
        end 
        triggerClientEvent("ResourcesTable", getRootElement(), resources) 
        triggerClientEvent("RSgetinfo", getRootElement(), resourcesinfo) 
    end 

function RSgetinfo(resourcesinfo) 
    RSresourcesinfo = resourcesinfo 
    if guiGridListGetSelectedItem (RS_gridlist) ~= -1 then 
    local RSinfores = guiGridListGetItemText ( RS_gridlist, guiGridListGetSelectedItem ( RS_gridlist ), Rsnamecol ) 
    --outputChatBox(RSresourcesinfo[RSinfores].author) 
    --local author = RSresourcesinfo[RSinfores].author 
    guiSetText(RSIauthor_lab, "Author: "..RSresourcesinfo[RSinfores].author.."") -- > That's the line which has the error 
    --guiSetText(RSIfullname_lab, "Full name: "..fullnameRS.."") 
    --guiSetText(RSIversion_lab, "Version: "..versionRS.."") 
end 
end 
addEventHandler( "onClientGUIClick", RS_gridlist,RSgetinfo) 
addEvent("RSgetinfo", true) 
addEventHandler("RSgetinfo", root, RSgetinfo) 

Attempt to index field '?' ( a nil value )

Link to comment
  • Moderators

You are using the same function to update the client-side resource table to update your gui using onClientGUIClick which doesn't send the table as argument at all.

So you were basicaly replacing the table by the button ("left", "middle" or "right"), when you were clicking on your gridlist.

So please don't mix functions that don't take the same arguments or that doesn't do the same task.

Also stop renaming your functions and tables with weird names. And finally reduce the ammount of triggers to save bandwidth. To do that, use only one table that you will send on the client-side. The table on the client-side part must be global (like RSresourcesinfo is) so you can use that table whereever you would like on the client-side.

I let you update the server part to remove resources and use resourcesinfo only.

client:

RSresourcesinfo = {} 
function updateResourceInfos(resources) 
    RSresourcesinfo = resources 
end 
addEvent("RSgetinfo", true) 
addEventHandler("RSgetinfo", root, RSgetinfo) 
  
function RSGridlistClicked( button, state ) 
    if button ~= "left" and state ~= "up" then return end 
  
    if guiGridListGetSelectedItem (RS_gridlist) ~= -1 then 
        local RSinfores = guiGridListGetItemText ( RS_gridlist, guiGridListGetSelectedItem ( RS_gridlist ), Rsnamecol ) 
        guiSetText(RSIauthor_lab, "Author: "..RSresourcesinfo[RSinfores].author) -- > That's the line which has the error 
        --guiSetText(RSIfullname_lab, "Full name: "..fullnameRS.."") 
        --guiSetText(RSIversion_lab, "Version: "..versionRS.."") 
    end 
end 
addEventHandler( "onClientGUIClick", RS_gridlist, RSGridlistClicked) 

Don't forget to call GLresRS when you need to update the table on the client-side part.

Note: if that doesn't work, it's basically that RSinfores isn't a valid resource name.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...