antispawn.lua 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. local PLAYERS_MSG = {}
  2. local PLAYERS_FREQ = {}
  3. local SPAM_SPEED = 5
  4. local SPAM_SPEED_MSECS = SPAM_SPEED * 1e6
  5. local SPAM_WARN = 5
  6. -- In seconds
  7. local SPAM_KICK = SPAM_WARN + 5
  8. local RESET_TIME = 30
  9. -- Convert to microsecs
  10. local RESET_TIME_MSECS = RESET_TIME * 1e6
  11. local WARNING_COLOR = minetest.get_color_escape_sequence"#FFBB33"
  12. minetest.register_on_leaveplayer(function(player)
  13. PLAYERS_MSG[player:get_player_name()] = nil
  14. PLAYERS_FREQ[player:get_player_name()] = nil
  15. end)
  16. minetest.register_on_joinplayer(function(player)
  17. PLAYERS_MSG[player:get_player_name()] = {}
  18. end)
  19. minetest.register_on_chat_message(function(name, message)
  20. for msg, info in pairs(PLAYERS_MSG[name]) do
  21. if minetest.get_us_time() - info[2] >= RESET_TIME_MSECS then PLAYERS_MSG[name][msg] = nil end
  22. end
  23. if PLAYERS_MSG[name][message] then
  24. local amount = PLAYERS_MSG[name][message][1] + 1
  25. PLAYERS_MSG[name][message][1] = amount
  26. PLAYERS_MSG[name][message][2] = minetest.get_us_time()
  27. if amount >= SPAM_KICK then minetest.kick_player(name, "Kicked for spamming.")
  28. elseif amount >= SPAM_WARN then
  29. minetest.chat_send_player(name, WARNING_COLOR .. "Warning! You've sent the message '" .. message .. "' too often. Wait at least " .. RESET_TIME .. " seconds before sending it again.")
  30. end
  31. else PLAYERS_MSG[name][message] = { 1, minetest.get_us_time() } end
  32. if not PLAYERS_FREQ[name] then
  33. PLAYERS_FREQ[name] = {
  34. 0,
  35. 0,
  36. minetest.get_us_time(),
  37. 0
  38. }
  39. return
  40. end
  41. local warns = PLAYERS_FREQ[name][4]
  42. local amount = PLAYERS_FREQ[name][2]
  43. local speed = PLAYERS_FREQ[name][1]
  44. local delay = minetest.get_us_time() - PLAYERS_FREQ[name][3]
  45. speed = (speed * amount + delay) / (amount + 1)
  46. if amount >= SPAM_WARN then
  47. if warns + 1 == SPAM_KICK - SPAM_WARN then minetest.kick_player(name, "Kicked for spamming.")
  48. elseif speed <= SPAM_SPEED_MSECS then
  49. minetest.chat_send_player(name, WARNING_COLOR .. "Warning! You are sending messages too fast. Wait at least " .. SPAM_SPEED .. " seconds before sending another message.")
  50. warns = warns + 1
  51. speed = SPAM_SPEED_MSECS
  52. amount = SPAM_WARN
  53. else
  54. speed = 0
  55. amount = 0
  56. warns = 0
  57. end
  58. end
  59. PLAYERS_FREQ[name] = {
  60. speed,
  61. amount + 1,
  62. minetest.get_us_time(),
  63. warns
  64. }
  65. end)