mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-10-30 23:15:32 +01:00 
			
		
		
		
	Cherry-pick most commits since 15c0376
				
					
				
			Commits not directly related to network changes were cherry-picked on a best-effort basis, as some cause difficult merge conflicts. Commits skipped over:0d1eedccccaa474e450182482ecd9db214cde5b42066655aae7e088fdfe340bf1d7b5f1b2f64473e7e56637ed064ff966bae51057a56f5009149a073cf4045ff0fe357577cb249f84b76bcb019221c307880ff74b6146f77fdb7a704c04f00Commits with conflicts:038d3a31dfe9eda2b0d0708337dfc2~~ modified client.cpp manually; shadow changes to packethandlers/client.cpp36e8ba9ce2~~ modified main.cpp manually; add ALLOW_ZWRITE_ON_TRANSPARENT set3b6480c5b0~~ modified server.cpp manually; change wrapDegrees -> modulo360f5a5854ea9dc09d026f053c91ad8fc2
This commit is contained in:
		| @@ -545,12 +545,11 @@ function table.copy(t, seen) | ||||
| 	seen = seen or {} | ||||
| 	seen[t] = n | ||||
| 	for k, v in pairs(t) do | ||||
| 		n[type(k) ~= "table" and k or seen[k] or table.copy(k, seen)] = | ||||
| 			type(v) ~= "table" and v or seen[v] or table.copy(v, seen) | ||||
| 		n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] = | ||||
| 			(type(v) == "table" and (seen[v] or table.copy(v, seen))) or v | ||||
| 	end | ||||
| 	return n | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| -- mainmenu only functions | ||||
| -------------------------------------------------------------------------------- | ||||
| @@ -565,7 +564,7 @@ if INIT == "mainmenu" then | ||||
| 		return nil | ||||
| 	end | ||||
|  | ||||
| 	function fgettext(text, ...) | ||||
| 	function fgettext_ne(text, ...) | ||||
| 		text = core.gettext(text) | ||||
| 		local arg = {n=select('#', ...), ...} | ||||
| 		if arg.n >= 1 then | ||||
| @@ -587,7 +586,11 @@ if INIT == "mainmenu" then | ||||
| 			end | ||||
| 			text = result | ||||
| 		end | ||||
| 		return core.formspec_escape(text) | ||||
| 		return text | ||||
| 	end | ||||
|  | ||||
| 	function fgettext(text, ...) | ||||
| 		return core.formspec_escape(fgettext_ne(text, ...)) | ||||
| 	end | ||||
| end | ||||
|  | ||||
|   | ||||
| @@ -115,11 +115,20 @@ function core.serialize(x) | ||||
| 	function dump_val(x) | ||||
| 		local  tp = type(x) | ||||
| 		if     x  == nil        then return "nil" | ||||
| 		elseif tp == "number"   then return string.format("%d", x) | ||||
| 		elseif tp == "string"   then return string.format("%q", x) | ||||
| 		elseif tp == "boolean"  then return x and "true" or "false" | ||||
| 		elseif tp == "function" then | ||||
| 			return string.format("loadstring(%q)", string.dump(x)) | ||||
| 		elseif tp == "number"   then | ||||
| 			-- Serialize integers with string.format to prevent | ||||
| 			-- scientific notation, which doesn't preserve | ||||
| 			-- precision and breaks things like node position | ||||
| 			-- hashes.  Serialize floats normally. | ||||
| 			if math.floor(x) == x then | ||||
| 				return string.format("%d", x) | ||||
| 			else | ||||
| 				return tostring(x) | ||||
| 			end | ||||
| 		elseif tp == "table" then | ||||
| 			local vals = {} | ||||
| 			local idx_dumped = {} | ||||
|   | ||||
| @@ -229,21 +229,28 @@ core.register_chatcommand("setpassword", { | ||||
| 		if not toname then | ||||
| 			return false, "Name field required" | ||||
| 		end | ||||
| 		local actstr = "?" | ||||
| 		local act_str_past = "?" | ||||
| 		local act_str_pres = "?" | ||||
| 		if not raw_password then | ||||
| 			core.set_player_password(toname, "") | ||||
| 			actstr = "cleared" | ||||
| 			act_str_past = "cleared" | ||||
| 			act_str_pres = "clears" | ||||
| 		else | ||||
| 			core.set_player_password(toname, | ||||
| 					core.get_password_hash(toname, | ||||
| 							raw_password)) | ||||
| 			actstr = "set" | ||||
| 			act_str_past = "set" | ||||
| 			act_str_pres = "sets" | ||||
| 		end | ||||
| 		if toname ~= name then | ||||
| 			core.chat_send_player(toname, "Your password was " | ||||
| 					.. actstr .. " by " .. name) | ||||
| 					.. act_str_past .. " by " .. name) | ||||
| 		end | ||||
| 		return true, "Password of player \"" .. toname .. "\" " .. actstr | ||||
|  | ||||
| 		core.log("action", name .. " " .. act_str_pres | ||||
| 		.. " password of " .. toname .. ".") | ||||
|  | ||||
| 		return true, "Password of player \"" .. toname .. "\" " .. act_str_past | ||||
| 	end, | ||||
| }) | ||||
|  | ||||
| @@ -257,6 +264,9 @@ core.register_chatcommand("clearpassword", { | ||||
| 			return false, "Name field required" | ||||
| 		end | ||||
| 		core.set_player_password(toname, '') | ||||
|  | ||||
| 		core.log("action", name .. " clears password of " .. toname .. ".") | ||||
|  | ||||
| 		return true, "Password of player \"" .. toname .. "\" cleared" | ||||
| 	end, | ||||
| }) | ||||
| @@ -404,13 +414,14 @@ core.register_chatcommand("set", { | ||||
| }) | ||||
|  | ||||
| core.register_chatcommand("deleteblocks", { | ||||
| 	params = "[here] [<pos1> <pos2>]", | ||||
| 	params = "(here [radius]) | (<pos1> <pos2>)", | ||||
| 	description = "delete map blocks contained in area pos1 to pos2", | ||||
| 	privs = {server=true}, | ||||
| 	func = function(name, param) | ||||
| 		local p1 = {} | ||||
| 		local p2 = {} | ||||
| 		if param == "here" then | ||||
| 		local args = param:split(" ") | ||||
| 		if args[1] == "here" then | ||||
| 			local player = core.get_player_by_name(name) | ||||
| 			if player == nil then | ||||
| 				core.log("error", "player is nil") | ||||
| @@ -418,6 +429,12 @@ core.register_chatcommand("deleteblocks", { | ||||
| 			end | ||||
| 			p1 = player:getpos() | ||||
| 			p2 = p1 | ||||
|  | ||||
| 			if #args >= 2 then | ||||
| 				local radius = tonumber(args[2]) or 0 | ||||
| 				p1 = vector.add(p1, radius) | ||||
| 				p2 = vector.subtract(p2, radius) | ||||
| 			end | ||||
| 		else | ||||
| 			local pos1, pos2 = unpack(param:split(") (")) | ||||
| 			if pos1 == nil or pos2 == nil then | ||||
| @@ -570,6 +587,9 @@ core.register_chatcommand("rollback_check", { | ||||
| 			.. " seconds=86400=24h, limit=5)", | ||||
| 	privs = {rollback=true}, | ||||
| 	func = function(name, param) | ||||
| 		if not core.setting_getbool("enable_rollback_recording") then | ||||
| 			return false, "Rollback functions are disabled." | ||||
| 		end | ||||
| 		local range, seconds, limit = | ||||
| 			param:match("(%d+) *(%d*) *(%d*)") | ||||
| 		range = tonumber(range) or 0 | ||||
| @@ -583,6 +603,10 @@ core.register_chatcommand("rollback_check", { | ||||
| 			local name = puncher:get_player_name() | ||||
| 			core.chat_send_player(name, "Checking " .. core.pos_to_string(pos) .. "...") | ||||
| 			local actions = core.rollback_get_node_actions(pos, range, seconds, limit) | ||||
| 			if not actions then | ||||
| 				core.chat_send_player(name, "Rollback functions are disabled") | ||||
| 				return | ||||
| 			end | ||||
| 			local num_actions = #actions | ||||
| 			if num_actions == 0 then | ||||
| 				core.chat_send_player(name, "Nobody has touched" | ||||
| @@ -614,6 +638,9 @@ core.register_chatcommand("rollback", { | ||||
| 	description = "revert actions of a player; default for <seconds> is 60", | ||||
| 	privs = {rollback=true}, | ||||
| 	func = function(name, param) | ||||
| 		if not core.setting_getbool("enable_rollback_recording") then | ||||
| 			return false, "Rollback functions are disabled." | ||||
| 		end | ||||
| 		local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)") | ||||
| 		if not target_name then | ||||
| 			local player_name = nil | ||||
|   | ||||
| @@ -106,7 +106,7 @@ function core.facedir_to_dir(facedir) | ||||
| 					{x=0, y=1, z=0}}) | ||||
|  | ||||
| 					--indexed into by a table of correlating facedirs | ||||
| 					[({[0]=1, 2, 3, 4,  | ||||
| 					[({[0]=1, 2, 3, 4, | ||||
| 						5, 2, 6, 4, | ||||
| 						6, 2, 5, 4, | ||||
| 						1, 5, 3, 6, | ||||
| @@ -238,7 +238,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2) | ||||
|  | ||||
| 	core.log("action", placer:get_player_name() .. " places node " | ||||
| 		.. def.name .. " at " .. core.pos_to_string(place_to)) | ||||
| 	 | ||||
|  | ||||
| 	local oldnode = core.get_node(place_to) | ||||
| 	local newnode = {name = def.name, param1 = 0, param2 = param2} | ||||
|  | ||||
| @@ -357,19 +357,37 @@ function core.item_drop(itemstack, dropper, pos) | ||||
| 	return itemstack | ||||
| end | ||||
|  | ||||
| function core.item_eat(hp_change, replace_with_item) | ||||
| 	return function(itemstack, user, pointed_thing)  -- closure | ||||
| 		for _, callback in pairs(core.registered_on_item_eats) do | ||||
| 			local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing) | ||||
| 			if result then | ||||
| 				return result | ||||
| function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing) | ||||
| 	for _, callback in pairs(core.registered_on_item_eats) do | ||||
| 		local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing) | ||||
| 		if result then | ||||
| 			return result | ||||
| 		end | ||||
| 	end | ||||
| 	if itemstack:take_item() ~= nil then | ||||
| 		user:set_hp(user:get_hp() + hp_change) | ||||
|  | ||||
| 		if replace_with_item then | ||||
| 			if itemstack:is_empty() then | ||||
| 				itemstack:add_item(replace_with_item) | ||||
| 			else | ||||
| 				local inv = user:get_inventory() | ||||
| 				if inv:room_for_item("main", {name=replace_with_item}) then | ||||
| 					inv:add_item("main", replace_with_item) | ||||
| 				else | ||||
| 					local pos = user:getpos() | ||||
| 					pos.y = math.floor(pos.y + 0.5) | ||||
| 					core.add_item(pos, replace_with_item) | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 		if itemstack:take_item() ~= nil then | ||||
| 			user:set_hp(user:get_hp() + hp_change) | ||||
| 			itemstack:add_item(replace_with_item) -- note: replace_with_item is optional | ||||
| 		end | ||||
| 		return itemstack | ||||
| 	end | ||||
| 	return itemstack | ||||
| end | ||||
|  | ||||
| function core.item_eat(hp_change, replace_with_item) | ||||
| 	return function(itemstack, user, pointed_thing)  -- closure | ||||
| 		return core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| @@ -425,7 +443,7 @@ function core.node_dig(pos, node, digger) | ||||
|  | ||||
| 	local wielded = digger:get_wielded_item() | ||||
| 	local drops = core.get_node_drops(node.name, wielded:get_name()) | ||||
| 	 | ||||
|  | ||||
| 	local wdef = wielded:get_definition() | ||||
| 	local tp = wielded:get_tool_capabilities() | ||||
| 	local dp = core.get_dig_params(def.groups, tp) | ||||
| @@ -438,7 +456,7 @@ function core.node_dig(pos, node, digger) | ||||
| 		end | ||||
| 	end | ||||
| 	digger:set_wielded_item(wielded) | ||||
| 	 | ||||
|  | ||||
| 	-- Handle drops | ||||
| 	core.handle_node_drops(pos, drops, digger) | ||||
|  | ||||
| @@ -449,7 +467,7 @@ function core.node_dig(pos, node, digger) | ||||
|  | ||||
| 	-- Remove node and update | ||||
| 	core.remove_node(pos) | ||||
| 	 | ||||
|  | ||||
| 	-- Run callback | ||||
| 	if def.after_dig_node then | ||||
| 		-- Copy pos and node because callback can modify them | ||||
| @@ -507,7 +525,7 @@ core.nodedef_default = { | ||||
| 	on_dig = redef_wrapper(core, 'node_dig'), -- core.node_dig | ||||
|  | ||||
| 	on_receive_fields = nil, | ||||
| 	 | ||||
|  | ||||
| 	on_metadata_inventory_move = core.node_metadata_inventory_move_allow_all, | ||||
| 	on_metadata_inventory_offer = core.node_metadata_inventory_offer_allow_all, | ||||
| 	on_metadata_inventory_take = core.node_metadata_inventory_take_allow_all, | ||||
|   | ||||
| @@ -16,9 +16,15 @@ | ||||
| --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| -------------------------------------------------------------------------------- | ||||
| -- Global menu data | ||||
| --------------------------------------------------------------------------------- | ||||
| -------------------------------------------------------------------------------- | ||||
| menudata = {} | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| -- Local cached values | ||||
| -------------------------------------------------------------------------------- | ||||
| local min_supp_proto = core.get_min_supp_proto() | ||||
| local max_supp_proto = core.get_max_supp_proto() | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| -- Menu helper functions | ||||
| -------------------------------------------------------------------------------- | ||||
| @@ -42,6 +48,25 @@ function image_column(tooltip, flagname) | ||||
| 		"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png") | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| function order_favorite_list(list) | ||||
| 	local res = {} | ||||
| 	--orders the favorite list after support | ||||
| 	for i=1,#list,1 do | ||||
| 		local fav = list[i] | ||||
| 		if is_server_protocol_compat(fav.proto_min, fav.proto_max) then | ||||
| 			table.insert(res, fav) | ||||
| 		end | ||||
| 	end | ||||
| 	for i=1,#list,1 do | ||||
| 		local fav = list[i] | ||||
| 		if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then | ||||
| 			table.insert(res, fav) | ||||
| 		end | ||||
| 	end | ||||
| 	return res | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| function render_favorite(spec,render_details) | ||||
| 	local text = "" | ||||
| @@ -68,6 +93,7 @@ function render_favorite(spec,render_details) | ||||
| 	end | ||||
|  | ||||
| 	local details = "" | ||||
| 	local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min) | ||||
|  | ||||
| 	if spec.clients ~= nil and spec.clients_max ~= nil then | ||||
| 		local clients_color = '' | ||||
| @@ -87,11 +113,17 @@ function render_favorite(spec,render_details) | ||||
| 			clients_color = '#ffba97' -- 90-100%: orange | ||||
| 		end | ||||
|  | ||||
| 		if grey_out then | ||||
| 			clients_color = '#aaaaaa' | ||||
| 		end | ||||
|  | ||||
| 		details = details .. | ||||
| 				clients_color .. ',' .. | ||||
| 				render_client_count(spec.clients) .. ',' .. | ||||
| 				'/,' .. | ||||
| 				render_client_count(spec.clients_max) .. ',' | ||||
| 	elseif grey_out then | ||||
| 		details = details .. '#aaaaaa,?,/,?,' | ||||
| 	else | ||||
| 		details = details .. ',?,/,?,' | ||||
| 	end | ||||
| @@ -114,7 +146,7 @@ function render_favorite(spec,render_details) | ||||
| 		details = details .. "0," | ||||
| 	end | ||||
|  | ||||
| 	return details .. text | ||||
| 	return details .. (grey_out and '#aaaaaa,' or ',') .. text | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| @@ -195,7 +227,7 @@ function asyncOnlineFavourites() | ||||
| 		nil, | ||||
| 		function(result) | ||||
| 			if core.setting_getbool("public_serverlist") then | ||||
| 				menudata.favorites = result | ||||
| 				menudata.favorites = order_favorite_list(result) | ||||
| 				core.event_handler("Refresh") | ||||
| 			end | ||||
| 		end | ||||
| @@ -225,3 +257,21 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency) | ||||
|  | ||||
| 	return retval | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| function is_server_protocol_compat(proto_min, proto_max) | ||||
| 	return not ((min_supp_proto > (proto_max or 24)) or (max_supp_proto < (proto_min or 13))) | ||||
| end | ||||
| -------------------------------------------------------------------------------- | ||||
| function is_server_protocol_compat_or_error(proto_min, proto_max) | ||||
| 	if not is_server_protocol_compat(proto_min, proto_max) then | ||||
| 		gamedata.errormessage = fgettext_ne("Protocol version mismatch, server " .. | ||||
| 			((proto_min ~= proto_max) and "supports protocols between $1 and $2" or "enforces protocol version $1") .. | ||||
| 			", we " .. | ||||
| 			((min_supp_proto ~= max_supp_proto) and "support protocols between version $3 and $4." or "only support protocol version $3"), | ||||
| 			proto_min or 13, proto_max or 24, min_supp_proto, max_supp_proto) | ||||
| 		return false | ||||
| 	end | ||||
|  | ||||
| 	return true | ||||
| end | ||||
|   | ||||
| @@ -16,6 +16,9 @@ | ||||
| --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| local function modname_valid(name) | ||||
| 	return not name:find("[^a-z0-9_]") | ||||
| end | ||||
|  | ||||
| local function get_formspec(data) | ||||
|  | ||||
| @@ -195,10 +198,12 @@ local function handle_buttons(this, fields) | ||||
| 		for i,mod in ipairs(rawlist) do | ||||
| 			if not mod.is_modpack and | ||||
| 					mod.typ ~= "game_mod" then | ||||
| 				if mod.enabled then | ||||
| 					worldfile:set("load_mod_"..mod.name, "true") | ||||
| 				if modname_valid(mod.name) then | ||||
| 					worldfile:set("load_mod_"..mod.name, tostring(mod.enabled)) | ||||
| 				else | ||||
| 					worldfile:set("load_mod_"..mod.name, "false") | ||||
| 					if mod.enabled then | ||||
| 						gamedata.errormessage = fgettext_ne("Failed to enable mod \"$1\" as it contains disallowed characters. Only chararacters [a-z0-9_] are allowed.", mod.name) | ||||
| 					end | ||||
| 				end | ||||
| 				mods["load_mod_"..mod.name] = nil | ||||
| 			end | ||||
|   | ||||
| @@ -90,6 +90,8 @@ local function create_world_buttonhandler(this, fields) | ||||
|  | ||||
| 			local message = nil | ||||
|  | ||||
| 			core.setting_set("fixed_map_seed", fields["te_seed"]) | ||||
|  | ||||
| 			if not menudata.worldlist:uid_exists_raw(worldname) then | ||||
| 				core.setting_set("mg_name",fields["dd_mapgen"]) | ||||
| 				message = core.create_world(worldname,gameindex) | ||||
| @@ -97,8 +99,6 @@ local function create_world_buttonhandler(this, fields) | ||||
| 				message = fgettext("A world named \"$1\" already exists", worldname) | ||||
| 			end | ||||
|  | ||||
| 			core.setting_set("fixed_map_seed", fields["te_seed"]) | ||||
|  | ||||
| 			if message ~= nil then | ||||
| 				gamedata.errormessage = message | ||||
| 			else | ||||
|   | ||||
| @@ -139,7 +139,11 @@ local function init_globals() | ||||
| 	tv_main:add(tab_credits) | ||||
|  | ||||
| 	tv_main:set_global_event_handler(main_event_handler) | ||||
| 	tv_main:set_fixed_size(false) | ||||
| 	if PLATFORM ~= "Android" then | ||||
| 		tv_main:set_fixed_size(true) | ||||
| 	else | ||||
| 		tv_main:set_fixed_size(false) | ||||
| 	end | ||||
|  | ||||
| 	if not (PLATFORM == "Android") then | ||||
| 		tv_main:set_tab(core.setting_get("maintab_LAST")) | ||||
|   | ||||
| @@ -122,35 +122,36 @@ end | ||||
| function modstore.showdownloading(title) | ||||
| 	local new_dlg = dialog_create("store_downloading", | ||||
| 		function(data) | ||||
| 			return "size[6,2]label[0.25,0.75;" .. fgettext("Downloading") .. | ||||
| 				" " .. data.title .. " " .. | ||||
| 				fgettext("please wait...") .. "]" | ||||
| 			return "size[6,2]label[0.25,0.75;" .. | ||||
| 				fgettext("Downloading $1, please wait...", data.title) .. "]" | ||||
| 		end, | ||||
| 		function(this,fields) | ||||
| 			if fields["btn_hidden_close_download"] ~= nil then | ||||
| 				if fields["btn_hidden_close_download"].successfull then | ||||
| 					modstore.lastmodentry = fields["btn_hidden_close_download"] | ||||
| 					modstore.successfulldialog() | ||||
| 					modstore.successfulldialog(this) | ||||
| 				else | ||||
| 					this.parent:show() | ||||
| 					this:delete() | ||||
| 					modstore.lastmodtitle = "" | ||||
| 				end | ||||
|  | ||||
| 				this:delete() | ||||
| 				return true | ||||
| 			end | ||||
|  | ||||
| 			return false | ||||
| 		end, | ||||
| 		nil, | ||||
| 		modstore.tv_store) | ||||
| 		nil) | ||||
|  | ||||
| 	new_dlg:set_parent(modstore.tv_store) | ||||
| 	modstore.tv_store:hide() | ||||
| 	new_dlg.data.title = title | ||||
| 	new_dlg:show() | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| -- @function [parent=#modstore] successfulldialog | ||||
| function modstore.successfulldialog() | ||||
| function modstore.successfulldialog(downloading_dlg) | ||||
| 	local new_dlg = dialog_create("store_downloading", | ||||
| 		function(data) | ||||
| 			local retval = "" | ||||
| @@ -158,18 +159,16 @@ function modstore.successfulldialog() | ||||
| 			if modstore.lastmodentry ~= nil then | ||||
| 				retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]" | ||||
| 				retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]" | ||||
|  | ||||
|  | ||||
| 				retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]" | ||||
| 				retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]" | ||||
|  | ||||
| 			end | ||||
| 			retval = retval .. "button[2.5,1.5;1,0.5;btn_confirm_mod_successfull;" .. fgettext("ok") .. "]" | ||||
| 			retval = retval .. "button[2.2,1.5;1.5,0.5;btn_confirm_mod_successfull;" .. fgettext("Ok") .. "]" | ||||
| 			return retval | ||||
| 		end, | ||||
| 		function(this,fields) | ||||
| 			if fields["btn_confirm_mod_successfull"] ~= nil then | ||||
| 				this.parent:show() | ||||
| 				this:hide() | ||||
| 				downloading_dlg:delete() | ||||
| 				this:delete() | ||||
|  | ||||
| 				return true | ||||
| @@ -177,10 +176,10 @@ function modstore.successfulldialog() | ||||
|  | ||||
| 			return false | ||||
| 		end, | ||||
| 		nil, | ||||
| 		modstore.tv_store) | ||||
| 		nil) | ||||
|  | ||||
| 	new_dlg.data.title = title | ||||
| 	new_dlg:set_parent(modstore.tv_store) | ||||
| 	modstore.tv_store:hide() | ||||
| 	new_dlg:show() | ||||
| end | ||||
|  | ||||
| @@ -217,7 +216,9 @@ function modstore.handle_buttons(parent, fields, name, data) | ||||
| 	end | ||||
|  | ||||
| 	if fields["btn_modstore_close"] then | ||||
| 		local maintab = ui.find_by_name("maintab") | ||||
| 		parent:hide() | ||||
| 		maintab:show() | ||||
| 		return true | ||||
| 	end | ||||
|  | ||||
| @@ -228,12 +229,7 @@ function modstore.handle_buttons(parent, fields, name, data) | ||||
| 			for i=1,#modstore.modlist_unsorted.data,1 do | ||||
| 				if modstore.modlist_unsorted.data[i].id == modid then | ||||
| 					local moddetails = modstore.modlist_unsorted.data[i].details | ||||
|  | ||||
| 					if modstore.lastmodtitle ~= "" then | ||||
| 						modstore.lastmodtitle = modstore.lastmodtitle .. ", " | ||||
| 					end | ||||
|  | ||||
| 					modstore.lastmodtitle = modstore.lastmodtitle .. moddetails.title | ||||
| 					modstore.lastmodtitle = moddetails.title | ||||
|  | ||||
| 					if not core.handle_async( | ||||
| 						function(param) | ||||
| @@ -281,7 +277,7 @@ function modstore.handle_buttons(parent, fields, name, data) | ||||
| 							texturename = modstore.modlist_unsorted.data[i].texturename | ||||
| 						}, | ||||
| 						function(result) | ||||
| 							print("Result from async: " .. dump(result.successfull)) | ||||
| 							--print("Result from async: " .. dump(result.successfull)) | ||||
| 							if result.successfull then | ||||
| 								modmgr.installmod(result.filename,result.moddetails.basename) | ||||
| 								os.remove(result.filename) | ||||
| @@ -299,7 +295,7 @@ function modstore.handle_buttons(parent, fields, name, data) | ||||
| 						print("ERROR: async event failed") | ||||
| 						gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle | ||||
| 					end | ||||
| 					parent:hide() | ||||
|  | ||||
| 					modstore.showdownloading(modstore.lastmodtitle) | ||||
| 					return true | ||||
| 				end | ||||
| @@ -391,7 +387,7 @@ function modstore.getscreenshot(ypos,listentry) | ||||
| 		listentry.details.screenshot_url == "") then | ||||
|  | ||||
| 		if listentry.texturename == nil then | ||||
| 			listentry.texturename = modstore.basetexturedir .. "no_screenshot.png" | ||||
| 			listentry.texturename = defaulttexturedir .. "no_screenshot.png" | ||||
| 		end | ||||
|  | ||||
| 		return "image[0,".. ypos .. ";3,2;" .. | ||||
|   | ||||
| @@ -57,7 +57,7 @@ local function get_formspec(tabview, name, tabdata) | ||||
| 		end | ||||
|  | ||||
| 		if modscreenshot == nil then | ||||
| 				modscreenshot = modstore.basetexturedir .. "no_screenshot.png" | ||||
| 				modscreenshot = defaulttexturedir .. "no_screenshot.png" | ||||
| 		end | ||||
|  | ||||
| 		retval = retval | ||||
| @@ -96,7 +96,7 @@ local function get_formspec(tabview, name, tabdata) | ||||
| 		else | ||||
| 			--show dependencies | ||||
|  | ||||
| 			retval = retval .. ",Depends:," | ||||
| 			retval = retval .. "," .. fgettext("Depends:") .. "," | ||||
|  | ||||
| 			local toadd = modmgr.get_dependencies(selected_mod.path) | ||||
|  | ||||
|   | ||||
| @@ -59,9 +59,10 @@ local function get_formspec(tabview, name, tabdata) | ||||
| 			"text,align=right;" ..                -- clients | ||||
| 			"text,align=center,padding=0.25;" ..  -- "/" | ||||
| 			"text,align=right,padding=0.25;" ..   -- clients_max | ||||
| 			image_column("Creative mode", "creative") .. ",padding=1;" .. | ||||
| 			image_column("Damage enabled", "damage") .. ",padding=0.25;" .. | ||||
| 			image_column("PvP enabled", "pvp") .. ",padding=0.25;" .. | ||||
| 			image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" .. | ||||
| 			image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" .. | ||||
| 			image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. | ||||
| 			"color,span=1;" .. | ||||
| 			"text,padding=1]"                               -- name | ||||
| 	else | ||||
| 		retval = retval .. "tablecolumns[text]" | ||||
| @@ -88,7 +89,6 @@ end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
| local function main_button_handler(tabview, fields, name, tabdata) | ||||
|  | ||||
| 	if fields["te_name"] ~= nil then | ||||
| 		gamedata.playername = fields["te_name"] | ||||
| 		core.setting_set("name", fields["te_name"]) | ||||
| @@ -98,6 +98,10 @@ local function main_button_handler(tabview, fields, name, tabdata) | ||||
| 		local event = core.explode_table_event(fields["favourites"]) | ||||
| 		if event.type == "DCL" then | ||||
| 			if event.row <= #menudata.favorites then | ||||
| 				if not is_server_protocol_compat_or_error(menudata.favorites[event.row].proto_min, | ||||
| 						menudata.favorites[event.row].proto_max) then | ||||
| 					return true | ||||
| 				end | ||||
| 				gamedata.address    = menudata.favorites[event.row].address | ||||
| 				gamedata.port       = menudata.favorites[event.row].port | ||||
| 				gamedata.playername = fields["te_name"] | ||||
| @@ -189,7 +193,7 @@ local function main_button_handler(tabview, fields, name, tabdata) | ||||
| 		local current_favourite = core.get_table_index("favourites") | ||||
| 		if current_favourite == nil then return end | ||||
| 		core.delete_favorite(current_favourite) | ||||
| 		menudata.favorites   = core.get_favorites() | ||||
| 		menudata.favorites = order_favorite_list(core.get_favorites()) | ||||
| 		tabdata.fav_selected = nil | ||||
|  | ||||
| 		core.setting_set("address","") | ||||
| @@ -198,8 +202,9 @@ local function main_button_handler(tabview, fields, name, tabdata) | ||||
| 		return true | ||||
| 	end | ||||
|  | ||||
| 	if fields["btn_mp_connect"] ~= nil or | ||||
| 		fields["key_enter"] ~= nil then | ||||
| 	if (fields["btn_mp_connect"] ~= nil or | ||||
| 		fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and | ||||
| 		fields["te_port"] ~= nil then | ||||
|  | ||||
| 		gamedata.playername     = fields["te_name"] | ||||
| 		gamedata.password       = fields["te_pwd"] | ||||
| @@ -214,6 +219,11 @@ local function main_button_handler(tabview, fields, name, tabdata) | ||||
|  | ||||
| 			gamedata.servername        = menudata.favorites[fav_idx].name | ||||
| 			gamedata.serverdescription = menudata.favorites[fav_idx].description | ||||
|  | ||||
| 			if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min, | ||||
| 					menudata.favorites[fav_idx].proto_max)then | ||||
| 				return true | ||||
| 			end | ||||
| 		else | ||||
| 			gamedata.servername        = "" | ||||
| 			gamedata.serverdescription = "" | ||||
|   | ||||
| @@ -42,9 +42,10 @@ local function get_formspec(tabview, name, tabdata) | ||||
| 			"text,align=right;" ..                -- clients | ||||
| 			"text,align=center,padding=0.25;" ..  -- "/" | ||||
| 			"text,align=right,padding=0.25;" ..   -- clients_max | ||||
| 			image_column("Creative mode", "creative") .. ",padding=1;" .. | ||||
| 			image_column("Damage enabled", "damage") .. ",padding=0.25;" .. | ||||
| 			image_column("PvP enabled", "pvp") .. ",padding=0.25;" .. | ||||
| 			image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" .. | ||||
| 			image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" .. | ||||
| 			image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. | ||||
| 			"color,span=1;" .. | ||||
| 			"text,padding=1]"                               -- name | ||||
| 	else | ||||
| 		retval = retval .. "tablecolumns[text]" | ||||
| @@ -87,7 +88,6 @@ local function get_formspec(tabview, name, tabdata) | ||||
| end | ||||
|  | ||||
| -------------------------------------------------------------------------------- | ||||
|  | ||||
| local function main_button_handler(tabview, fields, name, tabdata) | ||||
|  | ||||
| 	if fields["btn_start_singleplayer"] then | ||||
| @@ -159,6 +159,11 @@ local function main_button_handler(tabview, fields, name, tabdata) | ||||
|  | ||||
| 			gamedata.servername			= menudata.favorites[fav_idx].name | ||||
| 			gamedata.serverdescription	= menudata.favorites[fav_idx].description | ||||
|  | ||||
| 			if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min, | ||||
| 					menudata.favorites[fav_idx].proto_max) then | ||||
| 				return true | ||||
| 			end | ||||
| 		else | ||||
| 			gamedata.servername			= "" | ||||
| 			gamedata.serverdescription	= "" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user