Read table from file

Hey,

maybe someone read my other thread. This code worked fine (again thanks to the people (tried to) help/ed me) but now I want to make it a bit more “advanced” in a table.
The problem with a table was, if I use table.insert the thing I add is not really in this file so I use file.write.
I don’t know why but everytime I need to ask something I tell the story first and then I come to the questions :stuck_out_tongue:

1st: How do the SteamIDs need to be in the file that I can make it to a table by using this, haven’t found anything on the internet: local donator = file.Read(“donators.txt”, “DATA”)
Error using this at “for _, v in pairs(donator) do”: bad argument #1 to ‘pairs’ (table expected, got string)
2nd: Should I put something like this next time in the “Questions that don’t need an own thread” thread or is it OK if I do it like that?

Thanks in advance for the fast answering here and for the nice answers :slight_smile:
Regards,
Julian

When you save the table to the file, use util.TableToJSON( data );, when you read the file use util.JSONToTable( data || “{ }” );

Post your entire code, I have a feeling that it’s saved in JSON


function ulx.test2( calling_ply, target_plys )
	
	local donator = file.Read("donators.txt", "DATA")
	for _, v in ipairs( target_plys ) do
		ply = calling_ply
		ply:PrintMessage( HUD_PRINTTALK, "Checking " ..v:SteamID().. "...." )
		ply:PrintMessage( HUD_PRINTTALK, ".")
		
		x = "false"
		
		for _, v in pairs(donator) do
		ply:PrintMessage( HUD_PRINTTALK,   " is being checked")
			if v == v:SteamID() then
				x = "true"
				ply:PrintMessage( HUD_PRINTTALK, "  " ..v:SteamID().. " is a donator")
			end
		end
		
		if x == "true" then
			ply:PrintMessage( HUD_PRINTTALK, "  " ..v:SteamID().. " is a donator")
		else
			ply:PrintMessage( HUD_PRINTTALK, "  " ..v:SteamID().. " is not a donator")
	        end
       end
end

And in the donators.txt it was like
SteamID1
SteamID2
SteamID3

To acecool: Could you give me a little example for that?

And by the way, tried it like this now:


function ulx.test3( calling_ply, target_plys )
	
	local donator = { file.Read("donators.txt", "DATA") }
	for _, v in ipairs( target_plys ) do
		ply = calling_ply
		ply:PrintMessage( HUD_PRINTTALK, "Checking " ..v:SteamID().. "...." )
		ply:PrintMessage( HUD_PRINTTALK, ".")
		
		x = "false"
		
		z=v:SteamID()
	for _, v in pairs(donator) do
		if v==z then 
			ply:PrintMessage( HUD_PRINTTALK, "works")
			x = "true"
		end
	end

		
		if x == "true" then
			ply:PrintMessage( HUD_PRINTTALK, "  " ..v:SteamID().. " is a donator")
		else
			ply:PrintMessage( HUD_PRINTTALK, "  " ..v:SteamID().. " is not a donator")
		end
	end
end

But z never equals v… In donators.txt it’s like:
“STEAMID1”,
“STEAMID2”,
“STEAMID3”,

And all the PrintMessages are for me to see, how far it comes until something goes wrong…

local donator = file.Read(“donators.txt”, “DATA”)

becomes

local donator = util.JSONToTable( file.Read( “donators.txt”, “DATA” ) || “{ }” );

and your file.Write( name, data, location ) becomes file.Write( name, util.TableToJSON( data ), location )

The reason we do || “{ }” next to the file.Read, is so that in case there is no data, it’ll fall back to the default EMPTY JSON representation of a table, meaning we get a table no matter what ( unless someone edited the file, or file.Write didn’t save it as JSON ).

[ERROR] lua/autorun/server/test3.lua:13: bad argument #1 to ‘pairs’ (table expected, got nil)



function ulx.test3( calling_ply, target_plys )
	
	local donator = util.JSONToTable( file.Read( "donators.txt", "DATA" ) || "{ }" );
	for _, v in ipairs( target_plys ) do
		ply = calling_ply
		ply:PrintMessage( HUD_PRINTTALK, "Checking " ..v:SteamID().. "...." )
		ply:PrintMessage( HUD_PRINTTALK, ".")
		
		x = "false"
		
		z=v:SteamID()
	for _, v in pairs(donator) do
		if v==z then 
			ply:PrintMessage( HUD_PRINTTALK, "works")
			x = "true"
		end
	end

		
		if x == "true" then
			ply:PrintMessage( HUD_PRINTTALK, "  " ..v:SteamID().. " is a donator")
		else
			ply:PrintMessage( HUD_PRINTTALK, "  " ..v:SteamID().. " is not a donator")
		end
	end
end


How does it need to be in the donators.txt? Mabye it’s because of that?
And I mean file.append and not write, but already changed it in the other command.

You may need to reset the contents of the file. Can you show us what the file looks like?

It should look like: { 1:“Steam:0:0:1234”,2:“etc…” } or something similar.

At the moment it’s like
“STEAM_0:1:123”,“STEAM_0:1:1234”,“STEAM_0:0:12345”,“STEAM_0:0:123456”,

