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 }