airminer96

fsPlugins

Mar 29th, 2013
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.88 KB | None | 0 0
  1. -- fsPlugins created by airminer96
  2.  
  3. ------------
  4. -- Fields --
  5. ------------
  6.  
  7. -- Debug option
  8. local debug = false
  9.  
  10. -- The functions to be replaced from the fs API
  11. local keys = {"list","exists","isDir","isReadOnly","getDrive","getSize","getFreeSpace","makeDir","delete","open"}
  12.  
  13. -- The original values from the fs API
  14. local fsRaw = {}
  15.  
  16. -- The original value of os.unloadAPI
  17. local unloadRaw
  18.  
  19. -- The list of the registered handlers
  20. local handlers = {}
  21.  
  22. ----------------
  23. -- Public API --
  24. ----------------
  25.  
  26. --[[
  27.   Register a handler
  28.   parameters: handler
  29.     A handler is a function, which is passed the following paramters:
  30.       path: the path of the file being resolved
  31.       handle: the table, from which the fs API methods should be grabbed from
  32.       action: the name of the fs API method being used
  33.     A handler must return the following values:
  34.       path: the overridden path of the file being resolved
  35.       handle: the overridden table, from which the fs API methods should be grabbed from
  36. ]]
  37. function registerHandler(handler)
  38.   if type(handler) == "function" then
  39.     table.insert(handlers,handler)
  40.   else
  41.     error("Registered handler is not a function",2)
  42.   end
  43. end
  44.  
  45. --[[
  46.   Removes a handler
  47.   parameters: handler
  48. ]]
  49. function removeHandler(handler)
  50.   for k,v in ipairs(handlers) do
  51.     if v == handler then
  52.       table.remove(handlers,k)
  53.     end
  54.   end
  55. end
  56.  
  57. ---------------
  58. -- Internals --
  59. ---------------
  60.  
  61. -- Checks if the response from a handler is valid
  62. local function responseValid(path, handle)
  63.   if (type(path) == "string" or type(path) == "nil") and (type(handle) == "table" or type(handle) == "nil") then
  64.     for k,v in ipairs(keys) do
  65.       if type(handle[v]) ~= "function" then
  66.         return false
  67.       end
  68.     end
  69.     return true
  70.   end
  71.   return false
  72. end
  73.  
  74. -- Calls a handler, and removes it if it's response isn't valid
  75. local function callHandler(handler, path, handle, action)
  76.   p,h = handler(path, handle, action)
  77.   if responseValid(p,h) then
  78.     return p,h
  79.   else
  80.     removeHandler(handler)
  81.     return path,handle
  82.   end
  83. end
  84.  
  85. -- Resolves a path
  86. local function resolve(path, action)
  87.   -- Quickfix for infinite looping
  88.   loop = 0
  89.   p = path
  90.   h = fsRaw
  91.   trace = {}
  92.   activeHandlers = {unpack(handlers)}
  93.   while #activeHandlers > 0  and loop < 100 do
  94.     loop = loop + 1
  95.     p1,h1 = callHandler(activeHandlers[1],p,h,action)
  96.     if (p ~= p1) or (h ~= h1) then
  97.       activeHandlers = {unpack(handlers)}
  98.       p = p1
  99.       h = h1
  100.     else
  101.       table.remove(activeHandlers,1)
  102.     end
  103.   end
  104.   if debug then
  105.     print(path.." --> "..p)
  106.   end
  107.   return p,h
  108. end
  109.  
  110. -- Creates a wrapper function for the fs API function with the name of <action>
  111. local function funcFactory(action)
  112.   return function(path, ...)
  113.     p,h = resolve(path, action)
  114.     return h[action](p, ...)
  115.   end
  116. end
  117.  
  118. -- The hook which overrides os.unloadAPI
  119. local function unload(name)
  120.   if name == "fsPlugins" and fsPlugins then
  121.     -- Restore fs API
  122.     for k,v in pairs(fsRaw) do
  123.       fs[k] = v
  124.     end
  125.   end
  126.   if (name == "fsPlugins" or fsPlugins == nil) and os.unloadAPI == unload then
  127.       -- Restore os.unloadAPI
  128.       os.unloadAPI = unloadRaw
  129.   end
  130.   unloadRaw(name)
  131. end  
  132.  
  133. -- os.loadAPI sequence
  134. if shell == nil then
  135.   if fsPlugins then
  136.     -- Unload API if already loaded
  137.     os.unloadAPI("fsPlugins")
  138.   end
  139.   -- Override os.unloadAPI
  140.   unloadRaw = os.unloadAPI
  141.   os.unloadAPI = unload
  142.   -- Override fs API
  143.   for k,v in ipairs(keys) do
  144.     fsRaw[v] = fs[v]
  145.     fs[v] = funcFactory(v)
  146.   end
  147. -- Shell program sequence
  148. else
  149.   tArgs = {...}
  150.   if tArgs[1] == "load" then
  151.     -- Load API
  152.     os.loadAPI(shell.getRunningProgram())
  153.   elseif tArgs[1] == "unload" then
  154.     -- Unload API
  155.     os.unloadAPI("fsPlugins")
  156.   else
  157.     -- Print Usages
  158.     print("Usages:\nfsPlugins help\nfsPlugins api\nfsPlugins load\nfsPlugins unload")
  159.   end
  160. end
Advertisement
Add Comment
Please, Sign In to add comment