L'envoi et la réception de données sur Garry's Mod
Dans cette partie, nous allons aborder l'envoi et la réception de données dans un message net, en commençant par la théorie, puis en pratique avec un message net qui demande au serveur de nous donner un nombre aléatoire entre 1 et 6.
Le buffer
Quand vous recevez un message net, toutes les données de ce message sont écrites dans un buffer qui contient tous les bits des données.
Les 16 premiers bits d'un message net (ou deux octets, car un octet contient 8 bits) correspondent au Header
du message, qui est l'id unique. Cet identifiant numérique correspond à un nom de message qui a été ajouté à la string table
via util.AddNetworkString()
.
-- Example d'un message ajouté via AddNetworkString
util.AddNetworkString("MonMessageNet")
-- Utilitaire pour récupérer l'identifiant numérique d'un message net.
-- i = 2146 (example)
local i = util.NetworkStringToID("MonMessageNet")
-- Utilitaire pour récupérer le nom d'un message via son identifiant numérique.
-- name = 'MonMessageNet'
local name = util.NetworkIDToString(i)
Lorsqu'un message net est reçu, la fonction net.Incoming()
lit les 16 premiers bits du message:
local i = net.ReadHeader()
-- Ce qui correspond aussi à:
local i = net.ReadUInt(16)
Puis, elle convertit l'identifiant numérique en nom de message pour exécuter la fonction qui lui correspond si elle existe (la fonction attribuée avec net.Receive()
)
Les données suivantes sont exclusivement les données que vous allez envoyer dans vos messages. Le header est écrit automatiquement lorsque vous faites net.Start()
.
Les types de données
Vous pouvez envoyer la plupart des types de données de Garry's Mod via la bibliothèque net, et dans le cas échéant, vous pouvez envoyer des données compressées (ou non), comme du JSON.
Les types de données suivants ont des fonctions pour les envoyer et les recevoir:
- ReadAngle et WriteAngle
- ReadBool et WriteBool
- ReadColor et WriteColor
- ReadDouble et WriteDouble
- ReadEntity et WriteEntity
- ReadFloat et WriteFloat
- ReadInt et WriteInt
- ReadMatrix et WriteMatrix
- ReadNormal et WriteNormal
- Bien que ce soit un Vector, Normal est un vecteur normalisé (composants entre 0.0 et 1.0)
- ReadString et WriteString
- ReadUInt et WriteUInt
- Unsigned int, donc une valeur qui ne peut pas être dans les négatifs.
- ReadVector et WriteVector
Compresser les chiffres entiers (Int et UInt)
Les fonctions d'envoi pour les types Integer
et Unsigned Integer
ont un argument supplémentaire pendant la lecture et l'écriture: le nombre de bits à utiliser.
local num = 254 -- Ce chiffre est toujours entre 0 et 255
net.WriteUInt(math.Clamp(num, 0, 254), 8) -- 8 bits autorise une valeur minimale de 0, et maximale de 255
local receivedNum = net.ReadUInt(8)
-- Si vous ne savez pas combien de bits il vous faudra, laissez 32 bits pour être sur.
net.WriteInt(someNumber, 32)
local myNumber = net.ReadInt(32)
Les valeurs minimales/maximales par nombre de bits sont disponibles pour les Integer et les Unsigned Integer.
Example: Roll the Dice
Dans cet exemple, nous allons programmer un système qui donnera un nombre aléatoire entre 1 et 6 au client qui le demande. Le nombre est généré côté serveur.
-- cl_init.lua, coté client
net.Receive("RTD.ReceiveDice", function(len, ply)
local num = net.ReadUInt(8)
chat.AddText("You rolled a " .. tostring(num))
end)
-- init.lua, coté serveur
util.AddNetworkString("RTD.ReceiveDice")
hook.Add("PlayerSay", "CheckRTD", function(ply, text, teamChat)
if text:lower() == "!rtd" then
local dice = math.random(1, 6)
net.Start("RTD.ReceiveDice")
net.WriteUInt(dice, 8)
net.Send(ply)
return ""
end
end)
Lorsque vous ferez !rtd
dans votre chat, vous recevrez un nombre entre 1 et 6.
Dans la prochaine partie de notre série, nous allons aborder l'envoi de données binaires avec net.WriteData()
et leur compression avec util.Compress()