This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 0e770b2b49
commit 94063e4369
7342 changed files with 1718932 additions and 14 deletions

View File

@@ -0,0 +1,201 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local CL_LIMIT, CL_LIMIT_OVERRIDE, CL_NO_CLENGTH
if CLIENT then
CL_LIMIT = CreateConVar("pac_webcontent_limit", "-1", {FCVAR_ARCHIVE}, "webcontent limit in kb, -1 = unlimited")
CL_NO_CLENGTH = CreateConVar("pac_webcontent_allow_no_content_length", "0", {FCVAR_ARCHIVE}, "allow downloads with no content length")
CL_LIMIT_OVERRIDE = CreateConVar("pac_webcontent_limit_force", "0", {FCVAR_ARCHIVE}, "Override serverside setting")
end
local SV_LIMIT = CreateConVar("sv_pac_webcontent_limit", "-1", CLIENT and {FCVAR_REPLICATED} or {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "webcontent limit in kb, -1 = unlimited")
local SV_NO_CLENGTH = CreateConVar("sv_pac_webcontent_allow_no_content_length", "-1", CLIENT and {FCVAR_REPLICATED} or {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "allow downloads with no content length")
function pac.FixGMODUrl(url)
-- to avoid "invalid url" errors
-- gmod does not allow urls containing "10.", "172.16.", "192.168.", "127." or "://localhost"
-- we escape 10. and 127. can occur (mydomain.com/model10.zip) and assume the server supports
-- the escaped request
return url:Replace("10.", "%31%30%2e"):Replace("127.", "%31%32%37%2e")
end
local function http(method, url, headers, cb, failcb)
url = pac.FixGMODUrl(url)
return HTTP({
method = method,
url = url,
headers = headers,
success = function(code, data, headers)
if code < 400 then
cb(data, #data, headers)
else
local header = {}
for k,v in pairs(headers) do
table.insert(header, tostring(k) .. ": " .. tostring(v))
end
local err = "server returned code " .. code .. ":\n\n"
err = err .. "url: "..url.."\n"
err = err .. "================\n"
err = err .. "HEADER:\n"
err = err .. table.concat(header, "\n") .. "\n"
err = err .. "================\n"
err = err .. "BODY:\n"
err = err .. data .. "\n"
err = err .. "================\n"
failcb(err, code >= 400, code)
end
end,
failed = function(err)
if failcb then
failcb("_G.HTTP error: " .. err)
else
pac.Message("_G.HTTP error: " .. err)
end
end
})
end
function pac.FixUrl(url)
url = url:Trim()
url = url:gsub("[\"'<>\n\\]+", "")
if url:find("dropbox", 1, true) then
url = url:gsub([[^http%://dl%.dropboxusercontent%.com/]], [[https://dl.dropboxusercontent.com/]])
url = url:gsub([[^https?://dl.dropbox.com/]], [[https://www.dropbox.com/]])
url = url:gsub([[^https?://www.dropbox.com/s/(.+)%?dl%=[01]$]], [[https://dl.dropboxusercontent.com/s/%1]])
url = url:gsub([[^https?://www.dropbox.com/s/(.+)$]], [[https://dl.dropboxusercontent.com/s/%1]])
url = url:gsub([[^https?://www.dropbox.com/scl/(.+)$]], [[https://dl.dropboxusercontent.com/scl/%1]]) --Fix for new dropbox format.
return url
end
if url:find("drive.google.com", 1, true) and not url:find("export=download", 1, true) then
local id =
url:match("https://drive.google.com/file/d/(.-)/") or
url:match("https://drive.google.com/file/d/(.-)$") or
url:match("https://drive.google.com/open%?id=(.-)$")
if id then
return "https://drive.google.com/uc?export=download&id=" .. id
end
return url
end
if url:find("gitlab.com", 1, true) then
return url:gsub("^(https?://.-/.-/.-/)blob", "%1raw")
end
url = url:gsub([[^http%://onedrive%.live%.com/redir?]],[[https://onedrive.live.com/download?]])
url = url:gsub("pastebin.com/([a-zA-Z0-9]*)$", "pastebin.com/raw.php?i=%1")
url = url:gsub("github.com/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/blob/", "github.com/%1/%2/raw/")
return url
end
function pac.getContentLength(url, cb, failcb)
return http("HEAD", url, {["Accept-Encoding"] = "none"}, function(_, _, headers)
local length
-- server have rights to send headers in any case
for key, value in pairs(headers) do
if string.lower(key) == "content-length" then
length = tonumber(value)
if not length or math.floor(length) ~= length then
return failcb(string.format("malformed server reply with header content-length (got %q, expected valid integer number)", value), true)
end
break
end
end
if length then return cb(length) end
return pac.contentLengthFallback(url, cb, failcb)
end, function(err, over400, code)
if code == 405 then
return pac.contentLengthFallback(url, cb, failcb)
end
return failcb(err, over400)
end )
end
-- Performs a GET but requests 0 bytes
-- We can then read the response headers to determine the content size.
-- This allows Google Drive and other hosts to work with PAC even with content-length limits set
-- (They typically block HEAD requests)
function pac.contentLengthFallback(url, cb, failcb)
local function fail()
return failcb("unable to determine content length", true)
end
return http("GET", url, {["Range"] = "bytes=0-0"}, function(data, data_length, headers)
-- e.g. "bytes 0-0/11784402"
local contentRange = headers["Content-Range"]
if not contentRange then return fail() end
local spl = string.Split(contentRange, "/")
local contentLength = spl[2]
if contentLength then return cb(tonumber(contentLength)) end
return fail()
end )
end
function pac.HTTPGet(url, cb, failcb)
if not url or url:len() < 4 then
failcb("url length is less than 4 (" .. tostring(url) .. ")", true)
return
end
url = pac.FixUrl(url)
local limit = SV_LIMIT:GetInt()
if CLIENT and (CL_LIMIT_OVERRIDE:GetBool() or limit == -1) then
limit = CL_LIMIT:GetInt()
end
if limit == -1 then
return http("GET", url, nil, cb, failcb)
end
return pac.getContentLength(url, function(length)
if length then
if length <= (limit * 1024) then
http("GET", url, nil, cb, failcb)
else
failcb("download is too big (" .. string.NiceSize(length) .. ")", true)
end
else
local allow_no_contentlength = SV_NO_CLENGTH:GetInt()
if CLIENT and (CL_LIMIT_OVERRIDE:GetBool() or allow_no_contentlength < 0) then
allow_no_contentlength = CL_NO_CLENGTH:GetInt()
end
if allow_no_contentlength > 0 then
http("GET", url, nil, cb, failcb)
else
failcb("unknown file size when allow_no_contentlength is " .. allow_no_contentlength, true)
end
end
end, failcb)
end