dobrograd-13-06-2022/garrysmod/addons/util-luadev/lua/luadev/luadev.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

507 lines
11 KiB
Lua

module("luadev",package.seeall)
local function CMD(who)
return CLIENT and "CMD" or who or "CMD"
end
COMMAND('run_sv',function(ply,_,script,who)
RunOnServer(script,CMD(who),MakeExtras(ply))
end,true)
COMMAND('run_sh',function(ply,_,script,who)
RunOnShared(script,CMD(who),MakeExtras(ply))
end,true)
COMMAND('run_clients',function(ply,_,script,who)
RunOnClients(script,CMD(who),MakeExtras(ply))
end,true)
COMMAND('run_self',function(ply,_,script,who)
RunOnSelf(script,CMD(who),MakeExtras(ply))
end,true)
COMMAND('run_client',function(ply,tbl,script,who)
if !tbl[1] or !tbl[2] then Print("Syntax: lua_run_client (steamid/userid/accountid/part of name) script") return end
local cl=FindPlayer(tbl[1])
if !cl then Print("Client not found!\n") return end
if CLIENT then
Print("Running script on "..tostring(cl:Name()))
end
local _, e = script:find('^%s*"[^"]+')
if e then
script = script:sub(e+2)
else
local _, e = script:find('^%s*[^%s]+%s')
if not e then
Print("Invalid Command syntax.")
return
end
script = script:sub(e)
end
script = script:Trim()
RunOnClient(script,cl,CMD(who),MakeExtras(ply))
end)
COMMAND('send_cl',function(ply,tbl,cmd,who)
if !tbl[1] or !tbl[2] then Print("Syntax: lua_send_cl (steamid/userid/accountid/part of name) \"path\"") return end
local cl=FindPlayer(tbl[1])
if !cl then Print("Client not found!\n") return end
Print("Running script on "..tostring(cl:Name()))
table.remove(tbl,1)
local path=TableToString(tbl)
local Path,searchpath=RealFilePath(path)
if !Path then Print("Could not find the file\n") return end
local content = Path and GiveFileContent(Path,searchpath)
if !content then Print("Could not read the file\n") return end
RunOnClient(content,cl,who or CMD(who),MakeExtras(ply))
end)
COMMAND('send_sv',function(ply,c,cmd,who)
local Path,searchpath=RealFilePath(c[2] and TableToString(c) or c[1])
if !Path then Print("Could not find the file\n") return end
local content = Path and GiveFileContent(Path,searchpath)
if !content then Print("Could not read the file\n") return end
local who=string.GetFileFromFilename(Path)
RunOnServer(content,who or CMD(who),MakeExtras(ply))
end)
COMMAND('send_clients',function(ply,c,cmd,who)
local Path,searchpath=RealFilePath(c[2] and TableToString(c) or c[1])
if !Path then Print("Could not find the file\n") return end
local content = Path and GiveFileContent(Path,searchpath)
if !content then Print("Could not read the file\n") return end
local who=string.GetFileFromFilename(Path)
RunOnClients(content,who or CMD(who),MakeExtras(ply))
end)
COMMAND('send_sh',function(ply,c,cmd,who)
local Path,searchpath=RealFilePath(c[2] and TableToString(c) or c[1])
if !Path then Print("Could not find the file\n") return end
local content = Path and GiveFileContent(Path,searchpath)
if !content then Print("Could not read the file\n") return end
local who=string.GetFileFromFilename(Path)
RunOnShared(content,who or CMD(who),MakeExtras(ply))
end)
local function Guess(name,Path)
if name=="init" or name=="shared" or name=="cl_init" then
local newname = Path:gsub("\\","/"):match("^.+%/([^%/]-)/.-%.lua$")
Print("Guessing identifier: "..tostring(newname or "<Failed>"))
return newname or name
end
return name
end
local function SendEFFECT(cl,Path,ply,c,cmd,who)
local who=string.GetFileFromFilename(Path)
local effectname=string.GetFileFromFilename(Path):gsub("%.lua","")
effectname = Guess(effectname,Path)
if cl then
RunOnClients(cl,who or CMD(who),MakeExtras(ply,{effect=effectname}))
end
end
COMMAND('send_effect',function(ply,c,cmd,who)
local path = c[2] and TableToString(c) or c[1]
local Path,searchpath=RealFilePath(path)
if not Path then
Print("Could not find the file\n")
return
end
local content = GiveFileContent(Path,searchpath)
if content then
local sh = content
SendEFFECT(content,Path,ply,c,cmd,who)
return
end
local cl = GiveFileContent(Path..'/init.lua',searchpath)
if cl then
SendEFFECT(cl,Path,ply,c,cmd,who)
return
else
Print("Could not find required files from the folder\n")
end
end)
local function SendSWEP(cl,sh,sv,Path,ply,c,cmd,who)
local who=string.GetFileFromFilename(Path)
local swepname=string.GetFileFromFilename(Path):gsub("%.lua","")
swepname=Guess(swepname,Path)
if cl then
RunOnClients(cl,who or CMD(who),MakeExtras(ply,{swep=swepname}))
end
if sh then
RunOnShared(sh,who or CMD(who),MakeExtras(ply,{swep=swepname}))
end
if sv then
RunOnServer(sv,who or CMD(who),MakeExtras(ply,{swep=swepname}))
end
end
COMMAND('send_wep',function(ply,c,cmd,who)
local path = c[2] and TableToString(c) or c[1]
local Path,searchpath=RealFilePath(path)
if not Path then
Print("Could not find the file\n")
return
end
local content = GiveFileContent(Path,searchpath)
if content then
local sh = content
SendSWEP(nil,sh,nil,Path,ply,c,cmd,who)
return
end
local cl = GiveFileContent(Path..'/cl_init.lua',searchpath)
local sh = GiveFileContent(Path..'/shared.lua',searchpath)
local sv = GiveFileContent(Path..'/init.lua',searchpath)
if sv or sh or cl then
SendSWEP(cl,sh,sv,Path,ply,c,cmd,who)
return
else
Print("Could not find required files from the folder\n")
end
end)
local function SendENT(cl,sh,sv,Path,ply,c,cmd,who)
local who=string.GetFileFromFilename(Path)
local entname=string.GetFileFromFilename(Path):gsub("%.lua","")
entname = Guess(entname,Path)
if cl then
RunOnClients(cl,who or CMD(who),MakeExtras(ply,{sent=entname}))
end
if sh then
RunOnShared(sh,who or CMD(who),MakeExtras(ply,{sent=entname}))
end
if sv then
RunOnServer(sv,who or CMD(who),MakeExtras(ply,{sent=entname}))
end
end
COMMAND('send_ent',function(ply,c,cmd,who)
local path = c[2] and TableToString(c) or c[1]
local Path,searchpath=RealFilePath(path)
if not Path then
Print("Could not find the file\n")
return
end
local content = GiveFileContent(Path,searchpath)
if content then
local sh = content
SendENT(nil,sh,nil,Path,ply,c,cmd,who)
return
end
local cl = GiveFileContent(Path..'/cl_init.lua',searchpath)
local sh = GiveFileContent(Path..'/shared.lua',searchpath)
local sv = GiveFileContent(Path..'/init.lua',searchpath)
if sv or sh or cl then
SendENT(cl,sh,sv,Path,ply,c,cmd,who)
return
else
Print("Could not find required files from the folder\n")
end
end)
COMMAND('watch_kill',function(ply,c,cmd,wholeline)
local watchlist = GetWatchList()
if c[1]=="" or not c[1] then
Print"Killing all"
table.Empty(watchlist)
return
end
local t= table.remove(watchlist,tonumber(c[1]))
Print("killing",t and tostring(t.path) or "(not found)")
end,true)
COMMAND('watch',function(ply,c,cmd,wholeline)
local path_orig = c[1]
table.remove(c,1)
local fpath,searchpath=RealFilePath(path_orig,findpath)
if not fpath then Print("Could not find the file\n") return end
local content = fpath and GiveFileContent(fpath,searchpath)
local time = content and fpath and FileTime(fpath,searchpath)
if not content or not time then Print("File not readable\n") return end
local found
for k,v in next,c do
if v=="PATH" then
c[k] = path_orig
found = true
end
if v=="FILE" then
c[k] = path_orig
found = true
end
if v=="RPATH" then
c[k] = fpath
found = true
end
if v=="NOPATH" then
c[k] = false
found=true
end
end
for i=#c,1,-1 do
if c[i]==false then
table.remove(c,i)
end
end
if not c[1] then
Print"Missing command, assuming lua_send_self"
c[1] = 'lua_send_self'
end
if not found then
table.insert(c,path_orig)
end
local cmdd = {}
for k,v in next,c do
cmdd[k]=('%q'):format(tostring(v))
end
Print("Watching '"..tostring(fpath).."': ",table.concat(cmdd," "))
local entry = {
path = fpath,
searchpath = searchpath,
time = time,
cmd = c,
}
local watchlist = GetWatchList()
watchlist[#watchlist+1] = entry
end)
COMMAND('send_self',function(ply,c,cmd,who)
local Path,searchpath=RealFilePath(c[2] and TableToString(c) or c[1])
if !Path then Print("Could not find the file\n") return end
local content = GiveFileContent(Path,searchpath)
if !content then Print("Could not read the file\n") return end
local who=string.GetFileFromFilename(Path)
RunOnSelf(content,who or CMD(who),MakeExtras(ply))
end)
if SERVER then return end
net.Receive(Tag,function(...) _ReceivedData(...) end)
function _ReceivedData(len)
local script = ReadCompressed()
local decoded=net.ReadTable()
local info=decoded.info
local extra=decoded.extra
local ok,ret = Run(script,tostring(info),extra)
if not ok then
ErrorNoHalt(tostring(ret)..'\n')
end
--[[ -- Not done
if extra.retid then
net.Start(net_retdata)
net.WriteUInt(extra.retid,32)
net.WriteBool(ok)
net.WriteTable(ret)
net.SendToServer()
end --]]
end
function CheckStore(src)
if not ShouldStore() then return end
local crc = util.CRC(src)
local path = "luadev_hist/".. crc ..'.txt'
if file.Exists(path,'DATA') then return end
if not file.IsDir("luadev_hist",'DATA') then file.CreateDir("luadev_hist",'DATA') end
file.Write(path,tostring(src),'DATA')
end
function ToServer(data)
if TransmitHook(data)~=nil then return end
CheckStore(data.src)
net.Start(Tag)
WriteCompressed(data.src or "")
-- clear extra data
data.src = nil
if data.extra then
data.extra.ply = nil
if table.Count(data.extra)==0 then data.extra=nil end
end
net.WriteTable(data)
if net.BytesWritten()==65536 then
Print("Unable to send lua code (too big)\n")
return nil,"Unable to send lua code (too big)"
end
net.SendToServer()
return true
end
function RunOnClients(script,who,extra)
if not who and extra and isentity(extra) then extra = {ply=extra} end
local data={
src=script,
dst=TO_CLIENTS,
info=who,
extra=extra,
}
return ToServer(data)
end
function RunOnSelf(script,who,extra)
if not isstring(who) then who = nil end
if not who and extra and isentity(extra) then extra = {ply=extra} end
--if luadev_selftoself:GetBool() then
-- Run
--end
return RunOnClient(script,LocalPlayer(),who,extra)
end
function RunOnClient(script,targets,who,extra)
-- compat
if not targets and isentity(who) then
targets=who
who = nil
end
if extra and isentity(extra) and who==nil then extra={ply=extra} end
if (not istable(targets) and !IsValid(targets))
or (istable(targets) and table.Count(targets)==0)
then error"Invalid player(s)" end
local data={
src=script,
dst=TO_CLIENT,
dst_ply=targets,
info=who,
extra=extra,
}
return ToServer(data)
end
function RunOnServer(script,who,extra)
if not who and extra and isentity(extra) then extra = {ply=extra} end
local data={
src=script,
dst=TO_SERVER,
--dst_ply=pl
info=who,
extra=extra,
}
return ToServer(data)
end
function RunOnShared(script,who,extra)
if not who and extra and isentity(extra) then extra = {ply=extra} end
local data={
src=script,
dst=TO_SHARED,
--dst_ply=pl
info=who,
extra=extra,
}
return ToServer(data)
end