The New Net Library

There are some situations where it’d be nice to have support for tables containing arbitrary things.

An example would be my notification system. Some examples of its use:

[lua]ply:Notify( { "You were killed by ", attacker, “.” } )
ply:Notify( {"You took ", num, " damage from ", attacker, “.” } )
ply:Notify( {"You found a ", Color(255,0,0), “red thing.” } ) [/lua]

As you can see the table can contain any number of elements (the elements can be players, colors, numbers and text) and there’s no specific order to it. I figure Garry will implement code that handles something like this since there’s no point in making people jump through hoops making their own WriteTable clones.

Wait, so with the replacement of datastream we don’t send tables through networking any more?

You still can, the types you can have in tables being sent is fairly limited at the moment though. I imagine it’s still a work in progress.

I’m just having fun theorycrafting and coming up with ways to send stuff that isn’t supported yet.

You will have to deconstruct your table(s) most of the time or use glon. Oh to joy I love glon.

Well WriteTable is still under construction so you likely won’t need to. GLON is also a bad choice.

I did get my variable length table code to work! It’s really hacky in some areas (colors need to be converted to tables without string indices) but otherwise it works perfectly.

[lua]
net.Start( “LogEvent” )

	local tbl = {}

	for k,v in pairs( msg ) do
	
		table.insert( tbl, TypeID( v ) )
	
	end
 
    net.WriteTable( tbl )
	
	for k,v in pairs( msg ) do
	
		if type( v ) == "string" then
		
			net.WriteString( v )
		
		elseif type( v ) == "table" then
		
			net.WriteTable( { v.r, v.g, v.b } )
		
		else
		
			net.WriteLong( v )
		
		end
	
	end
 
net.Broadcast() [/lua]

There’s the serverside code, where msg is a table full of strings, numbers and colors.

Client code:

[lua]
net.Receive( “LogEvent”, function( len )

	MsgN( "Received message of ", len, " bits..." )
     
    local tbl = net.ReadTable()
	local notice = {}
	
	for k,v in pairs( tbl ) do
		
		if v == TypeID( "a" ) then
		
			table.insert( notice, net.ReadString() )
		
		elseif v == TypeID( 1 ) then
		
			table.insert( notice, net.ReadLong() )
		
		else
		
			local col = net.ReadTable()
		
			table.insert( notice, Color( col[1], col[2], col[3] ) )
		
		end
	
	end
  
end )[/lua]

Of course this is hacky as hell and we’re better off waiting for garry to just finish the net library. But it’s fun to muck around.

My new way would just be taking the WriteTable function, and then overwriting it with a function that supports strings and other tables. Either that, or just overwrite WriteVar, because that’s what makes WriteTable write different data types.

Why don’t you just wait till it’s finsihed? What would be the point of a WriteTable function that didn’t write a table properly? You think I decided that I would have a WriteTable function but only allow you to send strings, floats and vectors in them?

Meh, okay.

Table size: 6.
1 = eggs
2 = cheese
3 = shovel
4 = apple
5 = orange
6 = hitler

2 and 6
cheese hitler

someone should hit us up with some rough docd on the net library, like… how to omit players? not all of us got beta keys…

Updated the OP with more recent code and examples.

-snip-

awesome, thank you sir.
out of curiosity, is there only a send to player function? or is there anything similar to recipient filters from usermessages?

Garry already said there will be a way to send to a player, send to multiple players, send to all players, and don’t send to specific players.

There is net.SendOmit although i have not tried messing with it yet. I’ll take a look in a bit.

I’m having difficulty with the net.Send* functions.

A test on a server with two players:



lua_run player.GetAll()[1]:SendLua("net.Receive('abc',function(l)RunConsoleCommand('say','abc:'..l)end)")
> player.GetAll()[1]:SendLua("net.Receive('abc',function(l)RunConsoleCommand('say','abc:'..l)end)")...
lua_run player.GetAll()[2]:SendLua("net.Receive('abc',function(l)RunConsoleCommand('say','abc:'..l)end)")
> player.GetAll()[2]:SendLua("net.Receive('abc',function(l)RunConsoleCommand('say','abc:'..l)end)")...
> lua_run net.Start("abc") net.Broadcast()
> net.Start("abc") net.Broadcast()...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.Send()
> net.Start("abc") net.Send()...
> lua_run net.Start("abc") net.Send(Player(1))
> net.Start("abc") net.Send(Player(1))...
> lua_run net.Start("abc") net.Send(Player(2))
> net.Start("abc") net.Send(Player(2))...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.Send(Entity(1))
> net.Start("abc") net.Send(Entity(1))...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.Send(Entity(2))
> net.Start("abc") net.Send(Entity(2))...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.Send({Player(1)})
> net.Start("abc") net.Send({Player(1)})...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.Send({Player(2)})
> net.Start("abc") net.Send({Player(2)})...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.Send({})
> net.Start("abc") net.Send({})...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.Send(nil)
> net.Start("abc") net.Send(nil)...
> lua_run net.Start("abc") net.Send(1)
> net.Start("abc") net.Send(1)...
> lua_run net.Start("abc") net.Send(1337)
> net.Start("abc") net.Send(1337)...
> lua_run net.Start("abc") net.Send(true)
> net.Start("abc") net.Send(true)...
> lua_run net.Start("abc") net.SendOmit({})
> net.Start("abc") net.SendOmit({})...
Deco: abc:16
Chewgum: abc:16
> lua_run net.Start("abc") net.SendOmit({Player(1)})
> net.Start("abc") net.SendOmit({Player(1)})...
Deco: abc:16
Chewgum: abc:16


There seems to be no way to send to a specific set of players.
I’ve tried CRecipientFilters too.
Are these functions not working yet?

So basicly the Net Library is a improved “datastream”? Sadly I haven’t got a Beta key, as I can’t fix some stuff that I’m using datastream for. (Sending pretty big text shit, ya’ll know…)

net.WriteTable is like a new datastream, but the rest of the library is like the old usermessage system.

net.Send and SendOmit should take a { ply, ply, ply } or just a ply

If it doesn’t then post a bug in the beta forum

awesome, thanks garry.

any general guestimate on a release date so I can know when to start fixing my gamemode?