Working Network Tables!

I couldn’t see this on facepunch already and the only one I found was fake so I present you with my networked tables!

Functions are as you would expect: entity:SetNWTable(name, table) and entity:GetNWTable(name)


local meta = FindMetaTable("Entity");

function meta:GetNWTable(name)
	if(self.nwtabs==nil)then
		return {};
	else
		for i = 1,#self.nwtabs do
			if(self.nwtabs*==name)then
				return self.nwtabs[i+1];
			end
		end
		return {};
	end
end

if(SERVER)then
	util.AddNetworkString("TableToClient");
	
	function meta:SendTableToClient(tablename)
		net.Start("TableToClient");
		net.WriteEntity(self);
		net.WriteTable(tablename);
		for k,v in pairs(player.GetAll())do
			net.Send(v);
		end
	end
	
	function meta:SetNWTable(name,value)
		if(self.nwtabs==nil)then
			self.nwtabs={};
			
			self.nwtabs[#self.nwtabs+1]=name;
			self.nwtabs[#self.nwtabs+1]=value;
		else
			local CouldAdd = false;
			for i = 1,#self.nwtabs do
				if(self.nwtabs*==name)then
					self.nwtabs[i+1]=value;
					CouldAdd=true;
				end
			end
			
			if(!CouldAdd)then
				self.nwtabs[#self.nwtabs+1]=name;
				self.nwtabs[#self.nwtabs+1]=value;
			end
		end
		
		self:SendTableToClient(self.nwtabs);
	end
	
	hook.Add("PlayerInitialSpawn","Send information to clients when someone joins",function(u)
		for k,v in pairs(ents.GetAll())do
			if(v.nwtabs!=nil)then
				v:SendTableToClient(v.nwtabs);
			end
		end
	end)
end

if(CLIENT)then
	net.Receive("TableToClient",function()
		local u = LocalPlayer();
		
		local ent = net.ReadEntity();
		local tab = net.ReadTable();
		
		ent.nwtabs=tab;
	end)
	
	function meta:SetNWTable(name,value)
		if(self.nwtabs==nil)then
			self.nwtabs={};
			
			self.nwtabs[#self.nwtabs+1]=name;
			self.nwtabs[#self.nwtabs+1]=value;
		else
			local CouldAdd = false;
			for i = 1,#self.nwtabs do
				if(self.nwtabs*==name)then
					self.nwtabs[i+1]=value;
					CouldAdd=true;
				end
			end
			
			if(!CouldAdd)then
				self.nwtabs[#self.nwtabs+1]=name;
				self.nwtabs[#self.nwtabs+1]=value;
			end
		end
	end
end

[editline]26th April 2016[/editline]

If this doesn’t work for you please tell me so I can try and fix it :smiley:


self.nwtabs[#self.nwtabs+1]=name;
self.nwtabs[#self.nwtabs+1]=value;

:nope:

Sorry, but what?

Use table.insert or something like that, instead of this monstrosity you have created.

Why use table.insert when it is unnecessary? There is no need to replace what I currently have as it would not affect the performance of it in any way.


for k,v in pairs(player.GetAll())do
net.Send(v);
end

use net.Broadcast()

I dont think this is better than nw2…
And this is only for tables, sending tables in net is not so good and i wouldn’t use {value}

Anything to make the code slightly more readable than this butchered mess.

Here, you would have to call SetNWTable each time you wanted the table to be updated on the client. Since tables are passed around as pointers (as are other objects in Lua), you could reference the table to be sent the client, however it will not be sent again if the table changes.

I would see more use for automatic networking of the table rather than manual. You can do this easily by making use of the NewIndex method on the tables, but does require a bit more work. Here is a slightly more abstract version of what I am talking about.

But otherwise, nice start :slight_smile:

I’ll explain why I put “nope” emote there.

It’s not only looks ugly, it can cause some big perfomance issues. Every time you want to get one table, your function (GetNWTable) loops through the entire table. And your way of assigning variables makes it even worse (if you have 100 different nwvars, you’ll loop through 198 other values to get a last table you’ve added).

Here’s how you should do that kind of stuff:



function meta:SetNWTable(name, tbl)
	self._nwtables = self._nwtables or {}
	self._nwtables[name] = tbl
end

function meta:GetNWTable(name, default)
	return self._nwtable and self._nwtable[name] or default
end