Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UCL improvements #99

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 47 additions & 37 deletions lua/ulib/server/ucl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ function ucl.addGroup( name, allows, inherit_from, from_CAMI )
ucl.groups[ name ] = { allow=allows, inherit_from=inherit_from }
ucl.saveGroups()

ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", name, ucl.groups[ name ] )
hook.Call( ULib.HOOK_GROUP_CREATED, _, name, ucl.groups[ name ] )
hook.Call( ULib.HOOK_UCLCHANGED )

Expand Down Expand Up @@ -415,6 +416,7 @@ function ucl.groupAllow( name, access, revoke )

ucl.saveGroups()

ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", name, ucl.groups[ name ] )
hook.Call( ULib.HOOK_GROUP_ACCESS_CHANGE, _, name, access, revoke )
hook.Call( ULib.HOOK_UCLCHANGED )
end
Expand Down Expand Up @@ -475,6 +477,8 @@ function ucl.renameGroup( orig, new )
ucl.saveUsers()
ucl.saveGroups()

ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", new, ucl.groups[ new ] )
ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", orig, _ )
hook.Call( ULib.HOOK_GROUP_RENAMED, _, orig, new )
hook.Call( ULib.HOOK_UCLCHANGED )

Expand Down Expand Up @@ -539,6 +543,7 @@ function ucl.setGroupInheritance( group, inherit_from, from_CAMI )

ucl.saveGroups()

ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", group, ucl.groups[ group ] )
hook.Call( ULib.HOOK_GROUP_INHERIT_CHANGE, _, group, inherit_from, old_inherit )
hook.Call( ULib.HOOK_UCLCHANGED )

Expand Down Expand Up @@ -577,6 +582,7 @@ function ucl.setGroupCanTarget( group, can_target )

ucl.saveGroups()

ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", group, ucl.groups[ group ] )
hook.Call( ULib.HOOK_UCLCHANGED )
end

Expand Down Expand Up @@ -624,15 +630,17 @@ function ucl.removeGroup( name, from_CAMI )
end
local oldgroup = table.Copy( ucl.groups[ name ] )
ucl.groups[ name ] = nil
for _, groupInfo in pairs( ucl.groups ) do
for groupName, groupInfo in pairs( ucl.groups ) do
if groupInfo.inherit_from == name then
groupInfo.inherit_from = inherits_from
ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", groupName, groupInfo )
end
end

ucl.saveUsers()
ucl.saveGroups()

ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", name, _ )
hook.Call( ULib.HOOK_GROUP_REMOVED, _, name, oldgroup )
hook.Call( ULib.HOOK_UCLCHANGED )

Expand All @@ -645,7 +653,7 @@ end
--[[
Function: ucl.getUserRegisteredID

Returns the SteamID, IP, or UniqueID of a player if they're registered under any of those IDs under ucl.users. Checks in order. Returns nil if not registered.
Returns the SteamID, SteamID64, IP, or UniqueID of a player if they're registered under any of those IDs under ucl.users. Checks in order. Returns nil if not registered.

Parameters:

Expand All @@ -658,9 +666,10 @@ end

function ucl.getUserRegisteredID( ply )
local id = ply:SteamID()
local id64 = ply:SteamID64()
local uid = ply:UniqueID()
local ip = ULib.splitPort( ply:IPAddress() )
local checkIndexes = { id, ip, uid }
local checkIndexes = { id, id64, ip, uid }
for _, index in ipairs( checkIndexes ) do
if ULib.ucl.users[ index ] then
return id
Expand All @@ -675,7 +684,7 @@ end

Parameters:

id - The SteamID, IP, or UniqueID of the user you wish to check.
id - The SteamID, SteamID64, IP, or UniqueID of the user you wish to check.
]]

function ucl.getUserInfoFromID( id )
Expand All @@ -698,7 +707,7 @@ end

Parameters:

id - The SteamID, IP, or UniqueID of the user you wish to add.
id - The SteamID, SteamID64, IP, or UniqueID of the user you wish to add.
allows - *(Optional, defaults to empty table)* The list of access you wish to give this user.
denies - *(Optional, defaults to empty table)* The list of access you wish to explicitly deny this user.
group - *(Optional)* The string of the group this user should belong to. Must be a valid group.
Expand Down Expand Up @@ -759,7 +768,7 @@ end

Parameters:

