information_formspecs.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. local COLOR_BLUE = "#7AF"
  2. local COLOR_GREEN = "#7F7"
  3. local COLOR_GRAY = "#BBB"
  4. local LIST_FORMSPEC = [[
  5. size[13,6.5]
  6. label[0,-0.1;%s]
  7. tablecolumns[color;tree;text;text]
  8. table[0,0.5;12.8,5.5;list;%s;0]
  9. button_exit[5,6;3,1;quit;%s]
  10. ]]
  11. local LIST_FORMSPEC_DESCRIPTION = [[
  12. size[13,7.5]
  13. label[0,-0.1;%s]
  14. tablecolumns[color;tree;text;text]
  15. table[0,0.5;12.8,4.8;list;%s;%i]
  16. box[0,5.5;12.8,1.5;#000]
  17. textarea[0.3,5.5;13.05,1.9;;;%s]
  18. button_exit[5,7;3,1;quit;%s]
  19. ]]
  20. local formspec_escape = core.formspec_escape
  21. local check_player_privs = core.check_player_privs
  22. -- CHAT COMMANDS FORMSPEC
  23. local mod_cmds = {}
  24. local function load_mod_command_tree()
  25. mod_cmds = {}
  26. for name, def in pairs(core.registered_chatcommands) do
  27. mod_cmds[def.mod_origin] = mod_cmds[def.mod_origin] or {}
  28. local cmds = mod_cmds[def.mod_origin]
  29. -- Could be simplified, but avoid the priv checks whenever possible
  30. cmds[#cmds + 1] = { name, def }
  31. end
  32. local sorted_mod_cmds = {}
  33. for modname, cmds in pairs(mod_cmds) do
  34. table.sort(cmds, function(a, b) return a[1] < b[1] end)
  35. sorted_mod_cmds[#sorted_mod_cmds + 1] = { modname, cmds }
  36. end
  37. table.sort(sorted_mod_cmds, function(a, b) return a[1] < b[1] end)
  38. mod_cmds = sorted_mod_cmds
  39. end
  40. core.after(0, load_mod_command_tree)
  41. local function build_chatcommands_formspec(name, sel, copy)
  42. local rows = {}
  43. rows[1] = "#FFF,0,Command,Parameters"
  44. local description = "For more information, click on any entry in the list.\n" ..
  45. "Double-click to copy the entry to the chat history."
  46. for i, data in ipairs(mod_cmds) do
  47. rows[#rows + 1] = COLOR_BLUE .. ",0," .. formspec_escape(data[1]) .. ","
  48. for j, cmds in ipairs(data[2]) do
  49. local has_priv = check_player_privs(name, cmds[2].privs)
  50. rows[#rows + 1] = ("%s,1,%s,%s"):format(
  51. has_priv and COLOR_GREEN or COLOR_GRAY,
  52. cmds[1], formspec_escape(cmds[2].params))
  53. if sel == #rows then
  54. description = cmds[2].description
  55. if copy then
  56. core.chat_send_player(name, ("Command: %s %s"):format(
  57. core.colorize("#0FF", "/" .. cmds[1]), cmds[2].params))
  58. end
  59. end
  60. end
  61. end
  62. return LIST_FORMSPEC_DESCRIPTION:format(
  63. "Available commands: (see also: /help <cmd>)",
  64. table.concat(rows, ","), sel or 0,
  65. description, "Close"
  66. )
  67. end
  68. -- PRIVILEGES FORMSPEC
  69. local function build_privs_formspec(name)
  70. local privs = {}
  71. for priv_name, def in pairs(core.registered_privileges) do
  72. privs[#privs + 1] = { priv_name, def }
  73. end
  74. table.sort(privs, function(a, b) return a[1] < b[1] end)
  75. local rows = {}
  76. rows[1] = "#FFF,0,Privilege,Description"
  77. local player_privs = core.get_player_privs(name)
  78. for i, data in ipairs(privs) do
  79. rows[#rows + 1] = ("%s,0,%s,%s"):format(
  80. player_privs[data[1]] and COLOR_GREEN or COLOR_GRAY,
  81. data[1], formspec_escape(data[2].description))
  82. end
  83. return LIST_FORMSPEC:format(
  84. "Available privileges:",
  85. table.concat(rows, ","),
  86. "Close"
  87. )
  88. end
  89. -- DETAILED CHAT COMMAND INFORMATION
  90. core.register_on_player_receive_fields(function(player, formname, fields)
  91. if formname ~= "__builtin:help_cmds" or fields.quit then
  92. return
  93. end
  94. local event = minetest.explode_table_event(fields.list)
  95. if event.type ~= "INV" then
  96. local name = player:get_player_name()
  97. core.show_formspec(name, "__builtin:help_cmds",
  98. build_chatcommands_formspec(name, event.row, event.type == "DCL"))
  99. end
  100. end)
  101. local help_command = core.registered_chatcommands["help"]
  102. local old_help_func = help_command.func
  103. help_command.func = function(name, param)
  104. local admin = core.settings:get("name")
  105. -- If the admin ran help, put the output in the chat buffer as well to
  106. -- work with the server terminal
  107. if param == "privs" then
  108. core.show_formspec(name, "__builtin:help_privs",
  109. build_privs_formspec(name))
  110. if name ~= admin then
  111. return true
  112. end
  113. end
  114. if param == "" or param == "all" then
  115. core.show_formspec(name, "__builtin:help_cmds",
  116. build_chatcommands_formspec(name))
  117. if name ~= admin then
  118. return true
  119. end
  120. end
  121. return old_help_func(name, param)
  122. end