jail_token.lua 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. command_tokens = command_tokens or {}
  2. command_tokens.jail = command_tokens.jail or {}
  3. local formspec = "size[4.1,2.0]" ..
  4. default.gui_bg ..
  5. default.gui_bg_img ..
  6. default.gui_slots ..
  7. "label[0,0;Type name of trespasser:]" ..
  8. "field[0.30,0.75;4,1;PLAYERNAME;;]" ..
  9. "button_exit[0,1.30;2,1;OK;Confirm]" ..
  10. "button_exit[2,1.30;2,1;CANCEL;Cancel]" ..
  11. "field_close_on_enter[PLAYERNAME;true]"
  12. -- Called when the player uses a jail token.
  13. command_tokens.jail.jail_player = function(itemstack, user, pointed)
  14. if user and user:is_player() then
  15. local pname = user:get_player_name()
  16. if pointed.type == "object" then
  17. local object = pointed.ref
  18. if object and object:is_player() then
  19. local success = command_tokens.jail.execute(
  20. pname, object:get_player_name())
  21. if success then
  22. itemstack:take_item()
  23. return itemstack
  24. end
  25. else
  26. minetest.chat_send_player(pname, "# Server: Target is not a player!")
  27. end
  28. else
  29. minetest.show_formspec(pname, "command_tokens:jail", formspec)
  30. end
  31. end
  32. end
  33. local function is_valid_target(name, target)
  34. if minetest.get_player_by_name(target) then
  35. if not minetest.check_player_privs(target, {ignore_jail_token=true}) then
  36. return true
  37. end
  38. end
  39. return false
  40. end
  41. command_tokens.jail.execute = function(player, target)
  42. player = rename.grn(player)
  43. target = rename.grn(target)
  44. if not minetest.get_player_by_name(target) then
  45. minetest.chat_send_player(player, "# Server: Law enforcement couldn't find player <" .. rename.gpn(target) .. ">.")
  46. return
  47. end
  48. local pref = minetest.get_player_by_name(player)
  49. local p1 = pref:get_pos()
  50. local p2 = minetest.get_player_by_name(target):get_pos()
  51. if not rc.same_realm(p1, p2) then
  52. minetest.chat_send_player(player, "# Server: Target is in another dimension!")
  53. return
  54. end
  55. local self_arrest = false
  56. if player == target then
  57. --minetest.chat_send_player(player, "# Server: Law-enforcement does not arrest self-trespassers.")
  58. --return
  59. self_arrest = true
  60. end
  61. -- Allow self-arrest.
  62. if player ~= target then
  63. if not is_valid_target(player, target) then
  64. minetest.chat_send_player(player, "# Server: Player <" .. rename.gpn(target) .. "> is immune to accusations of trespassing.")
  65. return
  66. end
  67. end
  68. local ent = minetest.get_player_by_name(target)
  69. -- 'ent' should always be valid.
  70. local pos = ent:get_pos()
  71. local landowner = false
  72. -- If position is protected, and player has access, then player owns the land.
  73. if minetest.test_protection(pos, "") and
  74. not minetest.test_protection(pos, player) then
  75. landowner = true
  76. end
  77. if not city_block:in_city(pos) then
  78. minetest.chat_send_player(player, "# Server: Trespasser is not within city boundaries.")
  79. return
  80. end
  81. if not landowner then
  82. minetest.chat_send_player(player, "# Server: Player <" .. rename.gpn(target) .. "> is not in territory owned by you.")
  83. return
  84. end
  85. -- Ensure player has a jail token in their inventory.
  86. do
  87. local pinv = pref:get_inventory()
  88. local stack = ItemStack("command_tokens:jail_player")
  89. if not pinv:contains_item("main", stack) then
  90. return
  91. end
  92. end
  93. -- Get player out of cart.
  94. local kicktype = default.detach_player_if_attached(ent)
  95. if kicktype == "cart" then
  96. minetest.chat_send_all("# Server: Someone threw <" .. rename.gpn(target) .. "> out of a minecart.")
  97. elseif kicktype == "boat" then
  98. minetest.chat_send_all("# Server: Boater <" .. rename.gpn(target) .. "> was tossed overboard.")
  99. elseif kicktype == "sled" then
  100. minetest.chat_send_all("# Server: Someone kicked <" .. rename.gpn(target) .. "> off a sled.")
  101. elseif kicktype == "bed" then
  102. local formspec = "size[8,15;true]" ..
  103. "bgcolor[#080808BB; true]" ..
  104. "button_exit[2,12;4,0.75;leave;Ok]" ..
  105. "label[2.7,11;You were kicked out of bed!]"
  106. minetest.show_formspec(target, "command_tokens:bedkicked", formspec)
  107. minetest.chat_send_all("# Server: <" .. rename.gpn(target) .. "> was rudely kicked out of bed.")
  108. end
  109. local jaildelay = 0
  110. if kicktype ~= "" then
  111. jaildelay = 1
  112. end
  113. -- Not sure why the delay is necessary, but it may have to do with lag.
  114. minetest.after(jaildelay, function()
  115. if not default.player_attached[target] then
  116. local bcb = function()
  117. if self_arrest then
  118. minetest.chat_send_all("# Server: Player <" .. rename.gpn(target) .. "> committed self-arrest.")
  119. else
  120. minetest.chat_send_all("# Server: Player <" .. rename.gpn(target) .. "> sent to jail for trespassing on <" .. rename.gpn(player) .. ">'s land.")
  121. end
  122. end
  123. if not jail.go_to_jail(minetest.get_player_by_name(target), bcb) then
  124. minetest.chat_send_player(player, "# Server: There's no law enforcement to speak of!")
  125. end
  126. else
  127. minetest.chat_send_player(player, "# Server: Player <" .. rename.gpn(target) .. "> could not be detached!")
  128. end
  129. end)
  130. -- Caller must consume token.
  131. return true
  132. end
  133. command_tokens.jail_on_receive_fields = function(player, formname, fields)
  134. if formname == "command_tokens:jail" then
  135. if fields.key_enter_field == "PLAYERNAME" or fields.OK then
  136. local pname = player:get_player_name()
  137. local success = command_tokens.jail.execute(
  138. pname, fields.PLAYERNAME or "")
  139. if success then
  140. local inv = player:get_inventory()
  141. if inv then
  142. inv:remove_item("main", "command_tokens:jail_player")
  143. end
  144. end
  145. end
  146. end
  147. end
  148. -- Register once only.
  149. if not command_tokens.jail.registered then
  150. minetest.register_privilege("ignore_jail_token", {
  151. description = "Player cannot be sent to jail.",
  152. give_to_singleplayer = false,
  153. })
  154. minetest.register_on_player_receive_fields(function(...)
  155. return command_tokens.jail_on_receive_fields(...)
  156. end)
  157. command_tokens.jail.registered = true
  158. end