197 lines
		
	
	
		
			No EOL
		
	
	
		
			5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			No EOL
		
	
	
		
			5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| EntitiesStates = {}
 | |
| 
 | |
| --#region Register and Clear
 | |
| RegisterEntityState = function(uNetId)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         EntitiesStates[uNetId] = {
 | |
|             created = GetGameTimer(),
 | |
|             listeners = {},
 | |
|             states = {}
 | |
|         }
 | |
|     end
 | |
| end
 | |
| 
 | |
| ClearEntityStates = function(uNetId)
 | |
|     if EntitiesStates[uNetId] then
 | |
|         EntitiesStates[uNetId] = nil
 | |
|     end
 | |
| end
 | |
| --#endregion
 | |
| 
 | |
| -- #region Get, Set, Update
 | |
| GetEntityStateValue = function(uNetId, key)
 | |
|     if EntitiesStates[uNetId] then
 | |
|         if key then
 | |
|             return EntitiesStates[uNetId].states[key]
 | |
|         else
 | |
|             return EntitiesStates[uNetId].states
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| SetEntityStateValue = function(uNetId, key, value)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
|     
 | |
|     EntitiesStates[uNetId].states[key] = value
 | |
|     UpdateStateValueForListeners(uNetId, key, value)
 | |
| end
 | |
| 
 | |
| UpdateStateValueForListeners = function(uNetId, key, value)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     for k,v in pairs(EntitiesStates[uNetId].listeners) do
 | |
|         TriggerClientEvent("Utility:Net:UpdateStateValue", v, uNetId, key, value)
 | |
|     end
 | |
| end
 | |
| --#endregion
 | |
| 
 | |
| --#region Listeners
 | |
| ListenStateUpdates = function(source, uNetId)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     table.insert(EntitiesStates[uNetId].listeners, source)
 | |
| end
 | |
| 
 | |
| RemoveStateListener = function(source, uNetId)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     for k,v in pairs(EntitiesStates[uNetId].listeners) do
 | |
|         if v == source then
 | |
|             table.remove(EntitiesStates[uNetId].listeners, k)
 | |
|             break
 | |
|         end
 | |
|     end    
 | |
| end
 | |
| 
 | |
| RemoveStateListenerFromAll = function(source)
 | |
|     for k,v in pairs(EntitiesStates) do
 | |
|         RemoveStateListener(source, k)
 | |
|     end
 | |
| end
 | |
| 
 | |
| CallFunctionForListeners = function(uNetId, fn)
 | |
|     if GetLifetimeOfState(uNetId) > 5000 then
 | |
|         for k,v in pairs(EntitiesStates[uNetId].listeners) do
 | |
|             fn(v)
 | |
|         end
 | |
|     else -- If entity is pretty new we call the function for every single person (since it could be still rendering for someone)
 | |
|         local players = GetPlayers()
 | |
| 
 | |
|         for k,v in pairs(players) do
 | |
|             fn(v)
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| TriggerEventForListeners = function(event, uNetId, ...)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     local args = {...}
 | |
|     CallFunctionForListeners(uNetId, function(v) 
 | |
|         TriggerClientEvent(event, v, table.unpack(args))
 | |
|     end)
 | |
| end
 | |
| 
 | |
| TriggerEventForListenersExcept = function(event, uNetId, source, ...)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     local args = {...}
 | |
|     CallFunctionForListeners(uNetId, function(v)
 | |
|         if v ~= source then
 | |
|             TriggerClientEvent(event, v, table.unpack(args))
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| TriggerLatentEventForListeners = function(event, uNetId, speed, ...)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     local args = {...}
 | |
|     CallFunctionForListeners(uNetId, function(v)
 | |
|         TriggerLatentClientEvent(event, v, speed or 5120, table.unpack(args))
 | |
|     end)
 | |
| end
 | |
| 
 | |
| TriggerLatentEventForListenersExcept = function(event, uNetId, speed, source, ...)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     local args = {...}
 | |
|     CallFunctionForListeners(uNetId, function(v)
 | |
|         if v ~= source then
 | |
|             TriggerLatentClientEvent(event, v, speed or 5120, table.unpack(args))
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| GetLifetimeOfState = function(uNetId)
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         return 0
 | |
|     end
 | |
| 
 | |
|     return GetGameTimer() - EntitiesStates[uNetId].created
 | |
| end
 | |
| --#endregion
 | |
| 
 | |
| --#region Net Events
 | |
| RegisterNetEvent("Utility:Net:ListenStateUpdates", function(uNetId)
 | |
|     ListenStateUpdates(source, uNetId)
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent("Utility:Net:RemoveStateListener", function(uNetId)
 | |
|     RemoveStateListener(source, uNetId)
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent("Utility:Net:GetState", function(uNetId)
 | |
|     local source = source
 | |
| 
 | |
|     if not EntitiesStates[uNetId] then
 | |
|         TriggerClientEvent("Utility:Net:GetState"..uNetId, source, nil)
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     ListenStateUpdates(source, uNetId)
 | |
|     TriggerClientEvent("Utility:Net:GetState"..uNetId, source, EntitiesStates[uNetId].states)
 | |
| end)
 | |
| --#endregion
 | |
| 
 | |
| -- On player disconnect remove all listeners of that player (prevent useless bandwidth usage)
 | |
| AddEventHandler("playerDropped", function(reason)
 | |
|     RemoveStateListenerFromAll(source)
 | |
| end)
 | |
| 
 | |
| exports("GetEntityStateValue", GetEntityStateValue)
 | |
| exports("SetEntityStateValue", SetEntityStateValue)
 | |
| 
 | |
| --[[ Citizen.CreateThread(function()
 | |
|     local obj = UtilityNet.CreateEntity("prop_weed_01", vec3(-1268.5847, -3013.3059, -48.4830))
 | |
|     local state = UtilityNet.State(obj)
 | |
|     state.random = {}
 | |
| 
 | |
|     while true do
 | |
|         local rand = math.random(1, 100)
 | |
|         state.random.key = rand
 | |
|         state.random.key2 = rand + math.random(1, 100)
 | |
| 
 | |
|         state.random.deep = {}
 | |
|         state.random.deep.deep2 = math.random(1, 100)
 | |
| 
 | |
|         print(state.random.key, state.random.key2, state.random.deep, state.random.deep.deep2)
 | |
|         Citizen.Wait(5000)
 | |
|     end
 | |
| end) ]] | 
