2
0

common.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. --Minetest
  2. --Copyright (C) 2014 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. -- Global menu data
  19. --------------------------------------------------------------------------------
  20. menudata = {}
  21. --------------------------------------------------------------------------------
  22. -- Local cached values
  23. --------------------------------------------------------------------------------
  24. local min_supp_proto = core.get_min_supp_proto()
  25. local max_supp_proto = core.get_max_supp_proto()
  26. --------------------------------------------------------------------------------
  27. -- Menu helper functions
  28. --------------------------------------------------------------------------------
  29. --------------------------------------------------------------------------------
  30. local function render_client_count(n)
  31. if n > 99 then
  32. return '99+'
  33. elseif n >= 0 then
  34. return tostring(n)
  35. else
  36. return '?'
  37. end
  38. end
  39. local function configure_selected_world_params(idx)
  40. local worldconfig = modmgr.get_worldconfig(
  41. menudata.worldlist:get_list()[idx].path)
  42. if worldconfig.creative_mode ~= nil then
  43. core.setting_set("creative_mode", worldconfig.creative_mode)
  44. end
  45. if worldconfig.enable_damage ~= nil then
  46. core.setting_set("enable_damage", worldconfig.enable_damage)
  47. end
  48. end
  49. --------------------------------------------------------------------------------
  50. function image_column(tooltip, flagname)
  51. return "image," ..
  52. "tooltip=" .. core.formspec_escape(tooltip) .. "," ..
  53. "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
  54. "1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
  55. end
  56. --------------------------------------------------------------------------------
  57. function order_favorite_list(list)
  58. local res = {}
  59. --orders the favorite list after support
  60. for i=1,#list,1 do
  61. local fav = list[i]
  62. if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
  63. table.insert(res, fav)
  64. end
  65. end
  66. for i=1,#list,1 do
  67. local fav = list[i]
  68. if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
  69. table.insert(res, fav)
  70. end
  71. end
  72. return res
  73. end
  74. --------------------------------------------------------------------------------
  75. function render_favorite(spec,render_details)
  76. local text = ""
  77. if spec.name ~= nil then
  78. text = text .. core.formspec_escape(spec.name:trim())
  79. -- if spec.description ~= nil and
  80. -- core.formspec_escape(spec.description):trim() ~= "" then
  81. -- text = text .. " (" .. core.formspec_escape(spec.description) .. ")"
  82. -- end
  83. else
  84. if spec.address ~= nil then
  85. text = text .. spec.address:trim()
  86. if spec.port ~= nil then
  87. text = text .. ":" .. spec.port
  88. end
  89. end
  90. end
  91. if not render_details then
  92. return text
  93. end
  94. local details = ""
  95. local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min)
  96. if spec.clients ~= nil and spec.clients_max ~= nil then
  97. local clients_color = ''
  98. local clients_percent = 100 * spec.clients / spec.clients_max
  99. -- Choose a color depending on how many clients are connected
  100. -- (relatively to clients_max)
  101. if spec.clients == 0 then
  102. clients_color = '' -- 0 players: default/white
  103. elseif spec.clients == spec.clients_max then
  104. clients_color = '#dd5b5b' -- full server: red (darker)
  105. elseif clients_percent <= 60 then
  106. clients_color = '#a1e587' -- 0-60%: green
  107. elseif clients_percent <= 90 then
  108. clients_color = '#ffdc97' -- 60-90%: yellow
  109. else
  110. clients_color = '#ffba97' -- 90-100%: orange
  111. end
  112. if grey_out then
  113. clients_color = '#aaaaaa'
  114. end
  115. details = details ..
  116. clients_color .. ',' ..
  117. render_client_count(spec.clients) .. ',' ..
  118. '/,' ..
  119. render_client_count(spec.clients_max) .. ','
  120. elseif grey_out then
  121. details = details .. '#aaaaaa,?,/,?,'
  122. else
  123. details = details .. ',?,/,?,'
  124. end
  125. if spec.creative then
  126. details = details .. "1,"
  127. else
  128. details = details .. "0,"
  129. end
  130. if spec.damage then
  131. details = details .. "1,"
  132. else
  133. details = details .. "0,"
  134. end
  135. if spec.pvp then
  136. details = details .. "1,"
  137. else
  138. details = details .. "0,"
  139. end
  140. return details .. (grey_out and '#aaaaaa,' or ',') .. text
  141. end
  142. --------------------------------------------------------------------------------
  143. os.tempfolder = function()
  144. if core.setting_get("TMPFolder") then
  145. return core.setting_get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000)
  146. end
  147. local filetocheck = os.tmpname()
  148. os.remove(filetocheck)
  149. local randname = "MTTempModFolder_" .. math.random(0,10000)
  150. if DIR_DELIM == "\\" then
  151. local tempfolder = os.getenv("TEMP")
  152. return tempfolder .. filetocheck
  153. else
  154. local backstring = filetocheck:reverse()
  155. return filetocheck:sub(0,filetocheck:len()-backstring:find(DIR_DELIM)+1) ..randname
  156. end
  157. end
  158. --------------------------------------------------------------------------------
  159. function menu_render_worldlist()
  160. local retval = ""
  161. local current_worldlist = menudata.worldlist:get_list()
  162. for i,v in ipairs(current_worldlist) do
  163. if retval ~= "" then
  164. retval = retval ..","
  165. end
  166. retval = retval .. core.formspec_escape(v.name) ..
  167. " \\[" .. core.formspec_escape(v.gameid) .. "\\]"
  168. end
  169. return retval
  170. end
  171. --------------------------------------------------------------------------------
  172. function menu_handle_key_up_down(fields,textlist,settingname)
  173. if fields["key_up"] then
  174. local oldidx = core.get_textlist_index(textlist)
  175. if oldidx ~= nil and oldidx > 1 then
  176. local newidx = oldidx -1
  177. core.setting_set(settingname,
  178. menudata.worldlist:get_raw_index(newidx))
  179. configure_selected_world_params(newidx)
  180. end
  181. return true
  182. end
  183. if fields["key_down"] then
  184. local oldidx = core.get_textlist_index(textlist)
  185. if oldidx ~= nil and oldidx < menudata.worldlist:size() then
  186. local newidx = oldidx + 1
  187. core.setting_set(settingname,
  188. menudata.worldlist:get_raw_index(newidx))
  189. configure_selected_world_params(newidx)
  190. end
  191. return true
  192. end
  193. return false
  194. end
  195. --------------------------------------------------------------------------------
  196. function asyncOnlineFavourites()
  197. if not menudata.public_known then
  198. menudata.public_known = {{
  199. name = fgettext("Loading..."),
  200. description = fgettext_ne("Try reenabling public serverlist and check your internet connection.")
  201. }}
  202. end
  203. menudata.favorites = menudata.public_known
  204. core.handle_async(
  205. function(param)
  206. return core.get_favorites("online")
  207. end,
  208. nil,
  209. function(result)
  210. if core.setting_getbool("public_serverlist") then
  211. local favs = order_favorite_list(result)
  212. if favs[1] then
  213. menudata.public_known = favs
  214. menudata.favorites = menudata.public_known
  215. end
  216. core.event_handler("Refresh")
  217. end
  218. end
  219. )
  220. end
  221. --------------------------------------------------------------------------------
  222. function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
  223. local textlines = core.splittext(text,textlen)
  224. local retval = "textlist[" .. xpos .. "," .. ypos .. ";"
  225. .. width .. "," .. height .. ";"
  226. .. tl_name .. ";"
  227. for i=1, #textlines, 1 do
  228. textlines[i] = textlines[i]:gsub("\r","")
  229. retval = retval .. core.formspec_escape(textlines[i]) .. ","
  230. end
  231. retval = retval .. ";0;"
  232. if transparency then
  233. retval = retval .. "true"
  234. end
  235. retval = retval .. "]"
  236. return retval
  237. end
  238. --------------------------------------------------------------------------------
  239. function is_server_protocol_compat(server_proto_min, server_proto_max)
  240. return not ((min_supp_proto > (server_proto_max or 24)) or (max_supp_proto < (server_proto_min or 13)))
  241. end
  242. --------------------------------------------------------------------------------
  243. function is_server_protocol_compat_or_error(server_proto_min, server_proto_max)
  244. if not is_server_protocol_compat(server_proto_min, server_proto_max) then
  245. local server_prot_ver_info
  246. local client_prot_ver_info
  247. if server_proto_min ~= server_proto_max then
  248. server_prot_ver_info = fgettext_ne("Server supports protocol versions between $1 and $2. ",
  249. server_proto_min or 13, server_proto_max or 24)
  250. else
  251. server_prot_ver_info = fgettext_ne("Server enforces protocol version $1. ",
  252. server_proto_min or 13)
  253. end
  254. if min_supp_proto ~= max_supp_proto then
  255. client_prot_ver_info= fgettext_ne("We support protocol versions between version $1 and $2.",
  256. min_supp_proto, max_supp_proto)
  257. else
  258. client_prot_ver_info = fgettext_ne("We only support protocol version $1.", min_supp_proto)
  259. end
  260. gamedata.errormessage = fgettext_ne("Protocol version mismatch. ")
  261. .. server_prot_ver_info
  262. .. client_prot_ver_info
  263. return false
  264. end
  265. return true
  266. end
  267. --------------------------------------------------------------------------------
  268. function menu_worldmt(selected, setting, value)
  269. local world = menudata.worldlist:get_list()[selected]
  270. if world then
  271. local filename = world.path .. DIR_DELIM .. "world.mt"
  272. local world_conf = Settings(filename)
  273. if value ~= nil then
  274. if not world_conf:write() then
  275. core.log("error", "Failed to write world config file")
  276. end
  277. world_conf:set(setting, value)
  278. world_conf:write()
  279. else
  280. return world_conf:get(setting)
  281. end
  282. else
  283. return nil
  284. end
  285. end
  286. function menu_worldmt_legacy(selected)
  287. local modes_names = {"creative_mode", "enable_damage", "server_announce"}
  288. for _, mode_name in pairs(modes_names) do
  289. local mode_val = menu_worldmt(selected, mode_name)
  290. if mode_val ~= nil then
  291. core.setting_set(mode_name, mode_val)
  292. else
  293. menu_worldmt(selected, mode_name, core.setting_get(mode_name))
  294. end
  295. end
  296. end