132 lines
3.9 KiB
Lua
132 lines
3.9 KiB
Lua
|
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
|