mute_token.lua 3.9 KB

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