Initial commit: insecure server-client communication protocol
This commit is contained in:
commit
91c8808ad9
|
@ -0,0 +1,131 @@
|
||||||
|
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
|
|
@ -0,0 +1,6 @@
|
||||||
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
|
||||||
|
dofile(modpath .. "/api.lua")
|
||||||
|
minetest.debug(modpath .. "/api.lua", modpath .. "/ping.lua")
|
||||||
|
|
||||||
|
dofile(modpath .. "/ping.lua")
|
|
@ -0,0 +1,20 @@
|
||||||
|
vl_client.register_capability("ping", 1)
|
||||||
|
|
||||||
|
minetest.register_chatcommand("ping", {
|
||||||
|
params = "<message>",
|
||||||
|
description = "pings the server from the client",
|
||||||
|
func = function(param)
|
||||||
|
minetest.debug("Pinging...")
|
||||||
|
vl_client.send_message("ping", {type="request", content=param})
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
vl_client.register_on_message("ping", function(message)
|
||||||
|
if message.type == "request" then
|
||||||
|
minetest.debug("Client received ping with content:", message.content)
|
||||||
|
vl_client.send_message("ping", {type="response", content=message.content})
|
||||||
|
else
|
||||||
|
minetest.debug("Client received server response to ping with content:", message.content)
|
||||||
|
end
|
||||||
|
end)
|
Loading…
Reference in New Issue