forked from your-land-mirror/yl_speak_up
		
	
		
			
				
	
	
		
			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
 | |
| })
 |