240 lines
6.3 KiB
Lua
240 lines
6.3 KiB
Lua
--------------------------------------------------------
|
|
-- Minetest :: Configuration Panel Mod (config)
|
|
--
|
|
-- See README.txt for licensing and other information.
|
|
-- Copyright (c) 2016-2020, Leslie E. Krause
|
|
--
|
|
-- ./games/minetest_game/mods/config/init.lua
|
|
--------------------------------------------------------
|
|
|
|
local world_path = minetest.get_worldpath( )
|
|
local configured_mods = { }
|
|
|
|
---------------------
|
|
-- Private Methods --
|
|
---------------------
|
|
|
|
local function import( config, filename )
|
|
local func = loadfile( filename )
|
|
if func then
|
|
setfenv( func, config )
|
|
local status = pcall( func )
|
|
if not status then
|
|
error( "Syntax error in configuration file: " .. filename )
|
|
end
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function load_world_config( mod_name )
|
|
local file = io.open( world_path .. "/config/" .. mod_name .. ".lua", "r" )
|
|
if not file then return nil end
|
|
|
|
local data = file:read( "*all" )
|
|
file:close( )
|
|
return data
|
|
end
|
|
|
|
local function load_game_config( mod_name )
|
|
local file = io.open( minetest.get_modpath( mod_name ) .. "/config.lua", "r" )
|
|
if not file then return nil end
|
|
|
|
local data = file:read( "*all" )
|
|
file:close( )
|
|
return data
|
|
end
|
|
|
|
local function save_world_config( mod_name, data )
|
|
local file = io.open( world_path .. "/config/" .. mod_name .. ".lua", "w" )
|
|
if not file then return false end
|
|
|
|
file:write( data )
|
|
file:close( )
|
|
return true
|
|
end
|
|
|
|
local function save_game_config( mod_name, data )
|
|
local file = io.open( minetest.get_modpath( mod_name ) .. "/config.lua", "w" )
|
|
if not file then return false end
|
|
|
|
file:write( data )
|
|
file:close( )
|
|
return true
|
|
end
|
|
|
|
local function create_world_config( mod_name )
|
|
local file = io.open( world_path .. "/config/" .. mod_name .. ".lua", "w" )
|
|
if not file then return false end
|
|
|
|
file:close( )
|
|
return true
|
|
end
|
|
|
|
local function create_game_config( mod_name )
|
|
local file = io.open( minetest.get_modpath( mod_name ) .. "/config.lua", "w" )
|
|
if not file then return false end
|
|
|
|
file:close( )
|
|
return true
|
|
end
|
|
|
|
local function delete_world_config( mod_name )
|
|
return os.remove( world_path .. "/config/" .. mod_name .. ".lua" ) ~= nil
|
|
end
|
|
|
|
local function delete_game_config( mod_name )
|
|
return os.remove( minetest.get_modpath( mod_name ) .. "/config.lua" ) ~= nil
|
|
end
|
|
|
|
local function open_config_editor( player_name, mod_name )
|
|
local origin_idx
|
|
local content
|
|
local delete_config, create_config, load_config, save_config
|
|
|
|
local function reset_origin_map( idx )
|
|
origin_idx = idx
|
|
|
|
if origin_idx == 1 then
|
|
delete_config = delete_game_config
|
|
create_config = create_game_config
|
|
load_config = load_game_config
|
|
save_config = save_game_config
|
|
else
|
|
delete_config = delete_world_config
|
|
create_config = create_world_config
|
|
load_config = load_world_config
|
|
save_config = save_world_config
|
|
end
|
|
end
|
|
|
|
local function get_formspec( )
|
|
local formspec =
|
|
"size[10.0,8.5]" ..
|
|
default.gui_bg ..
|
|
default.gui_bg_img ..
|
|
|
|
string.format( "label[0.0,0.1;Configuration for mod '%s']", mod_name ) ..
|
|
"label[2.2,8.0;Origin:]" ..
|
|
string.format( "dropdown[3.1,7.9;2.6,1.0;origin;Game Config,World Config;%d;true]", origin_idx )
|
|
|
|
if not content then
|
|
formspec = formspec ..
|
|
"box[0.0,0.8;9.8.0,6.6;#222222]" ..
|
|
"label[4.0,3.8;File does not exist.]" ..
|
|
|
|
"button_exit[0.0,7.8;2.0,1.0;close;Close]" ..
|
|
"button[8.0,7.8;2.0,1.0;create;Create]"
|
|
else
|
|
formspec = formspec ..
|
|
"textarea[0.3,0.8;10.0,7.6;content;;" .. minetest.formspec_escape( content ) .. "]" ..
|
|
|
|
"button_exit[0.0,7.8;2.0,1.0;close;Close]" ..
|
|
"button[6.0,7.8;2.0,1.0;delete;Delete]" ..
|
|
"button[8.0,7.8;2.0,1.0;save;Save]"
|
|
end
|
|
|
|
return formspec
|
|
end
|
|
|
|
local function on_close( state, player, fields )
|
|
if fields.quit then return end -- short-circuit on form closure
|
|
|
|
if fields.save then
|
|
content = fields.content
|
|
save_config( mod_name, content )
|
|
|
|
elseif fields.load then
|
|
content = load_config( mod_name )
|
|
minetest.update_form( player_name, get_formspec ( ) )
|
|
|
|
elseif fields.delete then
|
|
if not delete_config( mod_name ) then
|
|
minetest.destroy_form( player_name )
|
|
minetest.chat_send_player( player_name, "Unable to delete configuration file." )
|
|
end
|
|
content = nil
|
|
minetest.update_form( player_name, get_formspec ( ) )
|
|
|
|
elseif fields.create then
|
|
if not create_config( mod_name ) then
|
|
minetest.destroy_form( player_name )
|
|
minetest.chat_send_player( player_name, "Unable to create configuration file." )
|
|
end
|
|
content = ""
|
|
minetest.update_form( player_name, get_formspec ( ) )
|
|
|
|
elseif fields.origin then
|
|
reset_origin_map( fields.origin )
|
|
content = load_config( mod_name )
|
|
minetest.update_form( player_name, get_formspec ( ) )
|
|
|
|
end
|
|
end
|
|
|
|
reset_origin_map( 1 )
|
|
content = load_config( mod_name )
|
|
|
|
minetest.create_form( nil, player_name, get_formspec( ), on_close )
|
|
end
|
|
|
|
--------------------
|
|
-- Public Methods --
|
|
--------------------
|
|
|
|
minetest.load_config = function ( base_config, options )
|
|
local name = minetest.get_current_modname( )
|
|
local path = minetest.get_modpath( name )
|
|
local config = { } or base_config
|
|
local status
|
|
|
|
if not options then options = { } end
|
|
|
|
config.core = {
|
|
MOD_NAME = name,
|
|
MOD_PATH = path,
|
|
WORLD_PATH = world_path,
|
|
sprintf = string.format,
|
|
date = os.date,
|
|
time = os.time,
|
|
}
|
|
|
|
if options.can_override then
|
|
status = import( config, path .. "/config.lua" )
|
|
status = import( config, world_path .. "/config/" .. name .. ".lua" ) or status
|
|
else
|
|
status = import( config, path .. "/config.lua" ) or import( config, world_path .. "/config/" .. name .. ".lua" )
|
|
end
|
|
|
|
if not status then
|
|
minetest.log( "warning", "Missing configuration file for mod \"" .. name .. "\"" )
|
|
end
|
|
|
|
configured_mods[ name ] = {
|
|
base_config = base_config,
|
|
can_refresh = options.can_refresh,
|
|
can_override = options.can_override,
|
|
}
|
|
config.core = nil
|
|
|
|
return config
|
|
end
|
|
|
|
------------------------------
|
|
-- Registered Chat Commands --
|
|
------------------------------
|
|
|
|
minetest.register_chatcommand( "config", {
|
|
description = "View and edit the configuration for a given mod.",
|
|
privs = { server = true },
|
|
func = function( player_name, param )
|
|
if not string.match( param, "^[a-zA-Z0-9_]+$" ) then
|
|
return false, "Invalid mod name."
|
|
elseif not configured_mods[ param ] then
|
|
return false, "Configuration not available."
|
|
end
|
|
|
|
open_config_editor( player_name, param )
|
|
end
|
|
} )
|