Page 1 of 2

Sending multiple values with LUBE

Posted: Wed May 06, 2015 8:30 pm
by Ovidios
I've just started using LUBE and now want to send multiple tables from the server to the client. Is there any way to differentiate between the different send-calls, for example by using tags?
Thanks in advance! ^^

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 4:22 am
by cohadar
Make a new table:
{ msg_type = "player_death", table1 = table1, table2 = table2, ... }
{ msg_type = "position_update", table1 = table1, table2 = table2, table3 = table3 }

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 11:45 am
by Ovidios
But when I try to pack a table with subtables to a string using lube.bin:pack() I get an error message saying the type table is not supported... :/ Do I have to use another table serialization library? Could you recommend a simple one?

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 12:09 pm
by I~=Spam
Yep! Here is a very good one! https://github.com/gvx/Ser

Although if you are going to have tables rereferencing themselves you will need the slower but more advanced: https://github.com/pkulchenko/serpent

EDIT: Replaced img tag with url tag. :crazy:

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 2:32 pm
by Ovidios
I'm using the first one now since I'm doing very basic stuff and it works perfectly! Thank you two very much! :awesome:

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 3:00 pm
by cohadar
I am using enet with serpent, it works fine for now.

I detected serpent loses floating-point precision of numbers and have already suggested a fix to the author.

Presumably a perfect netcode serialization library would look like this:
  • Support nested tables
  • Do NOT support cycles, it is slow and it is responsibility of coder to make good input data to netcode
  • All keys MUST be strings, speed is the reason again
  • It should NOT use loadstring for deserialization, it would be a huge security hole.
I believe the best solution would in fact be to write love.pack and love.unpack methods in C++

EDIT:
Forgot to add that all values are either tables or primitive types.

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 3:19 pm
by zorg
I~=Spam wrote:Yep! Here is a very good one! Image

Although if you are going to have tables rereferencing themselves you will need the slower but more advanced: https://github.com/pkulchenko/serpent
For the record, ser can serialize lövecraftian tables too. :3
(And ser is also faster than serpent)

Edit:
cohadar wrote:It should NOT use loadstring for deserialization, it would be a huge security hole.
Also related: Smallfolk, by the same person.

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 3:58 pm
by I~=Spam
cohadar wrote:It should NOT use loadstring for deserialization, it would be a huge security hole.
You do know that you can use pcall and setfenv to make these perfectly safe right?
cohadar wrote:I believe the best solution would in fact be to write love.pack and love.unpack methods in C++
No it wouldn't change the security hole. Unless you rewrite the lua parser so that the C++ parses the lua code itself safely. (And that is a HUGE can of worms with security.) Seriously though. Lua has this already built in. http://lua-users.org/wiki/SandBoxes So it is actually safer to write the sandbox in lua...

Just sandbox the lua code! This will do all of the work for you: https://github.com/APItools/sandbox.lua @cohadar try to break out of this sandbox. I don't think you can.

I have written a lua sandbox but it isn't exactly what you are looking for here. Mine allows pausing untrusted lua code inside of sandboxed coroutines. While the library above forcefully exits the lua code if it takes too long and can only do one at a time. Because of how luajit works internally I actually have to use a small c library to achieve this. But this isn't what you need. :)

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 7:12 pm
by cohadar
pcall and setfenv are just more unneeded overhead.
even loadstring is an overhead.

We do not NEED full lua language parser for this, just parser that can read booleans, numbers, strings and tables.
Data parser is trivial to implement, and it would be extremely fast.

Now that I have written this I realize that implementing data parser is NOT something we should do.
There already exist good data parsers for a standard data-interchange format: JSON

What we need inside Love is a good json library.
And by good I mean one that preserves floating point precision.

For example serpent fails floating-preservation:

Code: Select all

local text = serpent.line( { pi = math.pi } )
ok, t = serpent.load( text )
assert( ok )
assert( math.pi == t.pi )
I suspect same is true of LUBE and Ser

EDIT: yep, Ser also fails

Code: Select all

	local text = ser( { pi = math.pi } )
	t = loadstring( text )
	assert( math.pi == t().pi )

Re: Sending multiple values with LUBE

Posted: Thu May 07, 2015 7:40 pm
by I~=Spam
cohadar wrote:We do not NEED full lua language parser for this, just parser that can read booleans, numbers, strings and tables.
Data parser is trivial to implement, and it would be extremely fast.
Ahh ok I understand what you are saying now. ;) It still doesn't change that what you said before about it being unsafe is completely false.
cohadar wrote: For example serpent fails floating-preservation:

Code: Select all

local text = serpent.line( { pi = math.pi } )
ok, t = serpent.load( text )
assert( ok )
assert( math.pi == t.pi )
I suspect same is true of LUBE and Ser

EDIT: yep, Ser also fails

Code: Select all

	local text = ser( { pi = math.pi } )
	t = loadstring( text )
	assert( math.pi == t().pi )
This is not their fault check it out.

Code: Select all

lua
Lua 5.2.4  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> print(math.pi)
3.1415926535898
> assert(math.pi == 3.1415926535898)
stdin:1: assertion failed!
stack traceback:
	[C]: in function 'assert'
	stdin:1: in main chunk
	[C]: in ?
> 
cohadar wrote:Now that I have written this I realize that implementing data parser is NOT something we should do.
There already exist good data parsers for a standard data-interchange format: JSON

What we need inside Love is a good json library.
And by good I mean one that preserves floating point precision.
I disagree. Json data cannot contain references to itself. (Like how lua tables can reference themselves.) Also I seriously doubt the speed boost would be enough to even matter. LuaJIT has optimized this to the point it can't get much faster. Just stick with lua tables. It works perfectly with lua with no add ons and with serpent you can serialize any table (as long as there is no userdata). This is not the case with json. Sure a json parser could be written in lua rather than a c library but then you loose the potential speed boost you were hoping to gain.