id - The SteamID, IP, or UniqueID of the user to change. Must be a valid, existing ID, or an ID of a connected player.
id - The SteamID, SteamID64, IP, or UniqueID of the user to change. Must be a valid, existing ID, or an ID of a connected player.
access - The string of the access or a table of accesses to add or remove. Access tags can be specified in values in the table for allows.
revoke - *(Optional, defaults to false)* A boolean of whether the access tag should be added or removed
from the allow or deny list. If true, it's removed.
Expand All @@ -785,15 +794,15 @@ function ucl.userAllow( id, access, revoke, deny )
id = id:upper() -- In case of steamid, needs to be upper case
if type( access ) == "string" then access = { access } end

local uid = id
if not ucl.authed[ uid ] then -- Check to see if it's a steamid or IP
local id64 = id
if not ucl.authed[ id64 ] then -- Check to see if it's a steamid or IP
local ply = ULib.getPlyByID( id )
if ply and ply:IsValid() then
uid = ply:UniqueID()
id64 = ply:SteamID64()
end
end

local userInfo = ucl.users[ id ] or ucl.authed[ uid ] -- Check both tables
local userInfo = ucl.users[ id ] or ucl.authed[ id64 ] -- Check both tables
if not userInfo then return error( "User id does not exist for changing access (" .. id .. ")", 2 ) end

-- If they're connected but don't exist in the ULib user database, add them.
Expand Down Expand Up @@ -881,7 +890,7 @@ end

Parameters:

id - The SteamID, IP, or UniqueID of the user you wish to remove. Must be a valid, existing ID.
id - The SteamID, SteamID64, IP, or UniqueID of the user you wish to remove. Must be a valid, existing ID.
The unique id of a connected user is always valid.
from_CAMI - *(Optional)* An indicator for this information coming from CAMI.

Expand All @@ -904,7 +913,7 @@ function ucl.removeUser( id, from_CAMI )
if not ply then return error( "SANITY CHECK FAILED!" ) end -- Should never be invalid

local ip = ULib.splitPort( ply:IPAddress() )
local checkIndexes = { ply:UniqueID(), ip, ply:SteamID() }
local checkIndexes = { ply:SteamID64(), ply:UniqueID(), ip, ply:SteamID() }

for _, index in ipairs( checkIndexes ) do
if ucl.users[ index ] then
Expand Down Expand Up @@ -983,11 +992,12 @@ function ucl.registerAccess( access, groups, comment, category )
if table.HasValue( groupInfo.allow, access ) then return end -- Found, don't add again
end

for _, group in ipairs( groups ) do
for name, group in ipairs( groups ) do
-- Create group if it doesn't exist
if not ucl.groups[ group ] then ucl.addGroup( group ) end

table.insert( ucl.groups[ group ].allow, access )
ULib.clientRPC( _, "ULib.ucl.updateClientUCLGroup", name, ucl.groups[ name ] )
end

timer.Create( "ULibSaveGroups", 1, 1, function() -- 1 sec delay, 1 rep
Expand Down Expand Up @@ -1015,22 +1025,22 @@ end
]]
function ucl.probe( ply )
local ip = ULib.splitPort( ply:IPAddress() )
local uid = ply:UniqueID()
local checkIndexes = { uid, ip, ply:SteamID() }
local id64 = ply:SteamID64()
local checkIndexes = { id64, ply:UniqueID(), ip, ply:SteamID() }

local match = false
for _, index in ipairs( checkIndexes ) do
if ucl.users[ index ] then
ucl.authed[ uid ] = ucl.users[ index ] -- Setup an ALIAS
ucl.authed[ id64 ] = ucl.users[ index ] -- Setup an ALIAS

-- If they have a group, set it
local group = ucl.authed[ uid ].group
local group = ucl.authed[ id64 ].group
if group and group ~= "" then
ply:SetUserGroup( group, true )
end

-- Update their name
ucl.authed[ uid ].name = ply:Nick()
ucl.authed[ id64 ].name = ply:Nick()
ucl.saveUsers()

match = true
Expand All @@ -1039,13 +1049,14 @@ function ucl.probe( ply )
end

if not match then
ucl.authed[ ply:UniqueID() ] = ULib.DEFAULT_GRANT_ACCESS
ucl.authed[ id64 ] = ULib.DEFAULT_GRANT_ACCESS
if ply.tmp_group then
ply:SetUserGroup( ply.tmp_group, true ) -- Make sure they keep the group
ply.tmp_group = nil
end
end

