Last active
May 14, 2023 23:30
-
-
Save SwadicalRag/906dc2b3cd162559891cfde78f2144fe to your computer and use it in GitHub Desktop.
Load gmod addons from github repositories
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local function FetchSync(url) | |
local this = coroutine.running() | |
http.Fetch(url,function(...) | |
local suc,err = coroutine.resume(this,...) | |
if not suc then error(err) end | |
end,function(...) | |
-- local suc,err = coroutine.resume(this,...) | |
-- if not suc then error(err) end | |
end) | |
return coroutine.yield() | |
end | |
local function getDir(author,repo,dir) | |
return util.JSONToTable(FetchSync("https://api.github.com/repos/"..author.."/"..repo.."/contents/"..dir)) | |
end | |
local function getFile(author,repo,dir,branch) | |
local data,size,headers,code = FetchSync("https://rawgit.com/"..author.."/"..repo.."/"..(branch or "master").."/"..dir) | |
return (code ~= 404 and data) or false | |
end | |
local function includeRepoInternal(author,repo,getFileOverrides,runExtra) | |
local getEnv | |
local cDir = {""} | |
local function compileFileInternal(path,...) | |
path = "lua/"..path | |
local contents | |
if getFileOverrides[path] then | |
contents = getFileOverrides[path] | |
else | |
contents = getFile(author,repo,path) | |
if not contents then return false end | |
end | |
-- print("LOAD",path) | |
local fn = CompileString(contents,path) | |
if type(fn) == "function" then | |
debug.setfenv(fn,getEnv()) | |
-- local oFn = fn | |
-- fn = function(...) | |
-- return coroutine.wrap(oFn)(...) | |
-- end | |
end | |
return fn | |
end | |
local pathlookup = {} | |
local function compileFile(path) | |
local fn = compileFileInternal(cDir[#cDir]..path) | |
if not fn then | |
fn = compileFileInternal(path) | |
if not fn then | |
error(path.." not found!") | |
else | |
pathlookup[fn] = path | |
end | |
else | |
pathlookup[fn] = cDir[#cDir]..path | |
end | |
return fn | |
end | |
local function runFile(path,...) | |
local fn = compileFile(path,...) | |
-- print("RUN",path) | |
if type(fn) == "function" then | |
if pathlookup[fn] then path = pathlookup[fn] end | |
cDir[#cDir + 1] = path:match("^(.-/)[^/]+$") or "" | |
local errMsg | |
local ret = {xpcall(fn,function(err) | |
cDir[#cDir] = nil | |
errMsg = err | |
end,...)} | |
if not table.remove(ret,1) then error(errMsg) end | |
return unpack(ret) | |
else | |
error(fn) | |
end | |
end | |
getEnv = function() | |
return setmetatable({ | |
include = runFile, | |
CompileFile = compileFile | |
},{ | |
__index = _G, | |
__newindex = _G | |
}) | |
end | |
local function runFolder(path) | |
local data = getDir(author,repo,path) | |
for i,fileData in ipairs(data) do | |
if fileData.type == "file" then | |
local contents = FetchSync(fileData.download_url) | |
-- print("RUN",fileData.path) | |
local fn = CompileString(contents,fileData.path) | |
if type(fn) == "function" then | |
debug.setfenv(fn,getEnv()) | |
cDir[#cDir + 1] = fileData.path:match("^(.-/)[^/]+$") or "" | |
local errMsg | |
local suc = xpcall(fn,function(err) | |
cDir[#cDir] = nil | |
errMsg = err | |
end) | |
if not suc then error(errMsg) end | |
else | |
error(fn) | |
end | |
end | |
end | |
end | |
runFolder("lua/autorun/") | |
if CLIENT then | |
runFolder("lua/autorun/client/") | |
elseif SERVER then | |
runFolder("lua/autorun/server/") | |
end | |
for i,path in ipairs(runExtra or {}) do runFile(path) end | |
end | |
function includeRepo(...) | |
return coroutine.wrap(includeRepoInternal)(...) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local coroutine,debug,xpcall = me.wew'coroutine',me.wew'debug',me.wew'xpcall' | |
local function setfenv(fn, env) | |
if type(fn) ~= "function" then return print("WARN: non-function passed into setfenv()") end | |
local i = 1 | |
while true do | |
local name = debug.getupvalue(fn, i) | |
if name == "_ENV" then | |
debug.upvaluejoin(fn, i, (function() | |
return env | |
end), 1) | |
break | |
elseif not name then | |
break | |
end | |
i = i + 1 | |
end | |
return fn | |
end | |
local function FetchSync(url) | |
local this = coroutine.running() | |
http.Fetch(url,function(...) | |
local suc,err = coroutine.resume(this,...) | |
if not suc then error(err) end | |
end,function(...) | |
-- local suc,err = coroutine.resume(this,...) | |
-- if not suc then error(err) end | |
end) | |
return coroutine.yield() | |
end | |
local function getDir(author,repo,dir) | |
local _,c = FetchSync("https://api.github.com/repos/"..author.."/"..repo.."/contents/"..dir) | |
return json.decode(c) | |
end | |
local function getFile(author,repo,dir,branch) | |
local code,data = FetchSync("https://cdn.rawgit.com/"..author.."/"..repo.."/"..(branch or "master").."/"..dir) | |
return (code ~= 404 and data) or false | |
end | |
local function includeRepoInternal(author,repo) | |
local getEnv | |
local cDir = {""} | |
local function compileFileInternal(path,...) | |
path = "lua/"..path | |
local contents = getFile(author,repo,path) | |
if not contents then return false end | |
-- print("LOAD",path) | |
local fn = load(contents,path) | |
if type(fn) == "function" then | |
setfenv(fn,getEnv()) | |
-- local oFn = fn | |
-- fn = function(...) | |
-- return coroutine.wrap(oFn)(...) | |
-- end | |
end | |
return fn | |
end | |
local pathlookup = {} | |
local function compileFile(path) | |
local fn = compileFileInternal(cDir[#cDir]..path) | |
if not fn then | |
fn = compileFileInternal(path) | |
if not fn then | |
print("WARN: "..path.." not found!") | |
else | |
pathlookup[fn] = path | |
end | |
else | |
pathlookup[fn] = cDir[#cDir]..path | |
end | |
return fn | |
end | |
local function runFile(path,...) | |
local fn = compileFile(path,...) | |
-- print("RUN",path) | |
if type(fn) == "function" then | |
if pathlookup[fn] then path = pathlookup[fn] end | |
cDir[#cDir + 1] = path:match("^(.-/)[^/]+$") or "" | |
local errMsg | |
local ret = {xpcall(fn,function(err) | |
cDir[#cDir] = nil | |
errMsg = err | |
end,...)} | |
if not table.remove(ret,1) then error(errMsg) end | |
return unpack(ret) | |
else | |
error(fn) | |
end | |
end | |
getEnv = function() | |
return setmetatable({ | |
include = runFile, | |
CompileFile = compileFile, | |
setfenv = setfenv, | |
unpack = table.unpack, | |
coroutine = coroutine, | |
debug = debug, | |
file = { | |
Exists = function(path,type) | |
local thing = getFile(author,repo,"lua/"..path) | |
if thing then return true else return false end | |
end | |
} | |
},{ | |
__index = _G, | |
__newindex = _G | |
}) | |
end | |
local function runFolder(path) | |
local data = getDir(author,repo,path) | |
for i,fileData in ipairs(data) do | |
if fileData.type == "file" then | |
local _,contents = FetchSync(fileData.download_url) | |
-- print("RUN",fileData.path) | |
local fn = load(contents,fileData.path) | |
if type(fn) == "function" then | |
setfenv(fn,getEnv()) | |
cDir[#cDir + 1] = fileData.path:match("^(.-/)[^/]+$") or "" | |
local errMsg | |
local suc = xpcall(coroutine.wrap(fn),function(err) | |
cDir[#cDir] = nil | |
errMsg = err | |
end) | |
if not suc then error(errMsg) end | |
else | |
error(fn) | |
end | |
end | |
end | |
end | |
local function init() | |
runFolder("lua/autorun/") | |
if CLIENT then | |
runFolder("lua/autorun/client/") | |
elseif SERVER then | |
runFolder("lua/autorun/server/") | |
end | |
end | |
return runFile,init | |
end | |
function includeRepo(...) | |
return coroutine.wrap(includeRepoInternal)(...) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment