init.lua 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. minetest.register_chatcommand("say", {
  2. params = "<text>",
  3. description = "Say <text> as the server",
  4. privs = {server=true},
  5. func = function(name, param)
  6. minetest.chat_send_all(name .. ": " .. param)
  7. end
  8. })
  9. minetest.register_chatcommand("tell", {
  10. params = "<name> <text>",
  11. description = "Say <text> to <name> privately",
  12. func = function(name, param)
  13. local found, _, target, message = param:find("^([^%s]+)%s+(.*)$")
  14. if found == nil then
  15. minetest.chat_send_player(name, "Invalid usage: " .. param)
  16. return
  17. end
  18. if not minetest.get_player_by_name(target) then
  19. minetest.chat_send_player(name, "Invalid target: " .. target)
  20. end
  21. minetest.chat_send_player(target, name .. " whispers: " .. message, false)
  22. end
  23. })
  24. minetest.register_chatcommand("hp", {
  25. params = "<name> <value>",
  26. description = "Set health of <name> to <value> hitpoints",
  27. privs = {ban=true},
  28. func = function(name, param)
  29. local found, _, target, value = param:find("^([^%s]+)%s+(%d+)$")
  30. if found == nil then
  31. minetest.chat_send_player(name, "Invalid usage: " .. param)
  32. return
  33. end
  34. local player = minetest.get_player_by_name(target)
  35. if player then
  36. player:set_hp(value)
  37. else
  38. minetest.chat_send_player(name, "Invalid target: " .. target)
  39. end
  40. end
  41. })
  42. local function initialize_data(meta)
  43. local commands = minetest.formspec_escape(meta:get_string("commands"))
  44. meta:set_string("formspec",
  45. "invsize[9,5;]" ..
  46. "textarea[0.5,0.5;8.5,4;commands;Commands;"..commands.."]" ..
  47. "label[1,3.8;@nearest, @farthest, and @random are replaced by the respective player names]" ..
  48. "button_exit[3.3,4.5;2,1;submit;Submit]")
  49. local owner = meta:get_string("owner")
  50. if owner == "" then
  51. owner = "not owned"
  52. else
  53. owner = "owned by " .. owner
  54. end
  55. meta:set_string("infotext", "Command Block\n" ..
  56. "(" .. owner .. ")\n" ..
  57. "Commands: "..commands)
  58. end
  59. local function construct(pos)
  60. local meta = minetest.get_meta(pos)
  61. meta:set_string("commands", "tell @nearest Commandblock unconfigured")
  62. meta:set_string("owner", "")
  63. initialize_data(meta)
  64. end
  65. local function after_place(pos, placer)
  66. if placer then
  67. local meta = minetest.get_meta(pos)
  68. meta:set_string("owner", placer:get_player_name())
  69. initialize_data(meta)
  70. end
  71. end
  72. local function receive_fields(pos, formname, fields, sender)
  73. if not fields.submit then
  74. return
  75. end
  76. local meta = minetest.get_meta(pos)
  77. local owner = meta:get_string("owner")
  78. if owner ~= "" and sender:get_player_name() ~= owner then
  79. return
  80. end
  81. meta:set_string("commands", fields.commands)
  82. initialize_data(meta)
  83. end
  84. local function resolve_commands(commands, pos)
  85. local players = minetest.get_connected_players()
  86. -- No players online: remove all commands containing
  87. -- @nearest, @farthest and @random
  88. if #players == 0 then
  89. commands = commands:gsub("[^\r\n]+", function (line)
  90. if line:find("@nearest") then return "" end
  91. if line:find("@farthest") then return "" end
  92. if line:find("@random") then return "" end
  93. return line
  94. end)
  95. return commands
  96. end
  97. local nearest, farthest = nil, nil
  98. local min_distance, max_distance = math.huge, -1
  99. for index, player in pairs(players) do
  100. local distance = vector.distance(pos, player:getpos())
  101. if distance < min_distance then
  102. min_distance = distance
  103. nearest = player:get_player_name()
  104. end
  105. if distance > max_distance then
  106. max_distance = distance
  107. farthest = player:get_player_name()
  108. end
  109. end
  110. local random = players[math.random(#players)]:get_player_name()
  111. commands = commands:gsub("@nearest", nearest)
  112. commands = commands:gsub("@farthest", farthest)
  113. commands = commands:gsub("@random", random)
  114. return commands
  115. end
  116. local function commandblock_action_on(pos, node)
  117. if node.name ~= "mesecons_commandblock:commandblock_off" then
  118. return
  119. end
  120. minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"})
  121. local meta = minetest.get_meta(pos)
  122. local owner = meta:get_string("owner")
  123. if owner == "" then
  124. return
  125. end
  126. local commands = resolve_commands(meta:get_string("commands"), pos)
  127. for _, command in pairs(commands:split("\n")) do
  128. local pos = command:find(" ")
  129. local cmd, param = command, ""
  130. if pos then
  131. cmd = command:sub(1, pos - 1)
  132. param = command:sub(pos + 1)
  133. end
  134. local cmddef = minetest.chatcommands[cmd]
  135. if not cmddef then
  136. minetest.chat_send_player(owner, "The command "..cmd.." does not exist")
  137. return
  138. end
  139. local has_privs, missing_privs = minetest.check_player_privs(owner, cmddef.privs)
  140. if not has_privs then
  141. minetest.chat_send_player(owner, "You don't have permission "
  142. .."to run "..cmd
  143. .." (missing privileges: "
  144. ..table.concat(missing_privs, ", ")..")")
  145. return
  146. end
  147. cmddef.func(owner, param)
  148. end
  149. end
  150. local function commandblock_action_off(pos, node)
  151. if node.name == "mesecons_commandblock:commandblock_on" then
  152. minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_off"})
  153. end
  154. end
  155. local function can_dig(pos, player)
  156. local meta = minetest.get_meta(pos)
  157. local owner = meta:get_string("owner")
  158. return owner == "" or owner == player:get_player_name()
  159. end
  160. minetest.register_node("mesecons_commandblock:commandblock_off", {
  161. description = "Command Block",
  162. tiles = {"jeija_commandblock_off.png"},
  163. inventory_image = minetest.inventorycube("jeija_commandblock_off.png"),
  164. is_ground_content = false,
  165. groups = {cracky=2, mesecon_effector_off=1},
  166. on_construct = construct,
  167. after_place_node = after_place,
  168. on_receive_fields = receive_fields,
  169. can_dig = can_dig,
  170. sounds = default.node_sound_stone_defaults(),
  171. mesecons = {effector = {
  172. action_on = commandblock_action_on
  173. }},
  174. on_blast = mesecon.on_blastnode,
  175. })
  176. minetest.register_node("mesecons_commandblock:commandblock_on", {
  177. tiles = {"jeija_commandblock_on.png"},
  178. is_ground_content = false,
  179. groups = {cracky=2, mesecon_effector_on=1, not_in_creative_inventory=1},
  180. light_source = 10,
  181. drop = "mesecons_commandblock:commandblock_off",
  182. on_construct = construct,
  183. after_place_node = after_place,
  184. on_receive_fields = receive_fields,
  185. can_dig = can_dig,
  186. sounds = default.node_sound_stone_defaults(),
  187. mesecons = {effector = {
  188. action_off = commandblock_action_off
  189. }},
  190. on_blast = mesecon.on_blastnode,
  191. })