mute_token.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. command_tokens = command_tokens or {}
  2. command_tokens.mute = command_tokens.mute or {}
  3. command_tokens.mute.players = command_tokens.mute.players or {}
  4. local mute_duration = 60*10 -- Time in seconds.
  5. -- Localize for performance.
  6. local math_random = math.random
  7. local formspec = "size[4.1,2.0]" ..
  8. default.gui_bg ..
  9. default.gui_bg_img ..
  10. default.gui_slots ..
  11. "label[0,0;Need name to mute for " .. mute_duration/60 .. " minutes:]" ..
  12. "field[0.30,0.75;4,1;PLAYERNAME;;]" ..
  13. "button_exit[0,1.30;2,1;OK;Confirm]" ..
  14. "button_exit[2,1.30;2,1;CANCEL;Cancel]" ..
  15. "field_close_on_enter[PLAYERNAME;false]"
  16. command_tokens.mute.player_muted = function(player)
  17. if command_tokens.mute.players[player] then
  18. return true
  19. else
  20. return false
  21. end
  22. end
  23. -- Called when the player uses a marker token.
  24. command_tokens.mute.mute_player = function(itemstack, user, pointed)
  25. if user and user:is_player() then
  26. if pointed.type == "object" then
  27. local object = pointed.ref
  28. if object and object:is_player() then
  29. command_tokens.mute.execute(user:get_player_name(), object:get_player_name())
  30. else
  31. minetest.chat_send_player(user:get_player_name(), "# Server: Target is not a player!")
  32. end
  33. else
  34. local name = user:get_player_name()
  35. minetest.show_formspec(name, "command_tokens:mute", formspec)
  36. end
  37. end
  38. end
  39. local function unmute_on_timeout(target, rng)
  40. if command_tokens.mute.players[target] then
  41. -- This delayed callback only works if rng number matches.
  42. if command_tokens.mute.players[target] == rng then
  43. local dname = rename.gpn(target)
  44. minetest.chat_send_all("# Server: Player <" .. dname .. ">'s chat has been restored.")
  45. command_tokens.mute.players[target] = nil
  46. end
  47. end
  48. end
  49. local function is_valid_target(target)
  50. if minetest.get_player_by_name(target) then
  51. if not minetest.check_player_privs(target, {server=true}) and
  52. not minetest.check_player_privs(target, {nomute=true}) then
  53. return true
  54. end
  55. end
  56. end
  57. command_tokens.mute.execute = function(player, target)
  58. player = rename.grn(player)
  59. target = rename.grn(target)
  60. local dname = rename.gpn(target)
  61. if is_valid_target(target) then
  62. -- Mute player if they wern't muted, unmute them if they were.
  63. if not command_tokens.mute.players[target] then
  64. -- Mark this occurance with an ID that isn't likely to be already in use.
  65. local rng = math_random(0, 65000)
  66. command_tokens.mute.players[target] = rng
  67. minetest.after(mute_duration, unmute_on_timeout, target, rng)
  68. minetest.chat_send_all("# Server: Player <" .. dname .. ">'s chat has been duct-taped!")
  69. minetest.log("action", player .. " applies ducktape to " .. target)
  70. else
  71. command_tokens.mute.players[target] = nil
  72. minetest.chat_send_all("# Server: Player <" .. dname .. "> was unmuted.")
  73. minetest.log("action", player .. " unmutes " .. target)
  74. end
  75. -- Consume token.
  76. minetest.after(0, function() -- Necessary because this code will not operate during the on_use callback.
  77. local ref = minetest.get_player_by_name(player)
  78. if ref and ref:is_player() then
  79. local inv = ref:get_inventory()
  80. inv:remove_item("main", "command_tokens:mute_player")
  81. end
  82. end)
  83. else
  84. -- Target not found. Restore the player's marker.
  85. minetest.chat_send_player(player, "# Server: Player <" .. dname .. "> cannot be silenced.")
  86. end
  87. end
  88. command_tokens.mute_on_receive_fields = function(player, formname, fields)
  89. if formname == "command_tokens:mute" then
  90. if fields.OK then
  91. command_tokens.mute.execute(player:get_player_name(), fields.PLAYERNAME or "")
  92. end
  93. end
  94. end
  95. -- Register once only.
  96. if not command_tokens.mute.registered then
  97. minetest.register_on_player_receive_fields(function(...)
  98. return command_tokens.mute_on_receive_fields(...)
  99. end)
  100. minetest.register_privilege("nomute", {
  101. description = "Player is immune to being muted.",
  102. give_to_singleplayer = false,
  103. })
  104. command_tokens.mute.registered = true
  105. end