Does it need to have 1: 2: and so on infront of it? Adding the { now.

Added it exactly like you sent me, still same error ;(

No problem, use this to convert it:

[lua]//
// Converts a comma delimited text to a table - Josh ‘Acecool’ Moser
//
function util.StringToTable( _text, _commaTrailing )
local _explode = string.Explode( “,”, _text );

if ( _commaTrailing ) then
	table.remove( _explode, table.GetLastKey( _explode ) );
end

return _explode;

end

local _table = util.StringToTable( [[“STEAM_0:1:123”,“STEAM_0:1:1234”,“STEAM_0:0:12345” ,“STEAM_0:0:123456”,]], true );
print( “TEST”, type( _table ), table.Count( _table ), _table )[/lua]

Output ( custom print which uses MsgC for output, and also can print every data-type, you may need to use PrintTable ):

[lua]TEST table 4 [1] = “STEAM_0:1:123”
[2] = “STEAM_0:1:1234”
[3] = “STEAM_0:0:12345”
[4] = “STEAM_0:0:123456”[/lua]

So, just change: [lua]local _table = util.StringToTable( [[“STEAM_0:1:123”,“STEAM_0:1:1234”,“STEAM_0:0:12345” ,“STEAM_0:0:123456”,]], true );[/lua]

to

[lua]local _table = util.StringToTable( file.Read( “file”, “DATA” ), true );[/lua]

and then save it, only save it once…

[lua]file.Write( “file”, util.TableToJSON( _table ), “DATA” );[/lua]

string.Explode converts a string to a table using a delimiter such as the comma; since you have a trailing comma it’ll have 5 elements in the example you gave so we cut it off the end and then just save the data as is.

Sorry, but don’t understand what you want me to do :smiley:
Sounds very complicated and I think I can’t use file.append to add a SteamID to the table?

Hoped I just need to change something in the txt file to fix the problem ;(

Add me on Steam; send me the complete file and I’ll send you what you need to replace the contents as so that JSONToTable and TableToJSON will work with the data.

The function I provided would only need to be run 1 time for it to convert the data into proper JSON

I don’t know if that happens to everyone at some point but I love Ace now :slight_smile:

If someone needs it
Code to write to table:



local _table = util.JSONToTable(file.Read("filename", "where?"))
table.insert( _table,v:SteamID() )
file.Write( "filename", util.TableToJSON( _table ), "where? )


Code to read as table:



local _table = util.JSONToTable( file.Read( "filename", "DATA" ) || "{ }" );


And here I am again… If I add a donator it works fine and if I try to add the same person again it says he is already on the list.
I thought I did the same with remove, but doesn’t work… I checked it for a few times but still: If someone is not on the list, I can’t remove him. If I add him once, I can remove him as many times as I want. If I add someone and remove again, it says, he is already on the list. Hope you guys (and maybe girls^^) understand what I mean and can help me :slight_smile:

Here is the code (coded it as ULX Command like you can see)



local addremove = { "add", "a", "remove", "r", "check", "c" }

function ulx.donator( calling_ply, string_arg, target_plys )
	ply = calling_ply
	for _, v in ipairs( target_plys ) do 
		
		if ( string_arg == "add" or string_arg == "a" ) then
			local _donators = util.JSONToTable(file.Read("donators.txt", "DATA"))
				for a, b in ipairs(_donators) do
					c = v:SteamID()
					if b == c then
						x = "exists"
					end
				end	
				if x == "exists" then	
					ply:PrintMessage( HUD_PRINTTALK, v:Nick().. "(" ..v:SteamID().. ") is already on the donator-list." )
				else	
					table.insert( _donators, v:SteamID() )
					file.Write( "donators.txt", util.TableToJSON( _donators ), "DATA" )
					if ply:IsValid() then
						ply:PrintMessage( HUD_PRINTTALK, "Successfully added " ..v:Nick().. "(" ..v:SteamID().. ") to the donator-list." )
					else
						print ( "Successfully added" ..v:Nick().. "(" .. v:SteamID().. ") to the donator-list." )
					end
					PrintMessage( HUD_PRINTTALK, "We have a new donator: " ..v:Nick().. "! Thanks for supporting the server!" )
				end
				print( file.Read( "donators.txt", "DATA" ))
			
		end
		
		if ( string_arg == "remove" or string_arg == "r" ) then
			local _donators = util.JSONToTable(file.Read("donators.txt", "DATA"))
			for a, b in ipairs(_donators) do
				c = v:SteamID()
				if b == c then
					x = "exists"
				end
			end	
			if x == "exists" then
				table.RemoveByValue( _donators, v:SteamID() )
				file.Write( "donators.txt", util.TableToJSON( _donators ), "DATA" )
				if ply:IsValid() then
					ply:PrintMessage( HUD_PRINTTALK, "Successfully removed " ..v:Nick().. "(" ..v:SteamID().. ") from the donator-list." )
				else
					print ( "Successfully removed " ..v:Nick().. "(" .. v:SteamID().. ") from the donator-list." )
				end	
				print( file.Read( "donators.txt", "DATA" ))		
			else
				ply:PrintMessage( HUD_PRINTTALK, v:Nick().. "(" ..v:SteamID().. ") is not on the donator-list." )
			end	
		end
	end
	
	if ( string_arg == "check" or string_arg == "c" ) then
		if ply:IsValid() then
			ply:PrintMessage( HUD_PRINTTALK, file.Read( "donators.txt", "DATA" ) )
		else
			print ( file.Read( "donators.txt", "DATA" ) )
		end	
	end	
end
local donator = ulx.command( "User Management", "ulx donator", ulx.donator, "!donator" )

donator:addParam{ type=ULib.cmds.StringArg, completes=addremove, default="add", hint="add or remove?", error="invalid string", ULib.cmds.restrictToCompletes }
donator:addParam{ type=ULib.cmds.PlayersArg }
donator:defaultAccess( ULib.ACCESS_SUPERADMIN )
donator:help( "Adds or removes donator(s)." )




What I need to say: Add and remove works fine, just have this little issue with removing/adding again :wink: