-- 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 })