dlg_config_world.lua 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. --Minetest
  2. --Copyright (C) 2013 sapier
  3. --
  4. --This program is free software; you can redistribute it and/or modify
  5. --it under the terms of the GNU Lesser General Public License as published by
  6. --the Free Software Foundation; either version 2.1 of the License, or
  7. --(at your option) any later version.
  8. --
  9. --This program is distributed in the hope that it will be useful,
  10. --but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. --MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. --GNU Lesser General Public License for more details.
  13. --
  14. --You should have received a copy of the GNU Lesser General Public License along
  15. --with this program; if not, write to the Free Software Foundation, Inc.,
  16. --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. --------------------------------------------------------------------------------
  18. local enabled_all = false
  19. local function modname_valid(name)
  20. return not name:find("[^a-z0-9_]")
  21. end
  22. local function init_data(data)
  23. data.list = filterlist.create(
  24. pkgmgr.preparemodlist,
  25. pkgmgr.comparemod,
  26. function(element, uid)
  27. if element.name == uid then
  28. return true
  29. end
  30. end,
  31. function(element, criteria)
  32. if criteria.hide_game and
  33. element.is_game_content then
  34. return false
  35. end
  36. if criteria.hide_modpackcontents and
  37. element.modpack ~= nil then
  38. return false
  39. end
  40. return true
  41. end,
  42. {
  43. worldpath = data.worldspec.path,
  44. gameid = data.worldspec.gameid
  45. })
  46. if data.selected_mod > data.list:size() then
  47. data.selected_mod = 0
  48. end
  49. data.list:set_filtercriteria({
  50. hide_game = data.hide_gamemods,
  51. hide_modpackcontents = data.hide_modpackcontents
  52. })
  53. data.list:add_sort_mechanism("alphabetic", sort_mod_list)
  54. data.list:set_sortmode("alphabetic")
  55. end
  56. local function get_formspec(data)
  57. if not data.list then
  58. init_data(data)
  59. end
  60. local mod = data.list:get_list()[data.selected_mod] or {name = ""}
  61. local retval =
  62. "size[11.5,7.5,true]" ..
  63. "label[0.5,0;" .. fgettext("World:") .. "]" ..
  64. "label[1.75,0;" .. data.worldspec.name .. "]"
  65. if mod.is_modpack or mod.type == "game" then
  66. local info = core.formspec_escape(
  67. core.get_content_info(mod.path).description)
  68. if info == "" then
  69. if mod.is_modpack then
  70. info = fgettext("No modpack description provided.")
  71. else
  72. info = fgettext("No game description provided.")
  73. end
  74. end
  75. retval = retval ..
  76. "textarea[0.25,0.7;5.75,7.2;;" .. info .. ";]"
  77. else
  78. local hard_deps, soft_deps = pkgmgr.get_dependencies(mod.path)
  79. local hard_deps_str = table.concat(hard_deps, ",")
  80. local soft_deps_str = table.concat(soft_deps, ",")
  81. retval = retval ..
  82. "label[0,0.7;" .. fgettext("Mod:") .. "]" ..
  83. "label[0.75,0.7;" .. mod.name .. "]"
  84. if hard_deps_str == "" then
  85. if soft_deps_str == "" then
  86. retval = retval ..
  87. "label[0,1.25;" ..
  88. fgettext("No (optional) dependencies") .. "]"
  89. else
  90. retval = retval ..
  91. "label[0,1.25;" .. fgettext("No hard dependencies") ..
  92. "]" ..
  93. "label[0,1.75;" .. fgettext("Optional dependencies:") ..
  94. "]" ..
  95. "textlist[0,2.25;5,4;world_config_optdepends;" ..
  96. soft_deps_str .. ";0]"
  97. end
  98. else
  99. if soft_deps_str == "" then
  100. retval = retval ..
  101. "label[0,1.25;" .. fgettext("Dependencies:") .. "]" ..
  102. "textlist[0,1.75;5,4;world_config_depends;" ..
  103. hard_deps_str .. ";0]" ..
  104. "label[0,6;" .. fgettext("No optional dependencies") .. "]"
  105. else
  106. retval = retval ..
  107. "label[0,1.25;" .. fgettext("Dependencies:") .. "]" ..
  108. "textlist[0,1.75;5,2.125;world_config_depends;" ..
  109. hard_deps_str .. ";0]" ..
  110. "label[0,3.9;" .. fgettext("Optional dependencies:") ..
  111. "]" ..
  112. "textlist[0,4.375;5,1.8;world_config_optdepends;" ..
  113. soft_deps_str .. ";0]"
  114. end
  115. end
  116. end
  117. retval = retval ..
  118. "button[3.25,7;2.5,0.5;btn_config_world_save;" ..
  119. fgettext("Save") .. "]" ..
  120. "button[5.75,7;2.5,0.5;btn_config_world_cancel;" ..
  121. fgettext("Cancel") .. "]" ..
  122. "button[9,7;2.5,0.5;btn_config_world_cdb;" ..
  123. fgettext("Find More Mods") .. "]"
  124. if mod.name ~= "" and not mod.is_game_content then
  125. if mod.is_modpack then
  126. if pkgmgr.is_modpack_entirely_enabled(data, mod.name) then
  127. retval = retval ..
  128. "button[5.5,0.125;3,0.5;btn_mp_disable;" ..
  129. fgettext("Disable modpack") .. "]"
  130. else
  131. retval = retval ..
  132. "button[5.5,0.125;3,0.5;btn_mp_enable;" ..
  133. fgettext("Enable modpack") .. "]"
  134. end
  135. else
  136. retval = retval ..
  137. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") ..
  138. ";" .. tostring(mod.enabled) .. "]"
  139. end
  140. end
  141. if enabled_all then
  142. retval = retval ..
  143. "button[8.95,0.125;2.5,0.5;btn_disable_all_mods;" ..
  144. fgettext("Disable all") .. "]"
  145. else
  146. retval = retval ..
  147. "button[8.95,0.125;2.5,0.5;btn_enable_all_mods;" ..
  148. fgettext("Enable all") .. "]"
  149. end
  150. return retval ..
  151. "tablecolumns[color;tree;text]" ..
  152. "table[5.5,0.75;5.75,6;world_config_modlist;" ..
  153. pkgmgr.render_packagelist(data.list) .. ";" .. data.selected_mod .."]"
  154. end
  155. local function handle_buttons(this, fields)
  156. if fields.world_config_modlist then
  157. local event = core.explode_table_event(fields.world_config_modlist)
  158. this.data.selected_mod = event.row
  159. core.settings:set("world_config_selected_mod", event.row)
  160. if event.type == "DCL" then
  161. pkgmgr.enable_mod(this)
  162. end
  163. return true
  164. end
  165. if fields.key_enter then
  166. pkgmgr.enable_mod(this)
  167. return true
  168. end
  169. if fields.cb_mod_enable ~= nil then
  170. pkgmgr.enable_mod(this, core.is_yes(fields.cb_mod_enable))
  171. return true
  172. end
  173. if fields.btn_mp_enable ~= nil or
  174. fields.btn_mp_disable then
  175. pkgmgr.enable_mod(this, fields.btn_mp_enable ~= nil)
  176. return true
  177. end
  178. if fields.btn_config_world_save then
  179. local filename = this.data.worldspec.path .. DIR_DELIM .. "world.mt"
  180. local worldfile = Settings(filename)
  181. local mods = worldfile:to_table()
  182. local rawlist = this.data.list:get_raw_list()
  183. for i = 1, #rawlist do
  184. local mod = rawlist[i]
  185. if not mod.is_modpack and
  186. not mod.is_game_content then
  187. if modname_valid(mod.name) then
  188. worldfile:set("load_mod_" .. mod.name,
  189. mod.enabled and "true" or "false")
  190. elseif mod.enabled then
  191. gamedata.errormessage = fgettext_ne("Failed to enable mo" ..
  192. "d \"$1\" as it contains disallowed characters. " ..
  193. "Only characters [a-z0-9_] are allowed.",
  194. mod.name)
  195. end
  196. mods["load_mod_" .. mod.name] = nil
  197. end
  198. end
  199. -- Remove mods that are not present anymore
  200. for key in pairs(mods) do
  201. if key:sub(1, 9) == "load_mod_" then
  202. worldfile:remove(key)
  203. end
  204. end
  205. if not worldfile:write() then
  206. core.log("error", "Failed to write world config file")
  207. end
  208. this:delete()
  209. return true
  210. end
  211. if fields.btn_config_world_cancel then
  212. this:delete()
  213. return true
  214. end
  215. if fields.btn_config_world_cdb then
  216. this.data.list = nil
  217. local dlg = create_store_dlg("mod")
  218. dlg:set_parent(this)
  219. this:hide()
  220. dlg:show()
  221. return true
  222. end
  223. if fields.btn_enable_all_mods then
  224. local list = this.data.list:get_raw_list()
  225. for i = 1, #list do
  226. if not list[i].is_game_content
  227. and not list[i].is_modpack then
  228. list[i].enabled = true
  229. end
  230. end
  231. enabled_all = true
  232. return true
  233. end
  234. if fields.btn_disable_all_mods then
  235. local list = this.data.list:get_raw_list()
  236. for i = 1, #list do
  237. if not list[i].is_game_content
  238. and not list[i].is_modpack then
  239. list[i].enabled = false
  240. end
  241. end
  242. enabled_all = false
  243. return true
  244. end
  245. return false
  246. end
  247. function create_configure_world_dlg(worldidx)
  248. local dlg = dialog_create("sp_config_world", get_formspec, handle_buttons)
  249. dlg.data.selected_mod = tonumber(
  250. core.settings:get("world_config_selected_mod")) or 0
  251. dlg.data.worldspec = core.get_worlds()[worldidx]
  252. if not dlg.data.worldspec then
  253. dlg:delete()
  254. return
  255. end
  256. dlg.data.worldconfig = pkgmgr.get_worldconfig(dlg.data.worldspec.path)
  257. if not dlg.data.worldconfig or not dlg.data.worldconfig.id or
  258. dlg.data.worldconfig.id == "" then
  259. dlg:delete()
  260. return
  261. end
  262. return dlg
  263. end