net.WriteTable not always transferring entire table

I’ve noticed in my map voting system, when i send a table of votable maps to a player they don’t always arrive intact. Sometimes there are a few missing, sometimes they are all there. Has anybody else had this problem?

While I see the issue, you could just use a foreach look with ipairs and do it yourself.

Unless the table is always the same size net. wouldn’t handle well the received message.

How big is the table you’re sending? The maximum is 64kb.

I have a feeling his map list isn’t 64,000 characters long.

Keep in mind it pretty much writes an int for the variable type of the key, the value of the key, the variable type of the value, and the value itself, so four things per item in the table.

Well the thing is, somtimes it works, sometimes it doesn’t, so i’m pretty sure it’s not an issue with the table size since for the most part it is the same size.

If all you are doing is sending a list of strings, there are more bandwidth efficient ways to do it than net.WriteTable. In my addon, I have to send a list of filenames to the client. I used this code:



-- SERVER
concommand.Add("doom_map_wadlist", function(ply, cmd, args)
	if not ply:IsAdmin() then return end
	local wads = file.Find("*.wad", "GAME")
	local count = #wads
	if count > 255 then ply:ChatPrint("Too many wad files in the server's garrysmod folder!") return end
	net.Start("DOOM.WadList")
	net.WriteUInt(count, 8)
	for i = 1, count do
		net.WriteString(wads*)
	end
	net.Send(ply)
end)

-- CLIENT
net.Receive("DOOM.WadList", function(bits)
	if not WadList then return end
	local value = WadList:GetValue()
	WadList:Clear()
	local count = net.ReadUInt(8)
	for i = 1, count do
		WadList:AddChoice(net.ReadString())
	end
	WadList:SetValue(value)
end)


If you really wanted to, you could drop the count from the message and keep reading strings until you determine that you have read all of the bytes.

I’ve been sending tables through the net library like a madman for months. I haven’t had a single issue.

Did you check the integrity of the table before and after sending it? (on the server)

The integrity is always solid. I have found that it usually only happens if it is done soon after the client connects. If i wait like 30 seconds, it works fine, which is usually not a problem since i only try to transfer the table quickly when i am testing.

Under what hook do you send the data?

I’m always doing this kind of stuff in PlayerAuthed.

Not under any gamemode hook, just a function call i do through console. It usually gets run right before the map vote happens, and i give it a 3 second grace period to transfer over the table, and then it shows the voting panel on the client side.

Try serializing the table and sending it as a string. (using vON, for example)
If this fixes it… It would be weird.

Can you post the code, I find this really strange and I’ve never had issues. Chances are you may have a mistake in it. Or you’re sending over 64kb; which I doubt.

As requested:

[lua]

// ON THE SERVER

function SMV.StartMapVote()
MsgN("[SMV] Map voting started!")

SMV.Voting = true
GAMEMODE.STOP = true

net.Start("smv_start")
net.WriteTable(SMV.Maps)
net.Broadcast()


timer.Simple(SMV.VoteTime + 5, function() SMV.EndMapVote() end)

end
hook.Add(“Morbus_MapChange”, “SMV_MapHook”,SMV.StartMapVote)

// ON THE CLIENT

function SMV.StartVote()
SMV.Maps = net.ReadTable()
SMV.Voting = true
if SMV.VotingPanel then
SMV.VotingPanel:Remove()
end
timer.Simple(2,SMV.OpenVotingPanel)
end
net.Receive(“smv_start”,SMV.StartVote)

// SMV.Maps looks like {“mor_map1”,“mor_map2”}

[/lua]

Not sure what it’s worth but the the only time I’ve had tables come through net incorrectly was when they contained functions.

GMod will error out when sending tables containing functions.
There is no index for the function type in the code for sending tables.

Please try sending a really huge string… Like, the map names separated by a semicolon (;).