mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 05:43:46 +03:00
Upload
This commit is contained in:
227
lua/gm_express/sh_init.lua
Normal file
227
lua/gm_express/sh_init.lua
Normal file
@@ -0,0 +1,227 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
require( "pon" )
|
||||
if SERVER then
|
||||
util.AddNetworkString( "express" )
|
||||
util.AddNetworkString( "express_proof" )
|
||||
util.AddNetworkString( "express_receivers_made" )
|
||||
end
|
||||
|
||||
express = {}
|
||||
express._receivers = {}
|
||||
express._protocol = "http"
|
||||
express._awaitingProof = {}
|
||||
express._preDlReceivers = {}
|
||||
express._maxDataSize = 24 * 1024 * 1024
|
||||
express._jsonHeaders = { ["Content-Type"] = "application/json" }
|
||||
express._bytesHeaders = { ["Accept"] = "application/octet-stream" }
|
||||
|
||||
|
||||
-- Removes a receiver --
|
||||
function express.ClearReceiver( message )
|
||||
message = string.lower( message )
|
||||
express._receivers[message] = nil
|
||||
end
|
||||
|
||||
|
||||
-- Registers a PreDownload receiver --
|
||||
function express.ReceivePreDl( message, preDl )
|
||||
message = string.lower( message )
|
||||
express._preDlReceivers[message] = preDl
|
||||
end
|
||||
|
||||
|
||||
-- Retrieves and parses the data for given ID --
|
||||
function express:Get( id, cb, _attempts )
|
||||
_attempts = _attempts or 0
|
||||
local url = self:makeAccessURL( "read", id )
|
||||
|
||||
local success = function( code, body )
|
||||
if code == 404 then
|
||||
assert( _attempts <= 35, "express:Get() failed to retrieve data after 35 attempts: " .. id )
|
||||
timer.Simple( 0.125 * _attempts, function()
|
||||
self:Get( id, cb, _attempts + 1 )
|
||||
end )
|
||||
return
|
||||
end
|
||||
|
||||
express._checkResponseCode( code )
|
||||
if _attempts > 0 then
|
||||
print( "express:Get() succeeded after " .. _attempts .. " attempts: " .. id )
|
||||
end
|
||||
|
||||
if string.StartWith( body, "<enc>" ) then
|
||||
body = util.Decompress( string.sub( body, 6 ) )
|
||||
if ( not body ) or #body == 0 then
|
||||
error( "Express: Failed to decompress data for ID '" .. id .. "'." )
|
||||
end
|
||||
end
|
||||
|
||||
local hash = util.SHA1( body )
|
||||
local decodedData = pon.decode( body )
|
||||
cb( decodedData, hash )
|
||||
end
|
||||
|
||||
HTTP( {
|
||||
method = "GET",
|
||||
url = url,
|
||||
success = success,
|
||||
failed = error,
|
||||
headers = self._bytesHeaders,
|
||||
timeout = self:_getTimeout()
|
||||
} )
|
||||
end
|
||||
|
||||
|
||||
-- Asks the API for this ID's data's size --
|
||||
function express:GetSize( id, cb )
|
||||
local url = self:makeAccessURL( "size", id )
|
||||
|
||||
local success = function( code, body )
|
||||
express._checkResponseCode( code )
|
||||
|
||||
local sizeHolder = util.JSONToTable( body )
|
||||
assert( sizeHolder, "Invalid JSON" )
|
||||
|
||||
local size = sizeHolder.size
|
||||
if not size then
|
||||
print( "Express: Failed to get size for ID '" .. id .. "'.", code )
|
||||
print( body )
|
||||
end
|
||||
assert( size, "No size data" )
|
||||
|
||||
cb( tonumber( size ) )
|
||||
end
|
||||
|
||||
HTTP( {
|
||||
method = "GET",
|
||||
url = url,
|
||||
success = success,
|
||||
failed = error,
|
||||
headers = self._jsonHeaders,
|
||||
timeout = self:_getTimeout()
|
||||
} )
|
||||
end
|
||||
|
||||
|
||||
-- Given prepared data, sends it to the API --
|
||||
function express:Put( data, cb )
|
||||
local success = function( code, body )
|
||||
express._checkResponseCode( code )
|
||||
|
||||
local response = util.JSONToTable( body )
|
||||
assert( response, "Invalid JSON" )
|
||||
assert( response.id, "No ID returned" )
|
||||
|
||||
cb( response.id )
|
||||
end
|
||||
|
||||
HTTP( {
|
||||
method = "POST",
|
||||
url = self:makeAccessURL( "write" ),
|
||||
body = data,
|
||||
success = success,
|
||||
failed = error,
|
||||
headers = {
|
||||
["Content-Length"] = #data,
|
||||
["Accept"] = "application/json"
|
||||
},
|
||||
type = "application/octet-stream",
|
||||
timeout = CLIENT and 240 or 60
|
||||
} )
|
||||
end
|
||||
|
||||
|
||||
-- Runs the express receiver for the given message --
|
||||
function express:Call( message, ply, data )
|
||||
local cb = self:_getReceiver( message )
|
||||
if not cb then return end
|
||||
|
||||
if CLIENT then return cb( data ) end
|
||||
if SERVER then return cb( ply, data ) end
|
||||
end
|
||||
|
||||
|
||||
-- Runs the express pre-download receiver for the given message --
|
||||
function express:CallPreDownload( message, ply, id, size, needsProof )
|
||||
local cb = self:_getPreDlReceiver( message )
|
||||
if not cb then return end
|
||||
|
||||
if CLIENT then return cb( message, id, size, needsProof ) end
|
||||
if SERVER then return cb( message, ply, id, size, needsProof ) end
|
||||
end
|
||||
|
||||
|
||||
-- Handles a net message containing an ID to download from the API --
|
||||
function express.OnMessage( _, ply )
|
||||
local message = net.ReadString()
|
||||
if not express:_getReceiver( message ) then
|
||||
error( "Express: Received a message that has no listener! (" .. message .. ")" )
|
||||
end
|
||||
|
||||
local id = net.ReadString()
|
||||
local needsProof = net.ReadBool()
|
||||
|
||||
local function makeRequest( size )
|
||||
if size then
|
||||
local check = express:CallPreDownload( message, ply, id, size, needsProof )
|
||||
if check == false then return end
|
||||
end
|
||||
|
||||
express:_get( id, function( data, hash )
|
||||
express:Call( message, ply, data )
|
||||
|
||||
if not needsProof then return end
|
||||
net.Start( "express_proof" )
|
||||
net.WriteString( hash )
|
||||
express.shSend( ply )
|
||||
end )
|
||||
end
|
||||
|
||||
if express:_getPreDlReceiver( message ) then
|
||||
return express:_getSize( id, makeRequest )
|
||||
end
|
||||
|
||||
makeRequest()
|
||||
end
|
||||
|
||||
|
||||
-- Handles a net message containing a proof of data download --
|
||||
function express.OnProof( _, ply )
|
||||
-- Server prefixes the hash with the player's Steam ID
|
||||
local prefix = ply and ply:SteamID64() .. "-" or ""
|
||||
local hash = prefix .. net.ReadString()
|
||||
|
||||
local cb = express._awaitingProof[hash]
|
||||
if not cb then return end
|
||||
|
||||
cb( ply )
|
||||
express._awaitingProof[hash] = nil
|
||||
end
|
||||
|
||||
|
||||
net.Receive( "express", express.OnMessage )
|
||||
net.Receive( "express_proof", express.OnProof )
|
||||
|
||||
include( "sh_helpers.lua" )
|
||||
|
||||
if SERVER then
|
||||
include( "sv_init.lua" )
|
||||
AddCSLuaFile( "cl_init.lua" )
|
||||
else
|
||||
include( "cl_init.lua" )
|
||||
end
|
||||
|
||||
hook.Add( "CreateTeams", "ExpressLoaded", function()
|
||||
hook.Run( "ExpressLoaded" )
|
||||
end )
|
||||
Reference in New Issue
Block a user