Network Library
From GMod Wiki
Lua: User Messages |
Description: | How to use the network library |
Original Author: | Science |
Created: | December 1, 2011 |
Contents |
Introduction
The new network library introduced to garrysmod in the beta of garrysmod 13 allows the user to transmit data between client and server and vice versa with ease, the system is very easy to use and removes limits (The limit is 64kb, but if you hit this there are problems). This system also allows for tables and other data types to be send both ways unlike console commands which limited the user to text responses.
The system works like this:
- Call net.Start on the server or client with a unique identifier as the first argument (A second argument is valid if accepting streams from clients (This argument is the player entity)).
- Push data in the message using other net.Write* functions, such as net.WriteTable, net.WriteString, etc.
- Call net.Send(Entity) to send the data from the server to a specific client. net.Broadcast can be used to also send data to every client as opposed to net.Send(player.GetAll()). You can also use net.SendToServer from the client, this will send the data of any type to the server via the net library.
- On the client or server, define and hook a callback function that will be called when the network is received using net.Receive or net.Incoming
This article assumes that you know the basics of GMod-specific Lua.
Size limit
Unlike umsg limits of 255 bytes, the new net library allows the user to send 64kb's of data from the server to the client and client to the server without limits and with any data format they wish, including tables, entities, vectors, angles and many more.
The allowed formats and their limits, if any, are listed below:
- Table
- String
- Long
- Float
- Entity
- Vector
- Angle
- Angles
- Byte
- Bit
Examples
Simple Server To Client
Server side code:
local fl = 2.3456 local long = 100200 local ent = Entity(1) local byte = 10 local str = "John Lua" local vec = Vector( 900, 3.4567, -500 ) local ang = Angle( 4.5678, -90, 45 ) net.Start( "Test2" ) net.WriteFloat( fl ) net.WriteLong( long ) net.WriteEntity( ent ) net.WriteByte( byte ) net.WriteString( str ) net.WriteVector( vec ) net.WriteAngles( ang ) net.Send(Entity(1))
Client side code:
net.Receive( "Test2", function(len) MsgN("Test2: Contains "..len.." bits") MsgN("ReadFloat:") MsgN(net.ReadFloat()) MsgN("ReadLong:") MsgN(net.ReadLong()) MsgN("ReadEntity:") MsgN(net.ReadEntity()) MsgN("ReadByte:") MsgN(net.ReadByte()) MsgN("ReadString:") MsgN(net.ReadString()) MsgN("ReadVector:") MsgN(net.ReadVector()) MsgN("ReadAngle:") MsgN(net.ReadAngle()) end)
Client To Server
This will send clientside data to the server.
Serverside code:
net.Receive( "Test2", function(len, ply) MsgN("Test2: Contains "..len.." bits") MsgN("Player: "..ply) MsgN("ReadFloat:") MsgN(net.ReadFloat()) MsgN("ReadLong:") MsgN(net.ReadLong()) MsgN("ReadEntity:") MsgN(net.ReadEntity()) MsgN("ReadByte:") MsgN(net.ReadByte()) MsgN("ReadString:") MsgN(net.ReadString()) MsgN("ReadVector:") MsgN(net.ReadVector()) MsgN("ReadAngle:") MsgN(net.ReadAngle()) end)
Clientside code:
local fl = 2.3456 local long = 100200 local ent = Entity(1) local byte = 10 local str = "John Lua" local vec = Vector( 900, 3.4567, -500 ) local ang = Angle( 4.5678, -90, 45 ) net.Start( "Test2" ) net.WriteFloat( fl ) net.WriteLong( long ) net.WriteEntity( ent ) net.WriteByte( byte ) net.WriteString( str ) net.WriteVector( vec ) net.WriteAngles( ang ) net.SendToServer()
Note: You need to read data in the same order as you send it. If you sent a string first, read it first, etc.
Note: net data is sent as soon as net.Send or any other finalising function is called, if the code is located in the body of a file, it will be sent as soon as the file has loaded, often before the client's lua has loaded, resulting in him not receiving the message. Send net data primarily when hooks are called, or using timers to make sure there is an audience for the message. Send data the client needs immediately upon joining in a PlayerInitialSpawn hook for example.
Practical example
You are making a server administration addon, for instance, and you want the menu to have a list of maps that are available on the server. Since your map list and the server's may differ, you need to manually send the map names.
Serverside:
hook.Add("PlayerInitialSpawn", "SendMapList", function(ply) net.Start("Maps") local maps = file.Find("../maps/*.bsp") net.WriteLong(#maps) for k,v in pairs(maps) do net.WriteString(v) end net.Send(ply) end)
Client:
local MapList = {} net.Receive("Maps", function(len) local amt = net.ReadLong() for i = 1,amt do MapList[#MapList+1] = net.ReadString() end end)
Client to Server
This new method of sending client to server allows many more data types, as console commands had a limit of 255 bytes and also only allow strings to be sent, it was a pain to send some data types to the user. This new system allows all data types to be sent and received on the client. Usermessages also did not allow certain types of data such as tables which the user needed to break down and recompile on the other end. The new system allows full tables to be exchanged by the recipient and server at any time, instantaniously.