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

226 lines
5.5 KiB
Lua

-- Copyright (C) 2017-2020 DBotThePony
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-- of the Software, and to permit persons to whom the Software is furnished to do so,
-- subject to the following conditions:
-- The above copyright notice and this permission notice shall be included in all copies
-- or substantial portions of the Software.
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-- DEALINGS IN THE SOFTWARE.
local DLib = DLib
local util = util
local pairs = pairs
local ipairs = ipairs
local RealTimeL = RealTimeL
local GetConVar = GetConVar
local net = net
local table = table
local IsValid = IsValid
local LocalPlayer = LocalPlayer
if SERVER then
net.pool('DLib.getinfo.replicate')
end
local plyMeta = FindMetaTable('Player')
local entMeta = FindMetaTable('Entity')
DLib.getinfo = DLib.getinfo or {}
local getinfo = DLib.getinfo
getinfo.bank = getinfo.bank or {}
getinfo.bankCRC = getinfo.bankCRC or {}
getinfo.bankOptimized = {}
--[[
@doc
@fname DLib.getinfo.Replicate
@args string cvarname, string valueType = 'string', any default
@desc
Marks a console variable for replication after it's creation (e.g. when you can specify FCVAR_USERINFO flag on a cvar)
valueType can be either:
`'boolean'`
`'number'` or `'integer'`
`'uinteger'`
`'float'`
`'string'` (by default, if type is invalid or missing)
@enddesc
]]
function getinfo.Replicate(cvarname, valuetype, default)
valuetype = valuetype or 'boolean'
local crc = util.CRC(cvarname)
local writeFunc, readFunc, nwGet, nwSet
if valuetype == 'boolean' then
readFunc = net.ReadBool
writeFunc = net.WriteBool
nwSet = entMeta.SetNWBool
nwGet = entMeta.GetNWBool
elseif valuetype == 'integer' or valuetype == 'number' then
readFunc = net.ReadInt32
writeFunc = net.WriteInt32
nwSet = entMeta.SetNWInt
nwGet = entMeta.GetNWInt
elseif valuetype == 'uinteger' then
readFunc = net.ReadUInt32
writeFunc = net.WriteUInt32
nwSet = entMeta.SetNWUInt
nwGet = entMeta.GetNWUInt
elseif valuetype == 'float' then
readFunc = net.ReadFloat
writeFunc = net.WriteFloat
nwSet = entMeta.SetNWFloat
nwGet = entMeta.GetNWFloat
else
readFunc = net.ReadString
writeFunc = net.WriteString
default = tostring(default)
valuetype = 'string'
nwSet = entMeta.SetNWString
nwGet = entMeta.GetNWString
end
if not nwSet then
error('Missing NW Set for ' .. cvarname .. '! This should never happen')
end
getinfo.bank[cvarname] = {
crc = crc,
uid = tonumber(crc),
created = RealTimeL(),
cvar = GetConVar(cvarname),
default = default,
valuetype = valuetype,
id = cvarname,
cvarname = cvarname,
writeFunc = writeFunc,
readFunc = readFunc,
nwGet = nwGet,
nwSet = nwSet,
}
if CLIENT then
cvars.AddChangeCallback(cvarname, getinfo.ReplicateNow, 'DLib.getinfo')
end
getinfo.bankCRC[crc] = getinfo.bank[cvarname]
getinfo.bankCRC[getinfo.bank[cvarname].uid] = getinfo.bank[cvarname]
getinfo.Rebuild()
end
getinfo.Register = getinfo.Replicate
--[[
@doc
@fname DLib.getinfo.Rebuild
@internal
@returns
table: optimized list for ipairs iteration
]]
function getinfo.Rebuild()
getinfo.bankOptimized = {}
for cvar, data in pairs(getinfo.bank) do
table.insert(getinfo.bankOptimized, data)
end
return getinfo.bankOptimized
end
getinfo.Rebuild()
if CLIENT then
timer.Create('DLib.getinfo.replication', 10, 0, function()
getinfo.ReplicateNow()
end)
function getinfo.ReplicateNow()
local ply = LocalPlayer()
if not IsValid(ply) then return end
net.Start('DLib.getinfo.replicate')
for i, data in ipairs(getinfo.bankOptimized) do
data.cvar = data.cvar or GetConVar(data.id)
local val = data.cvar:GetByType(data.valuetype)
--if val ~= data.oldval then
net.WriteUInt(data.uid, 32)
data.writeFunc(val)
data.nwSet(ply, data.id, val)
data.oldval = val
--end
end
net.WriteUInt(0, 32)
net.SendToServer()
end
else
net.receive('DLib.getinfo.replicate', function(len, ply)
if not IsValid(ply) then return end
local nextID = net.ReadUInt(32)
while nextID ~= 0 and getinfo.bankCRC[nextID] do
local bank = getinfo.bankCRC[nextID]
local val = bank.readFunc()
bank.nwSet(ply, bank.id, val)
nextID = net.ReadUInt(32)
end
end)
end
local cache = {}
local GetConVar_Internal = GetConVar_Internal
--[[
@doc
@fname Player:GetInfoDLib
@args string cvarname
@returns
string: or nil
]]
function plyMeta:GetInfoDLib(cvarname)
if getinfo.bank[cvarname] then
return getinfo.bank[cvarname].nwGet(self, cvarname)
elseif SERVER then
return self:GetInfo(cvarname)
else
if cache[cvarname] == nil then
cache[cvarname] = GetConVar_Internal(cvarname)
if not cache[cvarname] then
cache[cvarname] = false
end
end
if not cache[cvarname] then
cache[cvarname] = false
return -- no value, :GetInfo() can return "no value" in vanilla
-- even if gmod wiki stands it (always) return string
end
return cache[cvarname]:GetString()
end
end
return getinfo