Proof-of-concept Server-Sent CSMs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sscsm_init.lua 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. --
  2. -- SSCSM: Server-Sent Client-Side Mods proof-of-concept
  3. -- Initial code sent to the client
  4. --
  5. -- © 2019 by luk3yx
  6. --
  7. -- Make sure table.unpack exists
  8. if table.unpack then
  9. unpack = table.unpack
  10. else
  11. table.unpack = unpack
  12. end
  13. -- Make sure a few basic functions exist, these may have been blocked because
  14. -- of security or laziness.
  15. if not rawget then function rawget(n, name) return n[name] end end
  16. if not rawset then function rawset(n, k, v) n[k] = v end end
  17. if not rawequal then function rawequal(a, b) return a == b end end
  18. if not assert then
  19. function assert(value, err)
  20. if not value then
  21. error(err or 'Assertion failed!', 2)
  22. end
  23. return value
  24. end
  25. end
  26. -- Create the API
  27. sscsm = {}
  28. function sscsm.global_exists(name)
  29. return rawget(_G, name) ~= nil
  30. end
  31. if not sscsm.global_exists('minetest') then
  32. minetest = assert(core, 'No "minetest" global found!')
  33. end
  34. core = nil
  35. minetest.global_exists = sscsm.global_exists
  36. -- Check if join_mod_channel and leave_mod_channel exist.
  37. if sscsm.global_exists('join_mod_channel')
  38. and sscsm.global_exists('leave_mod_channel') then
  39. sscsm.join_mod_channel = join_mod_channel
  40. sscsm.leave_mod_channel = leave_mod_channel
  41. join_mod_channel, leave_mod_channel = nil, nil
  42. else
  43. local dummy = function() end
  44. sscsm.join_mod_channel = dummy
  45. sscsm.leave_mod_channel = dummy
  46. end
  47. -- Add print()
  48. function print(...)
  49. local msg = '[SSCSM] '
  50. for i = 1, select('#', ...) do
  51. if i > 1 then msg = msg .. '\t' end
  52. msg = msg .. tostring(select(i, ...))
  53. end
  54. minetest.log('none', msg)
  55. end
  56. print('Hello from the server-sent CSMs!')
  57. -- Add register_on_mods_loaded
  58. do
  59. local funcs = {}
  60. function sscsm.register_on_mods_loaded(callback)
  61. if funcs then table.insert(funcs, callback) end
  62. end
  63. function sscsm._done_loading_()
  64. sscsm._done_loading_ = nil
  65. for _, func in ipairs(funcs) do func() end
  66. funcs = nil
  67. end
  68. end
  69. sscsm.register_on_mods_loaded(function()
  70. print('SSCSMs loaded, leaving mod channel.')
  71. sscsm.leave_mod_channel()
  72. end)
  73. -- Helper functions
  74. if not minetest.get_node then
  75. function minetest.get_node(pos)
  76. return minetest.get_node_or_nil(pos) or {name = 'ignore', param1 = 0,
  77. param2 = 0}
  78. end
  79. end
  80. -- Make minetest.run_server_chatcommand allow param to be unspecified.
  81. function minetest.run_server_chatcommand(cmd, param)
  82. minetest.send_chat_message('/' .. cmd .. ' ' .. (param or ''))
  83. end
  84. -- Register "server-side" chatcommands
  85. -- Can allow instantaneous responses in some cases.
  86. sscsm.registered_chatcommands = {}
  87. local function on_chat_message(msg)
  88. if msg:sub(1, 1) ~= '/' then return false end
  89. local cmd, param = msg:match('^/([^ ]+) *(.*)')
  90. if not cmd then
  91. minetest.display_chat_message('-!- Empty command')
  92. return true
  93. end
  94. if not sscsm.registered_chatcommands[cmd] then return false end
  95. local _, res = sscsm.registered_chatcommands[cmd].func(param or '')
  96. if res then minetest.display_chat_message(tostring(res)) end
  97. return true
  98. end
  99. function sscsm.register_chatcommand(cmd, def)
  100. if type(def) == 'function' then
  101. def = {func = def}
  102. elseif type(def.func) ~= 'function' then
  103. error('Invalid definition passed to sscsm.register_chatcommand.')
  104. end
  105. sscsm.registered_chatcommands[cmd] = def
  106. if on_chat_message then
  107. minetest.register_on_sending_chat_message(on_chat_message)
  108. on_chat_message = false
  109. end
  110. end
  111. function sscsm.unregister_chatcommand(cmd)
  112. sscsm.registered_chatcommands[cmd] = nil
  113. end