283 lines
5.5 KiB
Lua
283 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 net = net
|
|
local player = player
|
|
local util = util
|
|
local bit = bit
|
|
|
|
if SERVER then
|
|
net.pool('dlib_sync_savetable_values')
|
|
end
|
|
|
|
DLib.__TrackedSaveTableValues = DLib.__TrackedSaveTableValues or {}
|
|
DLib.__TrackedSaveTableTypes = DLib.__TrackedSaveTableTypes or {}
|
|
local track = DLib.__TrackedSaveTableValues
|
|
local trackr = {}
|
|
local tracktypes = DLib.__TrackedSaveTableTypes
|
|
|
|
for i, ply in ipairs(player.GetAll()) do
|
|
ply.__dlib_st_cache = nil
|
|
end
|
|
|
|
local typesFuncs = {
|
|
string = {
|
|
net.WriteString,
|
|
net.ReadString
|
|
},
|
|
|
|
int = {
|
|
net.WriteInt32,
|
|
net.ReadInt32
|
|
},
|
|
|
|
float = {
|
|
net.WriteFloat,
|
|
net.ReadFloat
|
|
},
|
|
|
|
smallint = {
|
|
net.WriteInt16,
|
|
net.ReadInt16
|
|
},
|
|
|
|
byte = {
|
|
net.WriteInt8,
|
|
net.ReadInt8
|
|
},
|
|
|
|
uint = {
|
|
net.WriteUInt32,
|
|
net.ReadUInt32
|
|
},
|
|
|
|
smalluint = {
|
|
net.WriteUInt16,
|
|
net.ReadUInt16
|
|
},
|
|
|
|
ubyte = {
|
|
net.WriteUInt8,
|
|
net.ReadUInt8
|
|
},
|
|
|
|
angle = {
|
|
net.WriteAngle,
|
|
net.ReadAngle
|
|
},
|
|
|
|
vector = {
|
|
net.WriteVector,
|
|
net.ReadVector
|
|
},
|
|
|
|
angle_double = {
|
|
net.WriteAngleDouble,
|
|
net.ReadAngleDouble
|
|
},
|
|
|
|
vector_double = {
|
|
net.WriteVectorDouble,
|
|
net.ReadVectorDouble
|
|
},
|
|
|
|
bool = {
|
|
net.WriteBool,
|
|
net.ReadBool
|
|
},
|
|
|
|
entity = {
|
|
net.WriteEntity,
|
|
net.ReadEntity
|
|
},
|
|
|
|
any = {
|
|
net.WriteType,
|
|
net.ReadType
|
|
},
|
|
}
|
|
|
|
--[[
|
|
@doc
|
|
@fname DLib.TrackSaveTableVar
|
|
@args string varname, string vartype
|
|
@deprecated
|
|
|
|
@desc
|
|
Asks DLib for networking this savetable variable to clients.
|
|
This function very bandwidth efficently does so, however, it increase serverside lag because
|
|
it use !g:GetInternalVariable which is **damn slow**
|
|
`vartype` can be anything from next:
|
|
`string`
|
|
`int`
|
|
`uint`
|
|
`smallint`
|
|
`usmallint`
|
|
`byte`
|
|
`ubyte`
|
|
`float`
|
|
`angle`
|
|
`vector`
|
|
`angle_double`
|
|
`vector_double`
|
|
`bool`
|
|
`entity`
|
|
`any`
|
|
This is basically a workaround for https://github.com/Facepunch/garrysmod-issues/issues/2552
|
|
@enddesc
|
|
|
|
@returns
|
|
boolean: whenever variable was registered before. if so, it just updates it's type
|
|
]]
|
|
function DLib.TrackSaveTableVar(varname, vartype)
|
|
if vartype == 'Entity' then vartype = 'entity' end
|
|
|
|
if not typesFuncs[vartype] then
|
|
error('Unknown variable type provided')
|
|
end
|
|
|
|
tracktypes[varname] = vartype
|
|
|
|
if table.qhasValue(track, varname) then
|
|
return false
|
|
end
|
|
|
|
table.insert(track, varname)
|
|
table.sort(track)
|
|
|
|
for i, var in ipairs(track) do
|
|
if var == varname then
|
|
trackr[varname] = i
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
for i, varname in ipairs(track) do
|
|
trackr[varname] = i
|
|
end
|
|
|
|
local plyMeta = FindMetaTable('Player')
|
|
|
|
--[[
|
|
@doc
|
|
@fname Player:LookupServerInternalVariable
|
|
@args string varname, any default
|
|
@deprecated
|
|
|
|
@returns
|
|
any: stored variable
|
|
]]
|
|
function plyMeta:LookupServerInternalVariable(varname, def)
|
|
if SERVER then
|
|
local val = self:GetInternalVariable(varname)
|
|
if val == nil then return def end
|
|
return val
|
|
end
|
|
|
|
if not self.__dlib_st_cache then return def end
|
|
local val = self.__dlib_st_cache[varname]
|
|
if val == nil then return def end
|
|
return val
|
|
end
|
|
|
|
if SERVER then
|
|
local function PlayerPostThink(ply)
|
|
local data = ply.__dlib_st_cache
|
|
|
|
if not data then
|
|
data = {}
|
|
ply.__dlib_st_cache = data
|
|
end
|
|
|
|
local send
|
|
|
|
for i, var in ipairs(track) do
|
|
local getvar = ply:GetInternalVariable(var)
|
|
|
|
if getvar ~= data[var] and getvar ~= nil then
|
|
send = send or {}
|
|
send[var] = getvar
|
|
data[var] = getvar
|
|
end
|
|
end
|
|
|
|
if not send then return end
|
|
|
|
net.Start('dlib_sync_savetable_values')
|
|
local flags = {}
|
|
local mflags = (#track - #track % 32) / 32
|
|
|
|
for slot = 0, mflags do
|
|
flags[slot] = 0
|
|
end
|
|
|
|
for var in pairs(send) do
|
|
local i = trackr[var] - 1
|
|
local slot = (i - i % 32) / 32
|
|
flags[slot] = flags[slot]:bor(bit.lshift(1, i % 32))
|
|
end
|
|
|
|
for slot = 0, mflags do
|
|
net.WriteInt32(flags[slot])
|
|
end
|
|
|
|
for i, var in ipairs(track) do
|
|
local val = send[var]
|
|
|
|
if val ~= nil then
|
|
typesFuncs[tracktypes[var]][1](val)
|
|
end
|
|
end
|
|
|
|
net.Send(ply)
|
|
end
|
|
|
|
hook.Add('PlayerPostThink', 'DLib.SaveTableTrack', PlayerPostThink)
|
|
return
|
|
end
|
|
|
|
local LocalPlayer = LocalPlayer
|
|
|
|
net.receive('dlib_sync_savetable_values', function()
|
|
local ply = LocalPlayer()
|
|
local data = ply.__dlib_st_cache
|
|
|
|
if not data then
|
|
data = {}
|
|
ply.__dlib_st_cache = data
|
|
end
|
|
|
|
local flags = {}
|
|
|
|
for slot = 0, (#track - #track % 32) / 32 do
|
|
flags[slot] = net.ReadInt32()
|
|
end
|
|
|
|
for i, var in ipairs(track) do
|
|
i = i - 1
|
|
|
|
if flags[(i - i % 32) / 32]:band(bit.lshift(1, i % 32)) ~= 0 then
|
|
data[var] = typesFuncs[tracktypes[var]][2]()
|
|
end
|
|
end
|
|
end)
|