ULib.clientRPC( _, "ULib.ucl.updateClientUCLPlayer", id64, ucl.authed[ id64 ] )
hook.Call( ULib.HOOK_UCLCHANGED )
hook.Call( ULib.HOOK_UCLAUTH, _, ply )
end
Expand All @@ -1054,7 +1065,7 @@ end
local function setupBot( ply )
if not ply or not ply:IsValid() then return end

if not ucl.authed[ ply:UniqueID() ] then
if not ucl.authed[ ply:SteamID64() ] then
ply:SetUserGroup( ULib.ACCESS_ALL, true ) -- Give it a group!
ucl.probe( ply )
end
Expand All @@ -1075,28 +1086,24 @@ end
hook.Add( ULib.HOOK_UCLAUTH, "ULibSendAuthToClients", sendAuthToClients, HOOK_MONITOR_LOW )

local function sendUCLDataToClient( ply )
ULib.clientRPC( ply, "ULib.ucl.initClientUCL", ucl.authed, ucl.groups ) -- Send all UCL data (minus offline users) to all loaded users
ULib.clientRPC( ply, "hook.Call", ULib.HOOK_UCLCHANGED ) -- Call hook on client
ULib.clientRPC( ply, "authPlayerIfReady", ply, ply:UserID() ) -- Call on client
timer.Simple(0, function()
ULib.clientRPC( ply, "ULib.ucl.initClientUCL", ucl.authed, ucl.groups ) -- Send all UCL data (minus offline users) to the current user
ULib.clientRPC( ply, "authPlayerIfReady", ply, ply:UserID() ) -- Call on client
end)
end
hook.Add( ULib.HOOK_LOCALPLAYERREADY, "ULibSendUCLDataToClient", sendUCLDataToClient, HOOK_MONITOR_HIGH )
hook.Add( "PlayerInitialSpawn", "ULibSendUCLDataToClient", sendUCLDataToClient, HOOK_MONITOR_HIGH )

local function playerDisconnected( ply )
-- We want to perform these actions after everything else has processed through, but we need high priority hook to ensure we don't get sniped.
local uid = ply:UniqueID()
local id64 = ply:SteamID64()
ULib.queueFunctionCall( function()
ucl.authed[ uid ] = nil
ucl.authed[ id64 ] = nil
ULib.clientRPC( _, "ULib.ucl.updateClientUCLPlayer", id64, _ )
hook.Call( ULib.HOOK_UCLCHANGED )
end )
end
hook.Add( "PlayerDisconnected", "ULibUCLDisconnect", playerDisconnected, HOOK_MONITOR_HIGH )

local function UCLChanged()
ULib.clientRPC( _, "ULib.ucl.initClientUCL", ucl.authed, ucl.groups ) -- Send all UCL data (minus offline users) to all loaded users
ULib.clientRPC( _, "hook.Call", ULib.HOOK_UCLCHANGED ) -- Call hook on client
end
hook.Add( ULib.HOOK_UCLCHANGED, "ULibSendUCLToClients", UCLChanged )

