dlg_config_world.lua 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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 get_formspec(data)
  23. local mod = data.list:get_list()[data.selected_mod]
  24. local retval =
  25. "size[11.5,7.5,true]" ..
  26. "label[0.5,0;" .. fgettext("World:") .. "]" ..
  27. "label[1.75,0;" .. data.worldspec.name .. "]"
  28. if mod == nil then
  29. mod = {name=""}
  30. end
  31. local hard_deps, soft_deps = pkgmgr.get_dependencies(mod.path)
  32. retval = retval ..
  33. "label[0,0.7;" .. fgettext("Mod:") .. "]" ..
  34. "label[0.75,0.7;" .. mod.name .. "]" ..
  35. "label[0,1.25;" .. fgettext("Dependencies:") .. "]" ..
  36. "textlist[0,1.75;5,2.125;world_config_depends;" ..
  37. hard_deps .. ";0]" ..
  38. "label[0,3.875;" .. fgettext("Optional dependencies:") .. "]" ..
  39. "textlist[0,4.375;5,1.8;world_config_optdepends;" ..
  40. soft_deps .. ";0]" ..
  41. "button[3.25,7;2.5,0.5;btn_config_world_save;" .. fgettext("Save") .. "]" ..
  42. "button[5.75,7;2.5,0.5;btn_config_world_cancel;" .. fgettext("Cancel") .. "]"
  43. if mod and mod.name ~= "" and not mod.is_game_content then
  44. if mod.is_modpack then
  45. local rawlist = data.list:get_raw_list()
  46. local all_enabled = true
  47. for j = 1, #rawlist, 1 do
  48. if rawlist[j].modpack == mod.name and not rawlist[j].enabled then
  49. all_enabled = false
  50. break
  51. end
  52. end
  53. if all_enabled then
  54. retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_disable;" ..
  55. fgettext("Disable MP") .. "]"
  56. else
  57. retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_enable;" ..
  58. fgettext("Enable MP") .. "]"
  59. end
  60. else
  61. if mod.enabled then
  62. retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" ..
  63. fgettext("enabled") .. ";true]"
  64. else
  65. retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" ..
  66. fgettext("enabled") .. ";false]"
  67. end
  68. end
  69. end
  70. if enabled_all then
  71. retval = retval ..
  72. "button[8.75,0.125;2.5,0.5;btn_disable_all_mods;" .. fgettext("Disable all") .. "]"
  73. else
  74. retval = retval ..
  75. "button[8.75,0.125;2.5,0.5;btn_enable_all_mods;" .. fgettext("Enable all") .. "]"
  76. end
  77. retval = retval ..
  78. "tablecolumns[color;tree;text]" ..
  79. "table[5.5,0.75;5.75,6;world_config_modlist;"
  80. retval = retval .. pkgmgr.render_packagelist(data.list)
  81. retval = retval .. ";" .. data.selected_mod .."]"
  82. return retval
  83. end
  84. local function enable_mod(this, toset)
  85. local mod = this.data.list:get_list()[this.data.selected_mod]
  86. if mod.is_game_content then
  87. -- game mods can't be enabled or disabled
  88. elseif not mod.is_modpack then
  89. if toset == nil then
  90. mod.enabled = not mod.enabled
  91. else
  92. mod.enabled = toset
  93. end
  94. else
  95. local list = this.data.list:get_raw_list()
  96. for i=1,#list,1 do
  97. if list[i].modpack == mod.name then
  98. if toset == nil then
  99. toset = not list[i].enabled
  100. end
  101. list[i].enabled = toset
  102. end
  103. end
  104. end
  105. end
  106. local function handle_buttons(this, fields)
  107. if fields["world_config_modlist"] ~= nil then
  108. local event = core.explode_table_event(fields["world_config_modlist"])
  109. this.data.selected_mod = event.row
  110. core.settings:set("world_config_selected_mod", event.row)
  111. if event.type == "DCL" then
  112. enable_mod(this)
  113. end
  114. return true
  115. end
  116. if fields["key_enter"] ~= nil then
  117. enable_mod(this)
  118. return true
  119. end
  120. if fields["cb_mod_enable"] ~= nil then
  121. local toset = core.is_yes(fields["cb_mod_enable"])
  122. enable_mod(this,toset)
  123. return true
  124. end
  125. if fields["btn_mp_enable"] ~= nil or
  126. fields["btn_mp_disable"] then
  127. local toset = (fields["btn_mp_enable"] ~= nil)
  128. enable_mod(this,toset)
  129. return true
  130. end
  131. if fields["btn_config_world_save"] then
  132. local filename = this.data.worldspec.path ..
  133. DIR_DELIM .. "world.mt"
  134. local worldfile = Settings(filename)
  135. local mods = worldfile:to_table()
  136. local rawlist = this.data.list:get_raw_list()
  137. local i,mod
  138. for i,mod in ipairs(rawlist) do
  139. if not mod.is_modpack and
  140. not mod.is_game_content then
  141. if modname_valid(mod.name) then
  142. worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
  143. else
  144. if mod.enabled then
  145. gamedata.errormessage = fgettext_ne("Failed to enable mod \"$1\" as it contains disallowed characters. Only chararacters [a-z0-9_] are allowed.", mod.name)
  146. end
  147. end
  148. mods["load_mod_"..mod.name] = nil
  149. end
  150. end
  151. -- Remove mods that are not present anymore
  152. for key,value in pairs(mods) do
  153. if key:sub(1,9) == "load_mod_" then
  154. worldfile:remove(key)
  155. end
  156. end
  157. if not worldfile:write() then
  158. core.log("error", "Failed to write world config file")
  159. end
  160. this:delete()
  161. return true
  162. end
  163. if fields["btn_config_world_cancel"] then
  164. this:delete()
  165. return true
  166. end
  167. if fields.btn_enable_all_mods then
  168. local list = this.data.list:get_raw_list()
  169. for i = 1, #list do
  170. if not list[i].is_game_content
  171. and not list[i].is_modpack then
  172. list[i].enabled = true
  173. end
  174. end
  175. enabled_all = true
  176. return true
  177. end
  178. if fields.btn_disable_all_mods then
  179. local list = this.data.list:get_raw_list()
  180. for i = 1, #list do
  181. if not list[i].is_game_content
  182. and not list[i].is_modpack then
  183. list[i].enabled = false
  184. end
  185. end
  186. enabled_all = false
  187. return true
  188. end
  189. return false
  190. end
  191. function create_configure_world_dlg(worldidx)
  192. local dlg = dialog_create("sp_config_world",
  193. get_formspec,
  194. handle_buttons,
  195. nil)
  196. dlg.data.selected_mod = tonumber(core.settings:get("world_config_selected_mod"))
  197. if dlg.data.selected_mod == nil then
  198. dlg.data.selected_mod = 0
  199. end
  200. dlg.data.worldspec = core.get_worlds()[worldidx]
  201. if dlg.data.worldspec == nil then dlg:delete() return nil end
  202. dlg.data.worldconfig = pkgmgr.get_worldconfig(dlg.data.worldspec.path)
  203. if dlg.data.worldconfig == nil or dlg.data.worldconfig.id == nil or
  204. dlg.data.worldconfig.id == "" then
  205. dlg:delete()
  206. return nil
  207. end
  208. dlg.data.list = filterlist.create(
  209. pkgmgr.preparemodlist, --refresh
  210. pkgmgr.comparemod, --compare
  211. function(element,uid) --uid match
  212. if element.name == uid then
  213. return true
  214. end
  215. end,
  216. function(element, criteria)
  217. if criteria.hide_game and
  218. element.is_game_content then
  219. return false
  220. end
  221. if criteria.hide_modpackcontents and
  222. element.modpack ~= nil then
  223. return false
  224. end
  225. return true
  226. end, --filter
  227. { worldpath= dlg.data.worldspec.path,
  228. gameid = dlg.data.worldspec.gameid }
  229. )
  230. if dlg.data.selected_mod > dlg.data.list:size() then
  231. dlg.data.selected_mod = 0
  232. end
  233. dlg.data.list:set_filtercriteria(
  234. {
  235. hide_game=dlg.data.hide_gamemods,
  236. hide_modpackcontents= dlg.data.hide_modpackcontents
  237. })
  238. dlg.data.list:add_sort_mechanism("alphabetic", sort_mod_list)
  239. dlg.data.list:set_sortmode("alphabetic")
  240. return dlg
  241. end