SSCSM

MultiCraft has a built-in SSCSM implementation that will load SSCSMs onto MultiCraft clients, as well as non-MultiCraft clients if they have the correct CSM installed.

Server-side API

  • sscsm.register(SSCSM definition table):
    • Registers a server-provided CSM with an [SSCSM definition table].
  • sscsm.register_on_sscsms_loaded(function(name)):
    • Registers a callback that will be called when SSCSMs have been loaded on a client.
  • sscsm.has_sscsms_enabled(name):
    • Returns a boolean.
    • Returns true if the client supports SSCSMs and SSCSMs have been loaded.
    • Note that this will not return true immediately after joining.
  • sscsm.com_send(player_or_name, channel, msg):
    • Sends a com message to a specific client.
    • msg can be any object that can be serialized with JSON.
  • sscsm.com_send_all(channel, msg):
    • Sends a com message to all clients.
  • sscsm.register_on_com_receive(channel, function(name, msg)):
    • Registers a function to be called when a message on channel is received from the client.
    • Note that msg may be any JSON-compatible type, so checking the type of this object is strongly recommended.

Client-side API

SSCSMs have access most of the API functions mentioned in client_lua_api.txt, along with an extra sscsm namespace:

  • sscsm.register_on_mods_loaded(function()):
    • Runs the provided callback once all SSCSMs are loaded.
  • sscsm.register_chatcommand(command, function(param)):
    • Similar to core.register_chatcommand, however overrides commands starting in / instead. This can be used to make some commands have instantaneous responses.
  • sscsm.unregister_chatcommand(command):
    • Unregisters a chatcommand.
  • sscsm.get_player_control():
    • Returns a table similar to the server-side player:get_player_control().
  • sscsm.every(interval, func, ...):
    • Calls func every interval seconds with any extra parameters specified.
    • Use core.register_globalstep instead if interval is zero.
  • sscsm.com_send(channel, msg):
    • Sends msg (a JSON-compatible object) to the server.
    • Note that client-to-server messages cannot be long, for plain strings the channel and message combined must be at most 492 characters.
  • sscsm.register_on_com_receive(channel, function(msg)):
    • Registers a function to be called when a message on channel is received from the server.

This namespace has the following constants:

  • sscsm.restriction_flags:
    • The csm_restriction_flags setting set in the server's multicraft.conf.
  • sscsm.restrictions: A table based on csm_restriction_flags:
    • chat_messages: When true, SSCSMs can't send chat messages or run server chatcommands.
    • read_itemdefs: When true, SSCSMs can't read item definitions.
    • read_nodedefs: When true, SSCSMs can't read node definitions.
    • lookup_nodes_limit: When true, any get_node calls are restricted.
    • read_playerinfo: When true, core.get_player_names() will return nil.

SSCSM definition table

sscsm.register({
    -- The name of the server-provided CSM. Using `modname` or
    -- `modname:sscsmname` is strongly recommended. This name cannot start with
    -- a colon or contain newlines.
    name = "mymod",

    -- The code to be sent to clients.
    -- code = "print('Hello world!')",

    -- The file to read code from.
    -- This should be used instead of `code`.
    file = core.get_modpath("mymod") .. DIR_DELIM .. "sscsm.lua",

    -- An optional list of SSCSMs that this one depends on.
    -- depends = {"othermod"},
})

Security considerations

Do not trust any input sent to the server via SSCSMs (and do not store sensitive data in SSCSM code), as malicious users can and will inspect code and modify the output from SSCSMs.

I repeat, do not trust the client and/or SSCSMs with any sensitive information and do not trust any output from the client and/or SSCSMs. Make sure you rerun any privilege checks on the server.