mute_token.lua 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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;true]"
  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. local pname = user:get_player_name()
  27. if pointed.type == "object" then
  28. local object = pointed.ref
  29. if object and object:is_player() then
  30. local success = command_tokens.mute.execute(
  31. pname, object:get_player_name())
  32. if success then
  33. itemstack:take_item()
  34. return itemstack
  35. end
  36. else
  37. minetest.chat_send_player(pname, "# Server: Target is not a player!")
  38. end
  39. else
  40. minetest.show_formspec(pname, "command_tokens:mute", formspec)
  41. end
  42. end
  43. end
  44. local function unmute_on_timeout(target, rng)
  45. if command_tokens.mute.players[target] then
  46. -- This delayed callback only works if rng number matches.
  47. if command_tokens.mute.players[target] == rng then
  48. local dname = rename.gpn(target)
  49. minetest.chat_send_all("# Server: Player <" .. dname .. ">'s chat has been restored.")
  50. command_tokens.mute.players[target] = nil
  51. end
  52. end
  53. end
  54. local function is_valid_target(target)
  55. if minetest.get_player_by_name(target) then
  56. if not minetest.check_player_privs(target, {server=true}) and
  57. not minetest.check_player_privs(target, {nomute=true}) then
  58. return true
  59. end
  60. end
  61. end
  62. command_tokens.mute.execute = function(player, target)
  63. player = rename.grn(player)
  64. target = rename.grn(target)
  65. local dname = rename.gpn(target)
  66. if is_valid_target(target) then
  67. -- Ensure player has a mute token in their inventory.
  68. local pref = minetest.get_player_by_name(player)
  69. local pinv = pref:get_inventory()
  70. local stack = ItemStack("command_tokens:mute_player")
  71. if pinv:contains_item("main", stack) then
  72. -- Mute player if they wern't muted, unmute them if they were.
  73. if not command_tokens.mute.players[target] then
  74. -- Mark this occurance with an ID that isn't likely to be already in use.
  75. local rng = math_random(0, 65000)
  76. command_tokens.mute.players[target] = rng
  77. minetest.after(mute_duration, unmute_on_timeout, target, rng)
  78. minetest.chat_send_all("# Server: Player <" .. dname .. ">'s chat has been duct-taped!")
  79. minetest.log("action", player .. " applies ducktape to " .. target)
  80. else
  81. command_tokens.mute.players[target] = nil
  82. minetest.chat_send_all("# Server: Player <" .. dname .. "> was unmuted.")
  83. minetest.log("action", player .. " unmutes " .. target)
  84. end
  85. -- Caller must consume token.
  86. return true
  87. else
  88. minetest.chat_send_player(player, "# Server: Error. Invalid usage.")
  89. end
  90. else
  91. -- Target not found.
  92. minetest.chat_send_player(player, "# Server: Player <" .. dname .. "> cannot be silenced.")
  93. end
  94. end
  95. command_tokens.mute_on_receive_fields = function(player, formname, fields)
  96. if formname == "command_tokens:mute" then
  97. if fields.key_enter_field == "PLAYERNAME" or fields.OK then
  98. local pname = player:get_player_name()
  99. local success = command_tokens.mute.execute(
  100. pname, fields.PLAYERNAME or "")
  101. if success then
  102. local inv = player:get_inventory()
  103. if inv then
  104. inv:remove_item("main", "command_tokens:mute_player")
  105. end
  106. end
  107. end
  108. end
  109. end
  110. -- Register once only.
  111. if not command_tokens.mute.registered then
  112. minetest.register_on_player_receive_fields(function(...)
  113. return command_tokens.mute_on_receive_fields(...)
  114. end)
  115. minetest.register_privilege("nomute", {
  116. description = "Player is immune to being muted.",
  117. give_to_singleplayer = false,
  118. })
  119. command_tokens.mute.registered = true
  120. end