--[[
-- The following is useful for debugging since Garry changes client bootstrapping so frequently
hook.Add( ULib.HOOK_UCLCHANGED, "UTEST", function() print( "HERE HERE: UCL Changed" ) end )
Expand All @@ -1111,7 +1118,7 @@ local playerAuth = hook.GetTable().PlayerInitialSpawn.PlayerAuthSpawn
hook.Remove( "PlayerInitialSpawn", "PlayerAuthSpawn" ) -- Remove from original spot

local function newPlayerAuth( ply, ... )
ucl.authed[ ply:UniqueID() ] = nil -- If the player ent is removed before disconnecting, we can have this hanging out there.
ucl.authed[ ply:SteamID64() ] = nil -- If the player ent is removed before disconnecting, we can have this hanging out there.
playerAuth( ply, ... ) -- Put here, slightly ahead of ucl.
ucl.probe( ply, ... )
end
Expand All @@ -1127,16 +1134,19 @@ function meta:SetUserGroup( group, dontCall )
local oldGroup = self:GetUserGroup()
oldSetUserGroup( self, group )

if ucl.authed[ self:UniqueID() ] then
if ucl.authed[ self:UniqueID() ] == ULib.DEFAULT_GRANT_ACCESS then
ucl.authed[ self:UniqueID() ] = table.Copy( ULib.DEFAULT_GRANT_ACCESS )
local id64 = self:SteamID64()

if ucl.authed[ id64 ] then
if ucl.authed[ id64 ] == ULib.DEFAULT_GRANT_ACCESS then
ucl.authed[ id64 ] = table.Copy( ULib.DEFAULT_GRANT_ACCESS )
end
ucl.authed[ self:UniqueID() ].group = group
ucl.authed[ id64 ].group = group
else
self.tmp_group = group
end

if not dontCall and self:GetUserGroup() ~= oldGroup then -- Changed! Inform the masses of the change
ULib.clientRPC( _, "ULib.ucl.updateClientUCLPlayer", id64, ucl.authed[ id64 ] )
hook.Call( ULib.HOOK_UCLCHANGED )
hook.Call( ULib.HOOK_UCLAUTH, _, self )
end
Expand Down
4 changes: 2 additions & 2 deletions lua/ulib/shared/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ end


local Player = FindMetaTable( "Player" )
local checkIndexes = { Player.UniqueID, function( ply ) if CLIENT then return "" end local ip = ULib.splitPort( ply:IPAddress() ) return ip end, Player.SteamID, Player.UserID }
local checkIndexes = { Player.SteamID64, Player.UniqueID, function( ply ) if CLIENT then return "" end local ip = ULib.splitPort( ply:IPAddress() ) return ip end, Player.SteamID, Player.UserID }
--[[
Function: getPlyByID

Finds a user identified by the given ID.

Parameters:

id - The ID to try to match against connected players. Can be a unique id, ip address, steam id, or user id.
id - The ID to try to match against connected players. Can be a SteamID64, UniqueID, IP address, SteamID, or UserID.

Returns:

Expand Down
36 changes: 22 additions & 14 deletions lua/ulib/shared/sh_ucl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ local ucl = ULib.ucl -- Make it easier for us to refer to
-- Setup!
ucl.groups = ucl.groups or {} -- Stores allows, inheritance, and custom addon info keyed by group name
ucl.users = ucl.users or {} -- Stores allows, denies, group, and last seen name keyed by user id (steamid, ip, whatever)
ucl.authed = ucl.authed or {} -- alias to ucl.users subtable for player if they have an entry, otherwise a "guest" entry. Keyed by uniqueid.
ucl.authed = ucl.authed or {} -- alias to ucl.users subtable for player if they have an entry, otherwise a "guest" entry. Keyed by SteamID64.
-- End setup

--[[
Expand Down Expand Up @@ -45,13 +45,10 @@ function ucl.query( ply, access, hide )

access = access:lower()

local unique_id = ply:UniqueID()
if CLIENT and game.SinglePlayer() then
unique_id = "1" -- Fix garry's bug
end
local id64 = ply:SteamID64()

if not ucl.authed[ unique_id ] then return error( "[ULIB] Unauthed player" ) end -- Sanity check
local playerInfo = ucl.authed[ unique_id ]
if not ucl.authed[ id64 ] then return error( "[ULIB] Unauthed player" ) end -- Sanity check
local playerInfo = ucl.authed[ id64 ]

-- First check the player's info
if table.HasValue( playerInfo.deny, access ) then return false end -- Deny overrides all else
Expand Down Expand Up @@ -177,12 +174,25 @@ if CLIENT then
function ucl.initClientUCL( authed, groups )
ucl.authed = authed
ucl.groups = groups

for name, data in pairs( groups ) do
if not ULib.findInTable( {"superadmin", "admin", "user"}, name ) then
inherit_from = data.inherit_from or "user"
CAMI.RegisterUsergroup( {Name=name, Inherits=inherit_from}, CAMI.ULX_TOKEN )
CAMI.RegisterUsergroup( {Name = name, Inherits = inherit_from}, CAMI.ULX_TOKEN )
end
end

hook.Call( ULib.HOOK_UCLCHANGED )
end

function ucl.updateClientUCLPlayer( id, data )
ucl.authed[ id ] = data
hook.Call( ULib.HOOK_UCLCHANGED )
end

function ucl.updateClientUCLGroup( name, data )
ucl.groups[ name ] = data
hook.Call( ULib.HOOK_UCLCHANGED )
end
end

Expand Down Expand Up @@ -269,12 +279,10 @@ end
function meta:GetUserGroup()
if not self:IsValid() then return "" end -- Not a valid player

local uid = self:UniqueID()
if CLIENT and game.SinglePlayer() then
uid = "1" -- Fix garry's bug
end
if not ucl.authed[ uid ] then return "" end
return ucl.authed[ uid ].group or "user"
local id64 = self:SteamID64()

if not ucl.authed[ id64 ] then return "" end
return ucl.authed[ id64 ].group or "user"
end


Expand Down