vl_client/api.lua

132 lines
3.9 KiB
Lua
Raw Normal View History

local channel
vl_client = {
message_callbacks = {},
connect_callbacks = {},
activate_callbacks = {},
capabilities = {},
server_capabilities = {},
is_connected = false,
is_active = nil, -- importantly not false
}
-- SEND MESSAGE
-- format: (string) {opname, message}
-- Send a message via the modchannel to the server
-- data: table to be sent to server, must be json serialisable
local function send_data(data)
-- TODO: Should channel ever be nil?
if not channel then return end
local string_data = minetest.write_json(data)
--minetest.debug("Sending data to server:", string_data)
channel:send_all(string_data)
return true
end
-- opname: the name of the category of this message
-- message: any json-serialisable object (not necessarily table)
function vl_client.send_message(opname, message)
send_data({opname, message})
end
-- ON MESSAGE RECEIVED
-- format of received messages: (string) {playername, opname, message}
minetest.register_on_modchannel_message(function(channel_name, sender, raw_data)
if channel_name ~= "vl_client" then return end
local data = minetest.parse_json(raw_data)
if data == nil then
minetest.debug("ERROR vl_client: received non-json data:", raw_data)
end
local receiver, opname, message = unpack(data)
--minetest.debug("Client: message received from server with opname " .. opname)
if minetest.localplayer:get_name() ~= receiver then return end
--minetest.debug("Message received on client, sender:", sender, "opname: ", opname, "message:", dump(message))
local callbacks = vl_client.message_callbacks[opname]
if callbacks == nil then return end
for _, callback in pairs(callbacks) do
callback(message)
end
end)
-- opname: the name of the category of message to call function on
-- func: the callback function; arguments:
-- playername: the name of the player whose client sent the message
-- message: the message sent from the server - must not be modified by callback
function vl_client.register_on_message(opname, func)
if vl_client.message_callbacks[opname] == nil then
vl_client.message_callbacks[opname] = {}
end
table.insert(vl_client.message_callbacks[opname], func)
end
-- CONNECT TO SERVER
local function connect()
channel = minetest.mod_channel_join("vl_client")
vl_client.is_connected = true
minetest.debug("Client connected to modchannel")
for _, callback in pairs(vl_client.connect_callbacks) do
callback()
end
end
minetest.register_on_mods_loaded(connect)
-- Register a function to be called when we connect
-- Args: none
function vl_client.register_on_connect(func)
table.insert(vl_client.connect_callbacks, func)
end
-- ACTIVATE
-- Activation protocol: client sends capabilities, then server replies with capabilities
minetest.register_on_modchannel_signal(function(channel_name, signal)
if channel_name ~= "vl_client" then return end
if signal == 1 then -- join failed, retry
minetest.after(1, join)
end
if signal == 0 then
vl_client.send_message("_capabilities", vl_client.capabilities)
end
end)
-- receiving a _capabilities message means the server supports active csm (but not necessarily any features)
vl_client.register_on_message("_capabilities", function (message)
vl_client.is_active = true
vl_client.server_capabilities = message
minetest.debug("Client activated")
--minetest.debug("Server has capabilities:", dump(message))
for _, callback in pairs(vl_client.activate_callbacks) do
callback()
end
end)
-- Register a function to be called when we activate
-- Args: none
function vl_client.register_on_activate(func)
table.insert(vl_client.activate_callbacks, func)
end
-- CAPABILITIES
-- Register a capability of the client, of which the server will be informed
-- Capabilities can have a value to give details about that capability
-- The value can be any json-serialisable object (not necessarily table)
function vl_client.register_capability(capability, value)
vl_client.capabilities[capability] = value
end