Datastreams
From GMod Wiki
Lua: Datastreams |
Description: | Teaches how to use the new datastream module |
Original Author: | LuaBanana |
Contributors: | TGP1994 |
Created: | 24th January 2009, last edited 2nd March 2010 |
Contents |
What are they
Datastreams are much like usermessages except they allow for nonuniform sending of many data types. Not only can you send data to the client from the server, but you can send data to the server from the client. The datastream module is powered off of Deco da Man's GLON module, of which is available in Garry's Mod as well.
How do they work?
- The client or server calls their corresponding sending function ( datastream.StreamToClients serverside, datastream.StreamToServer clientside ). You can give this function nearly any type of data. Look here for the supported data types. You also need to give it a handler.
- The datastream module creates an operation table of which is placed into a cache. It has three stages.
- Server can send to multiple players at once
- In stage 1 (waiting), the script processes the data. It encodes it using glon, and splits it up by 128-character blocks. Datastream notifies the recipient of the new operation.
- If it is being sent from clientside, the server must accept the data via the AcceptStream hook.
- In stage 2 (transfer), the script sends the data via either concommands (client) or usermessages (server). It is concatenated into the recipients operation buffer.
- In stage 3 (complete), the data is decoded and the corresponding hook is called. It will also call gamemode.CompletedIncomingStream, of which you can return false serverside to stop the datastream hook from being called (for example, if you notice some malicious data).
Examples
Client to Server
On the client:
datastream.StreamToServer( "TestHook", { ["text"] = "Hello world! The answer to everything is", ["number"] = "42", ["bool"] = true } );
On the server:
function GM:AcceptStream( pl, handler, id ) return true; // Allow all streams end function TestHook( ply, handle, id, encoded, decoded ) print( decoded.text ); print( decoded.number ); print( decoded.bool ); end datastream.Hook( "TestHook", TestHook );
Server Output:
Hello world! The answer to everything is 42 true
Server to Client
On the client:
function TestHook( handle, id, encoded, decoded ) print( decoded.text ); print( decoded.number ); print( decoded.bool ); end datastream.Hook( "TestHook", TestHook );
On the server:
datastream.StreamToClients( player.GetAll( ), "TestHook", { ["text"] = "Hello world! The answer to everything is", ["number"] = "42", ["bool"] = true } );
Client Output:
Hello world! The answer to everything is 42 true
As you can see, the code is nearly identical in both ways. The main difference is that the client doesn't have to specify who he is streaming to and thus does not need player objects as it's first argument.