226 lines
5.5 KiB
Lua
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
|