@@ -8,6 +8,7 @@ table.Empty(LIB)
88local LIBUtil = StreamRadioLib .Util
99local LIBUrl = StreamRadioLib .Url
1010local LIBNet = StreamRadioLib .Net
11+ local LIBHook = StreamRadioLib .Hook
1112
1213local g_whitelistCache = LIBUtil .CreateCacheArray (2048 )
1314local g_whitelistCallbacks = {}
1920
2021local g_emptyFunction = function () end
2122
22- local function callCallbacks (result , url )
23- local callbacks = g_whitelistCallbacks [url ]
23+ local function callCallbacks (url , ... )
24+ local callbacksList = g_whitelistCallbacks [url ]
2425 g_whitelistCallbacks [url ] = nil
2526
26- if not callbacks then
27+ if not callbacksList then
2728 return
2829 end
2930
30- for _ , callback in ipairs (callbacks ) do
31- callback (result )
31+ for _ , callbacks in pairs (callbacksList ) do
32+ for _ , callback in ipairs (callbacks ) do
33+ callback (... )
34+ end
3235 end
3336end
3437
3538LIBNet .Receive (" whitelist_check_url_result" , function ()
3639 local url = net .ReadString ()
3740 local result = net .ReadBool ()
41+ local blockedByHook = net .ReadBool ()
3842
3943 url = LIBUrl .SanitizeUrl (url )
4044 if url == " " then
4145 return
4246 end
4347
44- g_whitelistCache :Set (url , result )
48+ local now = CurTime ()
49+ local lifetime = blockedByHook and 600 or 3600
50+ local expires = now + lifetime
51+
52+ g_whitelistCache :Set (url , {
53+ result = result ,
54+ blockedByHook = blockedByHook ,
55+ }, expires )
4556
46- callCallbacks (result , url )
57+ callCallbacks (url , result , blockedByHook )
4758end )
4859
4960LIBNet .Receive (" whitelist_clear_cache" , function ()
@@ -72,59 +83,122 @@ function LIB.AddCheckFunction(name, func)
7283 g_whitelistFunction [name ] = func
7384end
7485
75- function LIB .IsAllowedSync (url )
86+ function LIB .BuildContext (ent , ply )
87+ context = context or {}
88+
89+ if not IsValid (ent ) or not isentity (ent ) then
90+ ent = nil
91+ end
92+
93+ if ent and ent .__IsRadio and not IsValid (ply ) then
94+ ply = ent :GetRealRadioOwner ()
95+ end
96+
97+ if not IsValid (ply ) or not ply :IsPlayer () then
98+ ply = nil
99+ end
100+
101+ context .entity = ent
102+ context .player = ply
103+
104+ return context
105+ end
106+
107+ function LIB .SanitizeContext (context )
108+ context = context or {}
109+
110+ local ent = context .entity
111+ local ply = context .player
112+
113+ if not IsValid (ply ) or not ply :IsPlayer () then
114+ context .player = LocalPlayer ()
115+ end
116+
117+ if not IsValid (ent ) or not isentity (ent ) then
118+ context .entity = nil
119+ end
120+
121+ return context
122+ end
123+
124+ function LIB .IsAllowedSync (url , context )
76125 url = tostring (url or " " )
77126
78127 if url == " " then
79- return false
128+ return false , false
80129 end
81130
82131 if LIBUrl .IsOfflineURL (url ) then
83- return true
132+ return true , false
84133 end
85134
86135 url = LIBUrl .SanitizeOnlineUrl (url )
87136 if url == " " then
88- return false
137+ return false , false
138+ end
139+
140+ context = LIB .SanitizeContext (context )
141+
142+ local now = CurTime ()
143+
144+ local cacheItem = g_whitelistCache :Get (url , now )
145+ if cacheItem then
146+ -- Use cached result instead of asking the server again
147+
148+ local result = cacheItem .result or false
149+ local blockedByHook = cacheItem .blockedByHook or false
150+
151+ return result , blockedByHook
152+ end
153+
154+ local ply = context .player
155+ local ent = context .entity
156+
157+ local isAllowed = LIBHook .RunCustom (" UrlIsAllowed" , url , ply , ent )
158+
159+ if isAllowed == false then
160+ return false , true
89161 end
90162
91163 if not StreamRadioLib .IsUrlWhitelistEnabled () then
92164 -- allow all URLs if the whitelist is disabled
93- return true
165+ return nil , false
94166 end
95167
96168 if callCheckFunctions (url ) then
97- return true
169+ return true , false
98170 end
99171
100- if g_whitelistCache :Has (url ) then
101- local result = g_whitelistCache :Get (url )
102- return result
103- end
104-
105- return nil
172+ return nil , nil
106173end
107174
108- function LIB .IsAllowedAsync (url , callback )
175+ function LIB .IsAllowedAsync (url , context , callback )
109176 url = tostring (url or " " )
110177 callback = callback or g_emptyFunction
111178
112- local result = LIB .IsAllowedSync (url )
179+ context = LIB .SanitizeContext (context )
180+ local ent = context .entity or NULL
181+
182+ local result , blockedByHook = LIB .IsAllowedSync (url , context )
113183
114184 if result ~= nil then
115- callback (result )
185+ callback (result , blockedByHook or false )
116186 return
117187 end
118188
119- local callbacks = g_whitelistCallbacks [url ] or {}
120- g_whitelistCallbacks [url ] = callbacks
189+ local callbacksList = g_whitelistCallbacks [url ] or {}
190+ g_whitelistCallbacks [url ] = callbacksList
191+
192+ local callbacks = callbacksList [ent ] or {}
193+ callbacksList [ent ] = callbacks
121194
122195 local hasSend = # callbacks > 0
123196 table.insert (callbacks , callback )
124197
125198 if not hasSend then
126199 LIBNet .Start (" whitelist_check_url" )
127200 net .WriteString (url )
201+ net .WriteEntity (ent )
128202 net .SendToServer ()
129203 end
130204end
@@ -185,5 +259,9 @@ function LIB.QuickWhitelistRemove(url)
185259 g_whitelistCache :Remove (url )
186260end
187261
262+ function LIB .Load ()
263+ LIB .InvalidateCache ()
264+ end
265+
188266return true
189267
0 commit comments