mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

script.lua (3231B)


      1 local lfs = require( "lfs" )
      2 local serialize = require( "serialize" )
      3 
      4 local PathSeparator = package.config:match( "^([^\n]+)" )
      5 
      6 local ScriptsDirs
      7 if mud.os == "windows" then
      8 	ScriptsDirs = {
      9 		os.getenv( "APPDATA" ) .. "\\Mud Gangster\\scripts",
     10 		os.getenv( "USERPROFILE" ) .. "\\Documents\\Mud Gangster\\scripts",
     11 	}
     12 else
     13 	ScriptsDirs = { os.getenv( "HOME" ) .. "/.mudgangster/scripts" }
     14 end
     15 
     16 local function loadScript( name, path, padding )
     17 	local function throw( err )
     18 		if err:match( "^" .. path ) then
     19 			err = err:sub( path:len() + 2 )
     20 		end
     21 
     22 		mud.print( "#lr%-" .. padding .. "s", name )
     23 		mud.print( "#s\n>\n>     %s\n>", err )
     24 	end
     25 
     26 	mud.print( "#s\n>   " )
     27 
     28 	local mainPath = path .. PathSeparator .. "main.lua"
     29 	local readable, err = io.readable( mainPath )
     30 
     31 	if not readable then
     32 		throw( err )
     33 
     34 		return
     35 	end
     36 
     37 	local env = setmetatable(
     38 		{
     39 			require = function( requirePath, ... )
     40 				return require( "%s.%s" % { name, requirePath }, ... )
     41 			end,
     42 
     43 			saved = function( defaults )
     44 				local settingsPath = path .. PathSeparator .. "settings.lua"
     45 
     46 				mud.listen( "shutdown", function()
     47 					local file = io.open( settingsPath, "w" )
     48 					file:write( serialize.unwrapped( defaults ) )
     49 					file:close()
     50 				end )
     51 
     52 				local settingsEnv = setmetatable( { }, {
     53 					__newindex = defaults,
     54 				} )
     55 
     56 				local settings = loadfile( settingsPath, "t", settingsEnv )
     57 
     58 				if not settings then
     59 					return defaults
     60 				end
     61 
     62 				if _VERSION == "Lua 5.1" then
     63 					setfenv( settings, settingsEnv )
     64 				end
     65 
     66 				pcall( settings )
     67 
     68 				return defaults
     69 			end,
     70 		},
     71 		{
     72 			__index = _G,
     73 			__newindex = _G,
     74 		}
     75 	)
     76 
     77 	local script, err = loadfile( mainPath, "t", env )
     78 
     79 	if not script then
     80 		throw( err )
     81 
     82 		return
     83 	end
     84 
     85 	if _VERSION == "Lua 5.1" then
     86 		setfenv( script, env )
     87 	end
     88 
     89 	local loaded, err = pcall( script )
     90 
     91 	if loaded then
     92 		mud.print( "#lg%s", name )
     93 	else
     94 		throw( err )
     95 	end
     96 end
     97 
     98 local function loadScriptsFrom( dir )
     99 	mud.print( "\n#s> Loading scripts from %s... ", dir )
    100 
    101 	local readable, err = io.readable( dir )
    102 
    103 	if not readable then
    104 		mud.print( "#lrfailed!\n#s>     %s", err )
    105 		return
    106 	end
    107 
    108 	local attr = lfs.attributes( dir )
    109 
    110 	if attr.mode == "directory" then
    111 		local old_package_path = package.path
    112 		package.path = old_package_path .. ";" .. dir .. PathSeparator .. "?.lua"
    113 
    114 		local scripts = { }
    115 		local maxLen = 0
    116 
    117 		for script in lfs.dir( dir ) do
    118 			if not script:match( "^%." ) then
    119 				local path = dir .. PathSeparator .. script
    120 				local scriptAttr = lfs.attributes( path )
    121 
    122 				if scriptAttr.mode == "directory" then
    123 					maxLen = math.max( script:len(), maxLen )
    124 
    125 					table.insert( scripts, {
    126 						name = script,
    127 						path = path,
    128 					} )
    129 				end
    130 			end
    131 		end
    132 
    133 		table.sort( scripts, function( a, b )
    134 			return a.name < b.name
    135 		end )
    136 
    137 		for _, script in ipairs( scripts ) do
    138 			loadScript( script.name, script.path, maxLen )
    139 		end
    140 
    141 		package.path = old_package_path
    142 	else
    143 		mud.print( "#lrfailed!\n#s>     `%s' isn't a directory", dir )
    144 	end
    145 end
    146 
    147 local function loadScripts( exe_path )
    148 	for _, dir in ipairs( ScriptsDirs ) do
    149 		loadScriptsFrom( dir )
    150 	end
    151 
    152 	loadScriptsFrom( exe_path .. PathSeparator .. "scripts" )
    153 
    154 	mud.event( "scriptsLoaded" )
    155 end
    156 
    157 return {
    158 	load = loadScripts,
    159 }