165 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
-- Important: This is only of relevance for the Server YourLand -
 | 
						|
--            which was running an older version of this mod and nees
 | 
						|
--            adjustments for the newer version.
 | 
						|
--
 | 
						|
--            And even on that server the file was relevant only once.
 | 
						|
--            It is mainly included here as an example of how to iterate
 | 
						|
--            over all existing NPC (at least those who have dialogs!).
 | 
						|
---
 | 
						|
-- Rename this file to
 | 
						|
-- 	local_server_do_on_reload.lua
 | 
						|
-- and execute
 | 
						|
-- 	/npc_talk_migrate
 | 
						|
-- in order to automaticly add the necessary privs for all existing old NPC.
 | 
						|
--
 | 
						|
-- NPC dialogs are checked and reported if broken.
 | 
						|
 | 
						|
yl_speak_up.migration_npc_needs_priv = function(n_id, pname, counter, priv_name)
 | 
						|
	if(counter < 1) then
 | 
						|
		return
 | 
						|
	end
 | 
						|
	-- does the NPC have the priv already?
 | 
						|
	if(yl_speak_up.npc_has_priv(n_id, priv_name, nil)) then
 | 
						|
		minetest.chat_send_player(pname, "      OK: "..tostring(n_id).." has priv "..priv_name)
 | 
						|
		return
 | 
						|
	end
 | 
						|
	-- grant the NPC the priv
 | 
						|
	minetest.chat_send_player(pname, "      GRANTING "..tostring(n_id).." priv "..priv_name)
 | 
						|
	if(not(yl_speak_up.npc_priv_table[n_id])) then
 | 
						|
		yl_speak_up.npc_priv_table[n_id] = {}
 | 
						|
	end
 | 
						|
	yl_speak_up.npc_priv_table[n_id][priv_name] = true
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
yl_speak_up.check_one_npc_for_migration = function(dialog, pname, n_id, fname)
 | 
						|
	minetest.chat_send_player(pname, "  Checking NPC "..tostring(fname)..
 | 
						|
				" \""..tostring(dialog.n_npc or "- nameless -").."\"...")
 | 
						|
	-- nothing defined yet - nothing to repair
 | 
						|
	if(not(dialog.n_dialogs)) then
 | 
						|
		minetest.chat_send_player(pname, "    NPC "..tostring(n_id).." has nothing to say.")
 | 
						|
		return
 | 
						|
	end
 | 
						|
	local c_effect_exec_lua = 0
 | 
						|
	local c_effect_give_item = 0
 | 
						|
	local c_effect_take_item = 0
 | 
						|
	local c_effect_move_player = 0
 | 
						|
	local c_precon_exec_lua = 0
 | 
						|
	-- iterate over all dialogs
 | 
						|
	for d_id, d in pairs(dialog.n_dialogs) do
 | 
						|
		if(d_id and d and d.d_options) then
 | 
						|
			-- iterate over all options
 | 
						|
			for o_id, o in pairs(d.d_options) do
 | 
						|
				if(o_id and o and o.o_results) then
 | 
						|
					local has_close_formspec = false
 | 
						|
					local dialog_results = {}
 | 
						|
					-- iterate over all results
 | 
						|
					for r_id, r in pairs(o.o_results) do
 | 
						|
						if(r.r_type == "dialog") then
 | 
						|
							table.insert(dialog_results, r_id)
 | 
						|
						elseif(r.r_type == "function") then
 | 
						|
							c_effect_exec_lua    = c_effect_exec_lua + 1
 | 
						|
							-- if the formspec is closed, we need to use the
 | 
						|
							-- target dialog d_end
 | 
						|
							if(string.find(r.r_value , "minetest.close_formspec")) then
 | 
						|
								has_close_formspec = true
 | 
						|
							end
 | 
						|
						elseif(r.r_type == "move") then
 | 
						|
							c_effect_move_player = c_effect_move_player + 1
 | 
						|
						elseif(r.r_type == "give_item") then
 | 
						|
							c_effect_give_item   = c_effect_give_item + 1
 | 
						|
						elseif(r.r_type == "take_item") then
 | 
						|
							c_effect_take_item   = c_effect_take_item + 1
 | 
						|
						end
 | 
						|
					end
 | 
						|
					if(#dialog_results>1) then
 | 
						|
						local msg = "ERROR: Dialog "..
 | 
						|
							tostring(d_id)..", option "..tostring(o_id)..
 | 
						|
							", has multiple results of type dialog: "..
 | 
						|
							minetest.serialize(dialog_results)..". Please "..
 | 
						|
							"let someone with npc_master priv fix that first!"
 | 
						|
						yl_speak_up.log_change(pname, n_id, msg, "error")
 | 
						|
						if(pname) then
 | 
						|
							minetest.chat_send_player(pname, msg)
 | 
						|
						end
 | 
						|
					-- sometimes we need d_end because minetest.close_formspec in
 | 
						|
					-- an effect of type "function" is not enough
 | 
						|
					elseif(has_close_formspec) then
 | 
						|
						local found = false
 | 
						|
						local d_old = ""
 | 
						|
						for r_id, r in pairs(o.o_results) do
 | 
						|
							if(r.r_type == "dialog" and not(found)) then
 | 
						|
								d_old = r.r_value
 | 
						|
								r.r_value = "d_end"
 | 
						|
								found = true
 | 
						|
							end
 | 
						|
						end
 | 
						|
						-- if there is no dialog option yet: create one
 | 
						|
						if(not(found)) then
 | 
						|
							local future_r_id = yl_speak_up.add_new_result(
 | 
						|
									dialog, d_id, o_id)
 | 
						|
							o.o_results[future_r_id] = {
 | 
						|
								r_id = future_r_id,
 | 
						|
								r_type = "dialog",
 | 
						|
								r_value = "d_end"}
 | 
						|
						end
 | 
						|
						if(d_old ~= "d_end") then
 | 
						|
							yl_speak_up.save_dialog(n_id, dialog)
 | 
						|
							local msg = "ERROR: Dialog "..
 | 
						|
								tostring(d_id)..", option "..tostring(o_id)..
 | 
						|
								", uses minetest.close_formspec in its "..
 | 
						|
								"lua code but "..tostring(d_old)..
 | 
						|
								" instead of d_end as target dialog. Fixing."
 | 
						|
							minetest.chat_send_player(pname, msg)
 | 
						|
						end
 | 
						|
					end
 | 
						|
				end
 | 
						|
				if(o_id and o and o.o_prerequisites) then
 | 
						|
					for p_id, p in pairs(o.o_prerequisites) do
 | 
						|
						if(p.p_type == "function") then
 | 
						|
							c_precon_exec_lua    = c_precon_exec_lua + 1
 | 
						|
						end
 | 
						|
					end
 | 
						|
				end
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end
 | 
						|
	yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_exec_lua, "effect_exec_lua")
 | 
						|
	yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_give_item, "effect_give_item")
 | 
						|
	yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_take_item, "effect_take_item")
 | 
						|
	yl_speak_up.migration_npc_needs_priv(n_id, pname, c_effect_move_player, "effect_move_player")
 | 
						|
	yl_speak_up.migration_npc_needs_priv(n_id, pname, c_precon_exec_lua, "precon_exec_lua")
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
yl_speak_up.check_all_npc_for_migration = function(pname)
 | 
						|
	local path = yl_speak_up.worldpath..yl_speak_up.path.."/"
 | 
						|
	local file_names = minetest.get_dir_list(path, false)
 | 
						|
	minetest.chat_send_player(pname, "There are "..tostring(#file_names).." NPCs with stored dialogs "..
 | 
						|
		"in folder "..path..".")
 | 
						|
	for i, fname in ipairs(file_names) do
 | 
						|
		local file, err = io.open(path..fname, "r")
 | 
						|
		io.input(file)
 | 
						|
		local content = io.read()
 | 
						|
		local dialog = minetest.parse_json(content)
 | 
						|
		io.close(file)
 | 
						|
		if type(dialog) ~= "table" then
 | 
						|
			dialog = {}
 | 
						|
		end
 | 
						|
		yl_speak_up.check_one_npc_for_migration(dialog, pname, string.sub(fname, 0, -6), fname)
 | 
						|
	end
 | 
						|
	minetest.chat_send_player(pname, "Done with checking all NPC files for migration.")
 | 
						|
	-- store the changed privs
 | 
						|
	yl_speak_up.npc_privs_store()
 | 
						|
	return true
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
minetest.register_chatcommand( 'npc_talk_migrate', {
 | 
						|
        description = "Checks NPC from old yl_speak_up for migration to new version of the mod.",
 | 
						|
        privs = {npc_master = true},
 | 
						|
        func = function(pname, param)
 | 
						|
		return yl_speak_up.check_all_npc_for_migration(pname)
 | 
						|
	end
 | 
						|
})
 |