Compare commits
No commits in common. "e4b71869106d5d3d6a0d93c4b4a7cd859dfc1f82" and "45f85f0a88e0b3c97c869f3c67bd19c797070378" have entirely different histories.
e4b7186910
...
45f85f0a88
@ -76,9 +76,3 @@ txaEvent "serverShuttingDown" "{"delay":5000,"author":"txAdmin","m
|
|||||||
ensure "ui_pmenu"
|
ensure "ui_pmenu"
|
||||||
### 2025-03-16 15:09:04.329
|
### 2025-03-16 15:09:04.329
|
||||||
txaReportResources
|
txaReportResources
|
||||||
### 2025-03-17 13:21:02.116
|
|
||||||
txaReportResources
|
|
||||||
### 2025-03-17 13:25:13.990
|
|
||||||
txaEvent "serverShuttingDown" "{\"delay\":5000,\"author\":\"androxaaa\",\"message\":\"Server restarting (admin request).\"}"
|
|
||||||
### 2025-03-17 13:28:58.791
|
|
||||||
quit "host shutting down"
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aw
|
|||||||
|
|
||||||
name 'ox_lib'
|
name 'ox_lib'
|
||||||
author 'Overextended'
|
author 'Overextended'
|
||||||
version '3.30.3'
|
version '3.26.0'
|
||||||
license 'LGPL-3.0-or-later'
|
license 'LGPL-3.0-or-later'
|
||||||
repository 'https://github.com/overextended/ox_lib'
|
repository 'https://github.com/overextended/ox_lib'
|
||||||
description 'A library of shared functions to utilise in other resources.'
|
description 'A library of shared functions to utilise in other resources.'
|
||||||
|
|||||||
@ -1,12 +1,6 @@
|
|||||||
---@class Array<T> : OxClass, { [number]: T }
|
---@class Array : OxClass
|
||||||
lib.array = lib.class('Array')
|
lib.array = lib.class('Array')
|
||||||
|
|
||||||
local table_unpack = table.unpack
|
|
||||||
local table_remove = table.remove
|
|
||||||
local table_clone = table.clone
|
|
||||||
local table_concat = table.concat
|
|
||||||
local table_type = table.type
|
|
||||||
|
|
||||||
---@alias ArrayLike<T> Array | { [number]: T }
|
---@alias ArrayLike<T> Array | { [number]: T }
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
@ -25,63 +19,18 @@ function lib.array:__newindex(index, value)
|
|||||||
rawset(self, index, value)
|
rawset(self, index, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Creates a new array from an iteratable value.
|
---Create a new array containing the elements from two arrays.
|
||||||
---@param iter table | function | string
|
---@param arr ArrayLike
|
||||||
---@return Array
|
function lib.array:merge(arr)
|
||||||
function lib.array:from(iter)
|
local newArr = table.clone(self)
|
||||||
local iterType = type(iter)
|
|
||||||
|
|
||||||
if iterType == 'table' then
|
|
||||||
return lib.array:new(table_unpack(iter))
|
|
||||||
end
|
|
||||||
|
|
||||||
if iterType == 'string' then
|
|
||||||
return lib.array:new(string.strsplit('', iter))
|
|
||||||
end
|
|
||||||
|
|
||||||
if iterType == 'function' then
|
|
||||||
local arr = lib.array:new()
|
|
||||||
local length = 0
|
|
||||||
|
|
||||||
for value in iter do
|
|
||||||
length += 1
|
|
||||||
arr[length] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
return arr
|
|
||||||
end
|
|
||||||
|
|
||||||
error(('Array.from argument was not a valid iterable value (received %s)'):format(iterType))
|
|
||||||
end
|
|
||||||
|
|
||||||
---Returns the element at the given index, with negative numbers counting backwards from the end of the array.
|
|
||||||
---@param index number
|
|
||||||
---@return unknown
|
|
||||||
function lib.array:at(index)
|
|
||||||
if index < 0 then
|
|
||||||
index = #self + index + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
return self[index]
|
|
||||||
end
|
|
||||||
|
|
||||||
---Create a new array containing the elements of two or more arrays.
|
|
||||||
---@param ... ArrayLike
|
|
||||||
function lib.array:merge(...)
|
|
||||||
local newArr = table_clone(self)
|
|
||||||
local length = #self
|
local length = #self
|
||||||
local arrays = { ... }
|
|
||||||
|
|
||||||
for i = 1, #arrays do
|
for i = 1, #arr do
|
||||||
local arr = arrays[i]
|
|
||||||
|
|
||||||
for j = 1, #arr do
|
|
||||||
length += 1
|
length += 1
|
||||||
newArr[length] = arr[j]
|
newArr[length] = arr[i]
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return lib.array:new(table_unpack(newArr))
|
return lib.array:new(table.unpack(newArr))
|
||||||
end
|
end
|
||||||
|
|
||||||
---Tests if all elements in an array succeed in passing the provided test function.
|
---Tests if all elements in an array succeed in passing the provided test function.
|
||||||
@ -96,26 +45,7 @@ function lib.array:every(testFn)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
---Sets all elements within a range to the given value and returns the modified array.
|
---Creates a new array containing the elements from an array thtat pass the test of the provided function.
|
||||||
---@param value any
|
|
||||||
---@param start? number
|
|
||||||
---@param endIndex? number
|
|
||||||
function lib.array:fill(value, start, endIndex)
|
|
||||||
local length = #self
|
|
||||||
start = start or 1
|
|
||||||
endIndex = endIndex or length
|
|
||||||
|
|
||||||
if start < 1 then start = 1 end
|
|
||||||
if endIndex > length then endIndex = length end
|
|
||||||
|
|
||||||
for i = start, endIndex do
|
|
||||||
self[i] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
---Creates a new array containing the elements from an array that pass the test of the provided function.
|
|
||||||
---@param testFn fun(element: unknown): boolean
|
---@param testFn fun(element: unknown): boolean
|
||||||
function lib.array:filter(testFn)
|
function lib.array:filter(testFn)
|
||||||
local newArr = {}
|
local newArr = {}
|
||||||
@ -130,7 +60,7 @@ function lib.array:filter(testFn)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return lib.array:new(table_unpack(newArr))
|
return lib.array:new(table.unpack(newArr))
|
||||||
end
|
end
|
||||||
|
|
||||||
---Returns the first or last element of an array that passes the provided test function.
|
---Returns the first or last element of an array that passes the provided test function.
|
||||||
@ -179,7 +109,7 @@ function lib.array:indexOf(value, last)
|
|||||||
local element = self[i]
|
local element = self[i]
|
||||||
|
|
||||||
if element == value then
|
if element == value then
|
||||||
return i
|
return element
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -192,38 +122,15 @@ function lib.array:forEach(cb)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---Determines if a given element exists inside an array.
|
|
||||||
---@param element unknown The value to find in the array.
|
|
||||||
---@param fromIndex? number The position in the array to begin searching from.
|
|
||||||
function lib.array:includes(element, fromIndex)
|
|
||||||
for i = (fromIndex or 1), #self do
|
|
||||||
if self[i] == element then return true end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
---Concatenates all array elements into a string, seperated by commas or the specified seperator.
|
---Concatenates all array elements into a string, seperated by commas or the specified seperator.
|
||||||
---@param seperator? string
|
---@param seperator? string
|
||||||
function lib.array:join(seperator)
|
function lib.array:join(seperator)
|
||||||
return table_concat(self, seperator or ',')
|
return table.concat(self, seperator or ',')
|
||||||
end
|
|
||||||
|
|
||||||
---Create a new array containing the results from calling the provided function on every element in an array.
|
|
||||||
---@param cb fun(element: unknown, index: number, array: self): unknown
|
|
||||||
function lib.array:map(cb)
|
|
||||||
local arr = {}
|
|
||||||
|
|
||||||
for i = 1, #self do
|
|
||||||
arr[i] = cb(self[i], i, self)
|
|
||||||
end
|
|
||||||
|
|
||||||
return lib.array:new(table_unpack(arr))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---Removes the last element from an array and returns the removed element.
|
---Removes the last element from an array and returns the removed element.
|
||||||
function lib.array:pop()
|
function lib.array:pop()
|
||||||
return table_remove(self)
|
return table.remove(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Adds the given elements to the end of an array and returns the new array length.
|
---Adds the given elements to the end of an array and returns the new array length.
|
||||||
@ -240,110 +147,35 @@ function lib.array:push(...)
|
|||||||
return length
|
return length
|
||||||
end
|
end
|
||||||
|
|
||||||
---The "reducer" function is applied to every element within an array, with the previous element's result serving as the accumulator.
|
---Removes the first element from an array and returns the removed element.
|
||||||
|
function lib.array:shift()
|
||||||
|
return table.remove(self, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
---The "reducer" function is applied to every element within an array, with the previous element's result serving as the accumulator.\
|
||||||
---If an initial value is provided, it's used as the accumulator for index 1; otherwise, index 1 itself serves as the initial value, and iteration begins from index 2.
|
---If an initial value is provided, it's used as the accumulator for index 1; otherwise, index 1 itself serves as the initial value, and iteration begins from index 2.
|
||||||
---@generic T
|
---@generic T
|
||||||
---@param reducer fun(accumulator: T, currentValue: T, index?: number): T
|
---@param reducer fun(accumulator: T, currentValue: T, index?: number): T
|
||||||
---@param initialValue? T
|
---@param initialValue? T
|
||||||
---@param reverse? boolean Iterate over the array from right-to-left.
|
|
||||||
---@return T
|
---@return T
|
||||||
function lib.array:reduce(reducer, initialValue, reverse)
|
function lib.array:reduce(reducer, initialValue)
|
||||||
local length = #self
|
|
||||||
local initialIndex = initialValue and 1 or 2
|
local initialIndex = initialValue and 1 or 2
|
||||||
local accumulator = initialValue or self[1]
|
local accumulator = initialValue or self[1]
|
||||||
|
|
||||||
if reverse then
|
for i = initialIndex, #self do
|
||||||
for i = initialIndex, length do
|
|
||||||
local index = length - i + initialIndex
|
|
||||||
accumulator = reducer(accumulator, self[index], index)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for i = initialIndex, length do
|
|
||||||
accumulator = reducer(accumulator, self[i], i)
|
accumulator = reducer(accumulator, self[i], i)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
return accumulator
|
return accumulator
|
||||||
end
|
end
|
||||||
|
|
||||||
---Reverses the elements inside an array.
|
|
||||||
function lib.array:reverse()
|
|
||||||
local i, j = 1, #self
|
|
||||||
|
|
||||||
while i < j do
|
|
||||||
self[i], self[j] = self[j], self[i]
|
|
||||||
i += 1
|
|
||||||
j -= 1
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
---Removes the first element from an array and returns the removed element.
|
|
||||||
function lib.array:shift()
|
|
||||||
return table_remove(self, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
---Creates a shallow copy of a portion of an array as a new array.
|
|
||||||
---@param start? number
|
|
||||||
---@param finish? number
|
|
||||||
function lib.array:slice(start, finish)
|
|
||||||
local length = #self
|
|
||||||
start = start or 1
|
|
||||||
finish = finish or length
|
|
||||||
|
|
||||||
if start < 0 then start = length + start + 1 end
|
|
||||||
if finish < 0 then finish = length + finish + 1 end
|
|
||||||
if start < 1 then start = 1 end
|
|
||||||
if finish > length then finish = length end
|
|
||||||
|
|
||||||
local arr = lib.array:new()
|
|
||||||
local index = 0
|
|
||||||
|
|
||||||
for i = start, finish do
|
|
||||||
index += 1
|
|
||||||
arr[index] = self[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
return arr
|
|
||||||
end
|
|
||||||
|
|
||||||
---Creates a new array with reversed elements from the given array.
|
|
||||||
function lib.array:toReversed()
|
|
||||||
local reversed = lib.array:new()
|
|
||||||
|
|
||||||
for i = #self, 1, -1 do
|
|
||||||
reversed:push(self[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
return reversed
|
|
||||||
end
|
|
||||||
|
|
||||||
---Inserts the given elements to the start of an array and returns the new array length.
|
|
||||||
---@param ... any
|
|
||||||
function lib.array:unshift(...)
|
|
||||||
local elements = { ... }
|
|
||||||
local length = #self
|
|
||||||
local eLength = #elements
|
|
||||||
|
|
||||||
for i = length, 1, -1 do
|
|
||||||
self[i + eLength] = self[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, #elements do
|
|
||||||
self[i] = elements[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
return length + eLength
|
|
||||||
end
|
|
||||||
|
|
||||||
---Returns true if the given table is an instance of array or an array-like table.
|
---Returns true if the given table is an instance of array or an array-like table.
|
||||||
---@param tbl ArrayLike
|
---@param tbl ArrayLike
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function lib.array.isArray(tbl)
|
function lib.array.isArray(tbl)
|
||||||
local tableType = table_type(tbl)
|
if not type(tbl) == 'table' then return false end
|
||||||
|
|
||||||
if not tableType then return false end
|
local tableType = table.type(tbl)
|
||||||
|
|
||||||
if tableType == 'array' or tableType == 'empty' or lib.array.instanceOf(tbl, lib.array) then
|
if tableType == 'array' or tableType == 'empty' or lib.array.instanceOf(tbl, lib.array) then
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -5,12 +5,9 @@ local callbackTimeout = GetConvarInt('ox:callbackTimeout', 300000)
|
|||||||
|
|
||||||
RegisterNetEvent(cbEvent:format(cache.resource), function(key, ...)
|
RegisterNetEvent(cbEvent:format(cache.resource), function(key, ...)
|
||||||
local cb = pendingCallbacks[key]
|
local cb = pendingCallbacks[key]
|
||||||
|
|
||||||
if not cb then return end
|
|
||||||
|
|
||||||
pendingCallbacks[key] = nil
|
pendingCallbacks[key] = nil
|
||||||
|
|
||||||
cb(...)
|
return cb and cb(...)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
---@param event string
|
---@param event string
|
||||||
@ -44,19 +41,12 @@ local function triggerServerCallback(_, event, delay, cb, ...)
|
|||||||
key = ('%s:%s'):format(event, math.random(0, 100000))
|
key = ('%s:%s'):format(event, math.random(0, 100000))
|
||||||
until not pendingCallbacks[key]
|
until not pendingCallbacks[key]
|
||||||
|
|
||||||
TriggerServerEvent('ox_lib:validateCallback', event, cache.resource, key)
|
|
||||||
TriggerServerEvent(cbEvent:format(event), cache.resource, key, ...)
|
TriggerServerEvent(cbEvent:format(event), cache.resource, key, ...)
|
||||||
|
|
||||||
---@type promise | false
|
---@type promise | false
|
||||||
local promise = not cb and promise.new()
|
local promise = not cb and promise.new()
|
||||||
|
|
||||||
pendingCallbacks[key] = function(response, ...)
|
pendingCallbacks[key] = function(response, ...)
|
||||||
if response == 'cb_invalid' then
|
|
||||||
response = ("callback '%s' does not exist"):format(event)
|
|
||||||
|
|
||||||
return promise and promise:reject(response) or error(response)
|
|
||||||
end
|
|
||||||
|
|
||||||
response = { response, ... }
|
response = { response, ... }
|
||||||
|
|
||||||
if promise then
|
if promise then
|
||||||
@ -84,10 +74,6 @@ lib.callback = setmetatable({}, {
|
|||||||
else
|
else
|
||||||
local cbType = type(cb)
|
local cbType = type(cb)
|
||||||
|
|
||||||
if cbType == 'table' and getmetatable(cb)?.__call then
|
|
||||||
cbType = 'function'
|
|
||||||
end
|
|
||||||
|
|
||||||
assert(cbType == 'function', ("expected argument 3 to have type 'function' (received %s)"):format(cbType))
|
assert(cbType == 'function', ("expected argument 3 to have type 'function' (received %s)"):format(cbType))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -123,11 +109,7 @@ local pcall = pcall
|
|||||||
---Registers an event handler and callback function to respond to server requests.
|
---Registers an event handler and callback function to respond to server requests.
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
---@diagnostic disable-next-line: duplicate-set-field
|
||||||
function lib.callback.register(name, cb)
|
function lib.callback.register(name, cb)
|
||||||
event = cbEvent:format(name)
|
RegisterNetEvent(cbEvent:format(name), function(resource, key, ...)
|
||||||
|
|
||||||
lib.setValidCallback(name, true)
|
|
||||||
|
|
||||||
RegisterNetEvent(event, function(resource, key, ...)
|
|
||||||
TriggerServerEvent(cbEvent:format(resource), key, callbackResponse(pcall(cb, ...)))
|
TriggerServerEvent(cbEvent:format(resource), key, callbackResponse(pcall(cb, ...)))
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,12 +4,9 @@ local callbackTimeout = GetConvarInt('ox:callbackTimeout', 300000)
|
|||||||
|
|
||||||
RegisterNetEvent(cbEvent:format(cache.resource), function(key, ...)
|
RegisterNetEvent(cbEvent:format(cache.resource), function(key, ...)
|
||||||
local cb = pendingCallbacks[key]
|
local cb = pendingCallbacks[key]
|
||||||
|
|
||||||
if not cb then return end
|
|
||||||
|
|
||||||
pendingCallbacks[key] = nil
|
pendingCallbacks[key] = nil
|
||||||
|
|
||||||
cb(...)
|
return cb and cb(...)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
---@param _ any
|
---@param _ any
|
||||||
@ -27,19 +24,12 @@ local function triggerClientCallback(_, event, playerId, cb, ...)
|
|||||||
key = ('%s:%s:%s'):format(event, math.random(0, 100000), playerId)
|
key = ('%s:%s:%s'):format(event, math.random(0, 100000), playerId)
|
||||||
until not pendingCallbacks[key]
|
until not pendingCallbacks[key]
|
||||||
|
|
||||||
TriggerClientEvent('ox_lib:validateCallback', playerId, event, cache.resource, key)
|
|
||||||
TriggerClientEvent(cbEvent:format(event), playerId, cache.resource, key, ...)
|
TriggerClientEvent(cbEvent:format(event), playerId, cache.resource, key, ...)
|
||||||
|
|
||||||
---@type promise | false
|
---@type promise | false
|
||||||
local promise = not cb and promise.new()
|
local promise = not cb and promise.new()
|
||||||
|
|
||||||
pendingCallbacks[key] = function(response, ...)
|
pendingCallbacks[key] = function(response, ...)
|
||||||
if response == 'cb_invalid' then
|
|
||||||
response = ("callback '%s' does not exist"):format(event)
|
|
||||||
|
|
||||||
return promise and promise:reject(response) or error(response)
|
|
||||||
end
|
|
||||||
|
|
||||||
response = { response, ... }
|
response = { response, ... }
|
||||||
|
|
||||||
if promise then
|
if promise then
|
||||||
@ -67,10 +57,6 @@ lib.callback = setmetatable({}, {
|
|||||||
else
|
else
|
||||||
local cbType = type(cb)
|
local cbType = type(cb)
|
||||||
|
|
||||||
if cbType == 'table' and getmetatable(cb)?.__call then
|
|
||||||
cbType = 'function'
|
|
||||||
end
|
|
||||||
|
|
||||||
assert(cbType == 'function', ("expected argument 3 to have type 'function' (received %s)"):format(cbType))
|
assert(cbType == 'function', ("expected argument 3 to have type 'function' (received %s)"):format(cbType))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -106,11 +92,7 @@ local pcall = pcall
|
|||||||
---Registers an event handler and callback function to respond to client requests.
|
---Registers an event handler and callback function to respond to client requests.
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
---@diagnostic disable-next-line: duplicate-set-field
|
||||||
function lib.callback.register(name, cb)
|
function lib.callback.register(name, cb)
|
||||||
event = cbEvent:format(name)
|
RegisterNetEvent(cbEvent:format(name), function(resource, key, ...)
|
||||||
|
|
||||||
lib.setValidCallback(name, true)
|
|
||||||
|
|
||||||
RegisterNetEvent(event, function(resource, key, ...)
|
|
||||||
TriggerClientEvent(cbEvent:format(resource), source, key, callbackResponse(pcall(cb, source, ...)))
|
TriggerClientEvent(cbEvent:format(resource), source, key, callbackResponse(pcall(cb, source, ...)))
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -55,8 +55,10 @@ local function void() return '' end
|
|||||||
---@return T
|
---@return T
|
||||||
function mixins.new(class, ...)
|
function mixins.new(class, ...)
|
||||||
local constructor = getConstructor(class)
|
local constructor = getConstructor(class)
|
||||||
local private = {}
|
|
||||||
local obj = setmetatable({ private = private }, class)
|
local obj = setmetatable({
|
||||||
|
private = {}
|
||||||
|
}, class)
|
||||||
|
|
||||||
if constructor then
|
if constructor then
|
||||||
local parent = class
|
local parent = class
|
||||||
@ -73,8 +75,8 @@ function mixins.new(class, ...)
|
|||||||
|
|
||||||
rawset(obj, 'super', nil)
|
rawset(obj, 'super', nil)
|
||||||
|
|
||||||
if private ~= obj.private or next(obj.private) then
|
if next(obj.private) then
|
||||||
private = table.clone(obj.private)
|
local private = table.clone(obj.private)
|
||||||
|
|
||||||
table.wipe(obj.private)
|
table.wipe(obj.private)
|
||||||
setmetatable(obj.private, {
|
setmetatable(obj.private, {
|
||||||
|
|||||||
@ -7,27 +7,28 @@ local currentDate = {}
|
|||||||
setmetatable(currentDate, {
|
setmetatable(currentDate, {
|
||||||
__index = function(self, index)
|
__index = function(self, index)
|
||||||
local newDate = os.date('*t') --[[@as Date]]
|
local newDate = os.date('*t') --[[@as Date]]
|
||||||
|
|
||||||
for k, v in pairs(newDate) do
|
for k, v in pairs(newDate) do
|
||||||
self[k] = v
|
self[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
SetTimeout(1000, function() table.wipe(self) end)
|
SetTimeout(1000, function() table.wipe(self) end)
|
||||||
|
|
||||||
return self[index]
|
return self[index]
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
---@class OxTaskProperties
|
---@class OxTaskProperties
|
||||||
---@field minute? number|string|function
|
---@field minute? number | string
|
||||||
---@field hour? number|string|function
|
---@field hour? number | string
|
||||||
---@field day? number|string|function
|
---@field day? number | string
|
||||||
---@field month? number|string|function
|
---@field month? number | string
|
||||||
---@field year? number|string|function
|
---@field year? number | string
|
||||||
---@field weekday? number|string|function
|
---@field weekday? number | string
|
||||||
---@field job fun(task: OxTask, date: osdate)
|
---@field job fun(task: OxTask, date: osdate)
|
||||||
---@field isActive boolean
|
---@field isActive boolean
|
||||||
---@field id number
|
---@field id number
|
||||||
---@field debug? boolean
|
---@field debug? boolean
|
||||||
---@field lastRun? number
|
|
||||||
---@field maxDelay? number Maximum allowed delay in seconds before skipping (0 to disable)
|
|
||||||
|
|
||||||
---@class OxTask : OxTaskProperties
|
---@class OxTask : OxTaskProperties
|
||||||
---@field expression string
|
---@field expression string
|
||||||
@ -35,14 +36,6 @@ setmetatable(currentDate, {
|
|||||||
local OxTask = {}
|
local OxTask = {}
|
||||||
OxTask.__index = OxTask
|
OxTask.__index = OxTask
|
||||||
|
|
||||||
local validRanges = {
|
|
||||||
min = { min = 0, max = 59 },
|
|
||||||
hour = { min = 0, max = 23 },
|
|
||||||
day = { min = 1, max = 31 },
|
|
||||||
month = { min = 1, max = 12 },
|
|
||||||
wday = { min = 0, max = 7 },
|
|
||||||
}
|
|
||||||
|
|
||||||
local maxUnits = {
|
local maxUnits = {
|
||||||
min = 60,
|
min = 60,
|
||||||
hour = 24,
|
hour = 24,
|
||||||
@ -51,23 +44,7 @@ local maxUnits = {
|
|||||||
month = 12,
|
month = 12,
|
||||||
}
|
}
|
||||||
|
|
||||||
local weekdayMap = {
|
--- Gets the amount of days in certain month
|
||||||
sun = 1,
|
|
||||||
mon = 2,
|
|
||||||
tue = 3,
|
|
||||||
wed = 4,
|
|
||||||
thu = 5,
|
|
||||||
fri = 6,
|
|
||||||
sat = 7,
|
|
||||||
}
|
|
||||||
|
|
||||||
local monthMap = {
|
|
||||||
jan = 1, feb = 2, mar = 3, apr = 4,
|
|
||||||
may = 5, jun = 6, jul = 7, aug = 8,
|
|
||||||
sep = 9, oct = 10, nov = 11, dec = 12
|
|
||||||
}
|
|
||||||
|
|
||||||
---Returns the last day of the specified month
|
|
||||||
---@param month number
|
---@param month number
|
||||||
---@param year? number
|
---@param year? number
|
||||||
---@return number
|
---@return number
|
||||||
@ -75,96 +52,9 @@ local function getMaxDaysInMonth(month, year)
|
|||||||
return os.date('*t', os.time({ year = year or currentDate.year, month = month + 1, day = -1 })).day --[[@as number]]
|
return os.date('*t', os.time({ year = year or currentDate.year, month = month + 1, day = -1 })).day --[[@as number]]
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param value string|number
|
---@param value string | number | nil
|
||||||
---@param unit string
|
---@param unit string
|
||||||
---@return boolean
|
---@return string | number | false | nil
|
||||||
local function isValueInRange(value, unit)
|
|
||||||
local range = validRanges[unit]
|
|
||||||
if not range then return true end
|
|
||||||
return value >= range.min and value <= range.max
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param value string
|
|
||||||
---@param unit string
|
|
||||||
---@return number|string|function|nil
|
|
||||||
local function parseCron(value, unit)
|
|
||||||
if not value or value == '*' then return end
|
|
||||||
|
|
||||||
if unit == 'day' and value:lower() == 'l' then
|
|
||||||
return function()
|
|
||||||
return getMaxDaysInMonth(currentDate.month, currentDate.year)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local num = tonumber(value)
|
|
||||||
if num then
|
|
||||||
if not isValueInRange(num, unit) then
|
|
||||||
error(("^1invalid cron expression. '%s' is out of range for %s^0"):format(value, unit), 3)
|
|
||||||
end
|
|
||||||
return num
|
|
||||||
end
|
|
||||||
|
|
||||||
if unit == 'wday' then
|
|
||||||
local start, stop = value:match('(%a+)-(%a+)')
|
|
||||||
if start and stop then
|
|
||||||
start = weekdayMap[start:lower()]
|
|
||||||
stop = weekdayMap[stop:lower()]
|
|
||||||
if start and stop then
|
|
||||||
if stop < start then stop = stop + 7 end
|
|
||||||
return ('%d-%d'):format(start, stop)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local day = weekdayMap[value:lower()]
|
|
||||||
if day then return day end
|
|
||||||
end
|
|
||||||
|
|
||||||
if unit == 'month' then
|
|
||||||
local months = {}
|
|
||||||
for month in value:gmatch('[^,]+') do
|
|
||||||
local monthNum = monthMap[month:lower()]
|
|
||||||
if monthNum then
|
|
||||||
months[#months + 1] = tostring(monthNum)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #months > 0 then
|
|
||||||
return table.concat(months, ',')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local stepMatch = value:match('^%*/(%d+)$')
|
|
||||||
if stepMatch then
|
|
||||||
local step = tonumber(stepMatch)
|
|
||||||
if not step or step == 0 then
|
|
||||||
error(("^1invalid cron expression. Step value cannot be %s^0"):format(step or 'nil'), 3)
|
|
||||||
end
|
|
||||||
return value
|
|
||||||
end
|
|
||||||
|
|
||||||
local start, stop = value:match('^(%d+)-(%d+)$')
|
|
||||||
if start and stop then
|
|
||||||
start, stop = tonumber(start), tonumber(stop)
|
|
||||||
if not start or not stop or not isValueInRange(start, unit) or not isValueInRange(stop, unit) then
|
|
||||||
error(("^1invalid cron expression. Range '%s' is invalid for %s^0"):format(value, unit), 3)
|
|
||||||
end
|
|
||||||
return value
|
|
||||||
end
|
|
||||||
|
|
||||||
local valid = true
|
|
||||||
for item in value:gmatch('[^,]+') do
|
|
||||||
local num = tonumber(item)
|
|
||||||
if not num or not isValueInRange(num, unit) then
|
|
||||||
valid = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if valid then return value end
|
|
||||||
|
|
||||||
error(("^1invalid cron expression. '%s' is not supported for %s^0"):format(value, unit), 3)
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param value string|number|function|nil
|
|
||||||
---@param unit string
|
|
||||||
---@return number|false|nil
|
|
||||||
local function getTimeUnit(value, unit)
|
local function getTimeUnit(value, unit)
|
||||||
local currentTime = currentDate[unit]
|
local currentTime = currentDate[unit]
|
||||||
|
|
||||||
@ -172,24 +62,25 @@ local function getTimeUnit(value, unit)
|
|||||||
return unit == 'min' and currentTime + 1 or currentTime
|
return unit == 'min' and currentTime + 1 or currentTime
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(value) == 'function' then
|
|
||||||
return value()
|
|
||||||
end
|
|
||||||
|
|
||||||
local unitMax = maxUnits[unit]
|
local unitMax = maxUnits[unit]
|
||||||
|
|
||||||
if type(value) == 'string' then
|
if type(value) == 'string' then
|
||||||
local stepValue = string.match(value, '*/(%d+)')
|
local stepValue = string.match(value, '*/(%d+)')
|
||||||
|
|
||||||
if stepValue then
|
if stepValue then
|
||||||
local step = tonumber(stepValue)
|
-- */10 * * * * is equal to a list of 0,10,20,30,40,50
|
||||||
|
-- best suited to factors of unitMax (excluding the highest and lowest numbers)
|
||||||
|
-- i.e. for minutes - 2, 3, 4, 5, 6, 10, 12, 15, 20, 30
|
||||||
for i = currentTime + 1, unitMax do
|
for i = currentTime + 1, unitMax do
|
||||||
if i % step == 0 then return i end
|
-- if i is divisible by stepValue
|
||||||
|
if i % stepValue == 0 then return i end
|
||||||
end
|
end
|
||||||
return step + unitMax
|
|
||||||
|
return stepValue + unitMax
|
||||||
end
|
end
|
||||||
|
|
||||||
local range = string.match(value, '%d+-%d+')
|
local range = string.match(value, '%d+-%d+')
|
||||||
|
|
||||||
if range then
|
if range then
|
||||||
local min, max = string.strsplit('-', range)
|
local min, max = string.strsplit('-', range)
|
||||||
min, max = tonumber(min, 10), tonumber(max, 10)
|
min, max = tonumber(min, 10), tonumber(max, 10)
|
||||||
@ -206,15 +97,12 @@ local function getTimeUnit(value, unit)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local list = string.match(value, '%d+,%d+')
|
local list = string.match(value, '%d+,%d+')
|
||||||
if list then
|
|
||||||
local values = {}
|
|
||||||
for listValue in string.gmatch(value, '%d+') do
|
|
||||||
values[#values + 1] = tonumber(listValue)
|
|
||||||
end
|
|
||||||
table.sort(values)
|
|
||||||
|
|
||||||
for i = 1, #values do
|
if list then
|
||||||
local listValue = values[i]
|
for listValue in string.gmatch(value, '%d+') --[[@as number]] do
|
||||||
|
listValue = tonumber(listValue)
|
||||||
|
|
||||||
|
-- e.g. if current time is less than in the expression 0,10,20,45 * * * *
|
||||||
if unit == 'min' then
|
if unit == 'min' then
|
||||||
if currentTime < listValue then
|
if currentTime < listValue then
|
||||||
return listValue
|
return listValue
|
||||||
@ -224,47 +112,56 @@ local function getTimeUnit(value, unit)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return values[1] + unitMax
|
-- if iterator failed, return the first value in the list
|
||||||
|
return tonumber(string.match(value, '%d+')) + unitMax
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if unit == 'min' then
|
if unit == 'min' then
|
||||||
return value <= currentTime and value + unitMax or value --[[@as number]]
|
return value <= currentTime and value + unitMax or value
|
||||||
end
|
end
|
||||||
|
|
||||||
return value < currentTime and value + unitMax or value --[[@as number]]
|
return value < currentTime and value + unitMax or value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Get a timestamp for the next time to run the task today.
|
||||||
---@return number?
|
---@return number?
|
||||||
function OxTask:getNextTime()
|
function OxTask:getNextTime()
|
||||||
if not self.isActive then return end
|
if not self.isActive then return end
|
||||||
|
|
||||||
local day = getTimeUnit(self.day, 'day')
|
local day = getTimeUnit(self.day, 'day')
|
||||||
|
|
||||||
|
-- If current day is the last day of the month, and the task is scheduled for the last day of the month, then the task should run.
|
||||||
if day == 0 then
|
if day == 0 then
|
||||||
|
-- Should probably be used month from getTimeUnit, but don't want to reorder this code.
|
||||||
day = getMaxDaysInMonth(currentDate.month)
|
day = getMaxDaysInMonth(currentDate.month)
|
||||||
end
|
end
|
||||||
|
|
||||||
if day ~= currentDate.day then return end
|
if day ~= currentDate.day then return end
|
||||||
|
|
||||||
local month = getTimeUnit(self.month, 'month')
|
local month = getTimeUnit(self.month, 'month')
|
||||||
|
|
||||||
if month ~= currentDate.month then return end
|
if month ~= currentDate.month then return end
|
||||||
|
|
||||||
local weekday = getTimeUnit(self.weekday, 'wday')
|
local weekday = getTimeUnit(self.weekday, 'wday')
|
||||||
if weekday and weekday ~= currentDate.wday then return end
|
|
||||||
|
if weekday ~= currentDate.wday then return end
|
||||||
|
|
||||||
local minute = getTimeUnit(self.minute, 'min')
|
local minute = getTimeUnit(self.minute, 'min')
|
||||||
|
|
||||||
if not minute then return end
|
if not minute then return end
|
||||||
|
|
||||||
local hour = getTimeUnit(self.hour, 'hour')
|
local hour = getTimeUnit(self.hour, 'hour')
|
||||||
|
|
||||||
if not hour then return end
|
if not hour then return end
|
||||||
|
|
||||||
if minute >= maxUnits.min then
|
if minute >= maxUnits.min then
|
||||||
if not self.hour then
|
if not self.hour then
|
||||||
hour += math.floor(minute / maxUnits.min)
|
hour += math.floor(minute / maxUnits.min)
|
||||||
end
|
end
|
||||||
|
|
||||||
minute = minute % maxUnits.min
|
minute = minute % maxUnits.min
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -272,31 +169,20 @@ function OxTask:getNextTime()
|
|||||||
if not self.day then
|
if not self.day then
|
||||||
day += math.floor(hour / maxUnits.hour)
|
day += math.floor(hour / maxUnits.hour)
|
||||||
end
|
end
|
||||||
|
|
||||||
hour = hour % maxUnits.hour
|
hour = hour % maxUnits.hour
|
||||||
end
|
end
|
||||||
|
|
||||||
local nextTime = os.time({
|
return os.time({
|
||||||
min = minute,
|
min = minute,
|
||||||
hour = hour,
|
hour = hour,
|
||||||
day = day or currentDate.day,
|
day = day or currentDate.day,
|
||||||
month = month or currentDate.month,
|
month = month or currentDate.month,
|
||||||
year = currentDate.year,
|
year = currentDate.year,
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.lastRun and nextTime - self.lastRun < 60 then
|
|
||||||
if self.debug then
|
|
||||||
lib.print.debug(('Preventing duplicate execution of task %s - Last run: %s, Next scheduled: %s'):format(
|
|
||||||
self.id,
|
|
||||||
os.date('%c', self.lastRun),
|
|
||||||
os.date('%c', nextTime)
|
|
||||||
))
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
return nextTime
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Get timestamp for next time to run task at any day.
|
||||||
---@return number
|
---@return number
|
||||||
function OxTask:getAbsoluteNextTime()
|
function OxTask:getAbsoluteNextTime()
|
||||||
local minute = getTimeUnit(self.minute, 'min')
|
local minute = getTimeUnit(self.minute, 'min')
|
||||||
@ -305,6 +191,7 @@ function OxTask:getAbsoluteNextTime()
|
|||||||
local month = getTimeUnit(self.month, 'month')
|
local month = getTimeUnit(self.month, 'month')
|
||||||
local year = getTimeUnit(self.year, 'year')
|
local year = getTimeUnit(self.year, 'year')
|
||||||
|
|
||||||
|
-- To avoid modifying getTimeUnit function, the day is adjusted here if needed.
|
||||||
if self.day then
|
if self.day then
|
||||||
if currentDate.hour < hour or (currentDate.hour == hour and currentDate.min < minute) then
|
if currentDate.hour < hour or (currentDate.hour == hour and currentDate.min < minute) then
|
||||||
day = day - 1
|
day = day - 1
|
||||||
@ -322,6 +209,7 @@ function OxTask:getAbsoluteNextTime()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Check if time will be in next year.
|
||||||
---@diagnostic disable-next-line: assign-type-mismatch
|
---@diagnostic disable-next-line: assign-type-mismatch
|
||||||
if os.time({ year = year, month = month, day = day, hour = hour, min = minute }) < os.time() then
|
if os.time({ year = year, month = month, day = day, hour = hour, min = minute }) < os.time() then
|
||||||
year = year and year + 1 or currentDate.year + 1
|
year = year and year + 1 or currentDate.year + 1
|
||||||
@ -354,50 +242,40 @@ function OxTask:scheduleTask()
|
|||||||
local sleep = runAt - currentTime
|
local sleep = runAt - currentTime
|
||||||
|
|
||||||
if sleep < 0 then
|
if sleep < 0 then
|
||||||
if not self.maxDelay or -sleep > self.maxDelay then
|
|
||||||
return self:stop(self.debug and ('scheduled time expired %s seconds ago'):format(-sleep))
|
return self:stop(self.debug and ('scheduled time expired %s seconds ago'):format(-sleep))
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.debug then
|
|
||||||
lib.print.debug(('Task %s is %s seconds overdue, executing now due to maxDelay=%s'):format(
|
|
||||||
self.id,
|
|
||||||
-sleep,
|
|
||||||
self.maxDelay
|
|
||||||
))
|
|
||||||
end
|
|
||||||
|
|
||||||
sleep = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local timeAsString = self:getTimeAsString(runAt)
|
local timeAsString = self:getTimeAsString(runAt)
|
||||||
|
|
||||||
if self.debug then
|
if self.debug then
|
||||||
lib.print.debug(('(%s) task %s will run in %d seconds (%0.2f minutes / %0.2f hours)'):format(timeAsString, self.id, sleep,
|
print(('(%s) task %s will run in %d seconds (%0.2f minutes / %0.2f hours)'):format(timeAsString, self.id, sleep,
|
||||||
sleep / 60,
|
sleep / 60,
|
||||||
sleep / 60 / 60))
|
sleep / 60 / 60))
|
||||||
end
|
end
|
||||||
|
|
||||||
if sleep > 0 then
|
if sleep > 0 then
|
||||||
Wait(sleep * 1000)
|
Wait(sleep * 1000)
|
||||||
else
|
else -- will this even happen?
|
||||||
Wait(0)
|
Wait(1000)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.isActive then
|
if self.isActive then
|
||||||
if self.debug then
|
if self.debug then
|
||||||
lib.print.debug(('(%s) running task %s'):format(timeAsString, self.id))
|
print(('(%s) running task %s'):format(timeAsString, self.id))
|
||||||
end
|
end
|
||||||
|
|
||||||
Citizen.CreateThreadNow(function()
|
Citizen.CreateThreadNow(function()
|
||||||
self:job(currentDate)
|
self:job(currentDate)
|
||||||
self.lastRun = os.time()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- Wait(30000)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Start an inactive task.
|
||||||
function OxTask:run()
|
function OxTask:run()
|
||||||
if self.isActive then return end
|
if self.isActive then return end
|
||||||
|
|
||||||
@ -413,20 +291,58 @@ function OxTask:stop(msg)
|
|||||||
|
|
||||||
if self.debug then
|
if self.debug then
|
||||||
if msg then
|
if msg then
|
||||||
return lib.print.debug(('stopping task %s (%s)'):format(self.id, msg))
|
return print(('stopping task %s (%s)'):format(self.id, msg))
|
||||||
end
|
end
|
||||||
|
|
||||||
lib.print.debug(('stopping task %s'):format(self.id))
|
print(('stopping task %s'):format(self.id))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param value string
|
||||||
|
---@return number | string | nil
|
||||||
|
local function parseCron(value, unit)
|
||||||
|
if not value or value == '*' then return end
|
||||||
|
|
||||||
|
local num = tonumber(value)
|
||||||
|
|
||||||
|
if num then return num end
|
||||||
|
|
||||||
|
if unit == 'wday' then
|
||||||
|
if value == 'sun' then return 1 end
|
||||||
|
if value == 'mon' then return 2 end
|
||||||
|
if value == 'tue' then return 3 end
|
||||||
|
if value == 'wed' then return 4 end
|
||||||
|
if value == 'thu' then return 5 end
|
||||||
|
if value == 'fri' then return 6 end
|
||||||
|
if value == 'sat' then return 7 end
|
||||||
|
end
|
||||||
|
|
||||||
|
if unit == 'month' then
|
||||||
|
if value == 'jan' then return 1 end
|
||||||
|
if value == 'feb' then return 2 end
|
||||||
|
if value == 'mar' then return 3 end
|
||||||
|
if value == 'apr' then return 4 end
|
||||||
|
if value == 'may' then return 5 end
|
||||||
|
if value == 'jun' then return 6 end
|
||||||
|
if value == 'jul' then return 7 end
|
||||||
|
if value == 'aug' then return 8 end
|
||||||
|
if value == 'sep' then return 9 end
|
||||||
|
if value == 'oct' then return 10 end
|
||||||
|
if value == 'nov' then return 11 end
|
||||||
|
if value == 'dec' then return 12 end
|
||||||
|
end
|
||||||
|
|
||||||
|
if getTimeUnit(value, unit) then return value end
|
||||||
|
|
||||||
|
error(("^1invalid cron expression. '%s' is not supported for %s^0"):format(value, unit), 3)
|
||||||
|
end
|
||||||
|
|
||||||
---@param expression string A cron expression such as `* * * * *` representing minute, hour, day, month, and day of the week.
|
---@param expression string A cron expression such as `* * * * *` representing minute, hour, day, month, and day of the week.
|
||||||
---@param job fun(task: OxTask, date: osdate)
|
---@param job fun(task: OxTask, date: osdate)
|
||||||
---@param options? { debug?: boolean }
|
---@param options? { debug?: boolean }
|
||||||
---Creates a new [cronjob](https://en.wikipedia.org/wiki/Cron), scheduling a task to run at fixed times or intervals.
|
---Creates a new [cronjob](https://en.wikipedia.org/wiki/Cron), scheduling a task to run at fixed times or intervals.
|
||||||
---Supports numbers, any value `*`, lists `1,2,3`, ranges `1-3`, and steps `*/4`.
|
---Supports numbers, any value `*`, lists `1,2,3`, ranges `1-3`, and steps `*/4`.
|
||||||
---Day of the week is a range of `1-7` starting from Sunday and allows short-names (i.e. sun, mon, tue).
|
---Day of the week is a range of `1-7` starting from Sunday and allows short-names (i.e. sun, mon, tue).
|
||||||
---@note maxDelay: Maximum allowed delay in seconds before skipping (0 to disable)
|
|
||||||
function lib.cron.new(expression, job, options)
|
function lib.cron.new(expression, job, options)
|
||||||
if not job or type(job) ~= 'function' then
|
if not job or type(job) ~= 'function' then
|
||||||
error(("expected job to have type 'function' (received %s)"):format(type(job)))
|
error(("expected job to have type 'function' (received %s)"):format(type(job)))
|
||||||
@ -444,8 +360,6 @@ function lib.cron.new(expression, job, options)
|
|||||||
task.weekday = parseCron(weekday, 'wday')
|
task.weekday = parseCron(weekday, 'wday')
|
||||||
task.id = #tasks + 1
|
task.id = #tasks + 1
|
||||||
task.job = job
|
task.job = job
|
||||||
task.lastRun = nil
|
|
||||||
task.maxDelay = task.maxDelay or 1
|
|
||||||
tasks[task.id] = task
|
tasks[task.id] = task
|
||||||
task:run()
|
task:run()
|
||||||
|
|
||||||
@ -456,6 +370,7 @@ end
|
|||||||
lib.cron.new('0 0 * * *', function()
|
lib.cron.new('0 0 * * *', function()
|
||||||
for i = 1, #tasks do
|
for i = 1, #tasks do
|
||||||
local task = tasks[i]
|
local task = tasks[i]
|
||||||
|
|
||||||
if not task.isActive then
|
if not task.isActive then
|
||||||
task:run()
|
task:run()
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,87 +0,0 @@
|
|||||||
---@class DuiProperties
|
|
||||||
---@field url string
|
|
||||||
---@field width number
|
|
||||||
---@field height number
|
|
||||||
---@field debug? boolean
|
|
||||||
|
|
||||||
---@class Dui : OxClass
|
|
||||||
---@field private private { id: string, debug: boolean }
|
|
||||||
---@field url string
|
|
||||||
---@field duiObject number
|
|
||||||
---@field duiHandle string
|
|
||||||
---@field runtimeTxd number
|
|
||||||
---@field txdObject number
|
|
||||||
---@field dictName string
|
|
||||||
---@field txtName string
|
|
||||||
lib.dui = lib.class('Dui')
|
|
||||||
|
|
||||||
---@type table<string, Dui>
|
|
||||||
local duis = {}
|
|
||||||
|
|
||||||
local currentId = 0
|
|
||||||
|
|
||||||
---@param data DuiProperties
|
|
||||||
function lib.dui:constructor(data)
|
|
||||||
local time = GetGameTimer()
|
|
||||||
local id = ("%s_%s_%s"):format(cache.resource, time, currentId)
|
|
||||||
currentId = currentId + 1
|
|
||||||
local dictName = ('ox_lib_dui_dict_%s'):format(id)
|
|
||||||
local txtName = ('ox_lib_dui_txt_%s'):format(id)
|
|
||||||
local duiObject = CreateDui(data.url, data.width, data.height)
|
|
||||||
local duiHandle = GetDuiHandle(duiObject)
|
|
||||||
local runtimeTxd = CreateRuntimeTxd(dictName)
|
|
||||||
local txdObject = CreateRuntimeTextureFromDuiHandle(runtimeTxd, txtName, duiHandle)
|
|
||||||
self.private.id = id
|
|
||||||
self.private.debug = data.debug or false
|
|
||||||
self.url = data.url
|
|
||||||
self.duiObject = duiObject
|
|
||||||
self.duiHandle = duiHandle
|
|
||||||
self.runtimeTxd = runtimeTxd
|
|
||||||
self.txdObject = txdObject
|
|
||||||
self.dictName = dictName
|
|
||||||
self.txtName = txtName
|
|
||||||
duis[id] = self
|
|
||||||
|
|
||||||
if self.private.debug then
|
|
||||||
print(('Dui %s created'):format(id))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function lib.dui:remove()
|
|
||||||
SetDuiUrl(self.duiObject, 'about:blank')
|
|
||||||
DestroyDui(self.duiObject)
|
|
||||||
duis[self.private.id] = nil
|
|
||||||
|
|
||||||
if self.private.debug then
|
|
||||||
print(('Dui %s removed'):format(self.private.id))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param url string
|
|
||||||
function lib.dui:setUrl(url)
|
|
||||||
self.url = url
|
|
||||||
SetDuiUrl(self.duiObject, url)
|
|
||||||
|
|
||||||
if self.private.debug then
|
|
||||||
print(('Dui %s url set to %s'):format(self.private.id, url))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param message table
|
|
||||||
function lib.dui:sendMessage(message)
|
|
||||||
SendDuiMessage(self.duiObject, json.encode(message))
|
|
||||||
|
|
||||||
if self.private.debug then
|
|
||||||
print(('Dui %s message sent with data :'):format(self.private.id), json.encode(message, { indent = true }))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
AddEventHandler('onResourceStop', function(resourceName)
|
|
||||||
if cache.resource ~= resourceName then return end
|
|
||||||
|
|
||||||
for _, dui in pairs(duis) do
|
|
||||||
dui:remove()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
return lib.dui
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
local glm_sincos = require 'glm'.sincos --[[@as fun(n: number): number, number]]
|
|
||||||
local glm_rad = require 'glm'.rad --[[@as fun(n: number): number]]
|
|
||||||
|
|
||||||
---Get the relative coordinates based on heading/rotation and offset
|
|
||||||
---@overload fun(coords: vector3, heading: number, offset: vector3): vector3
|
|
||||||
---@overload fun(coords: vector4, offset: vector3): vector4
|
|
||||||
---@overload fun(coords: vector3, rotation: vector3, offset: vector3): vector3
|
|
||||||
function lib.getRelativeCoords(coords, rotation, offset)
|
|
||||||
if type(rotation) == 'vector3' and offset then
|
|
||||||
local pitch = glm_rad(rotation.x)
|
|
||||||
local roll = glm_rad(rotation.y)
|
|
||||||
local yaw = glm_rad(rotation.z)
|
|
||||||
|
|
||||||
local sp, cp = glm_sincos(pitch)
|
|
||||||
local sr, cr = glm_sincos(roll)
|
|
||||||
local sy, cy = glm_sincos(yaw)
|
|
||||||
|
|
||||||
local rotatedX = offset.x * (cy * cr) + offset.y * (cy * sr * sp - sy * cp) + offset.z * (cy * sr * cp + sy * sp)
|
|
||||||
local rotatedY = offset.x * (sy * cr) + offset.y * (sy * sr * sp + cy * cp) + offset.z * (sy * sr * cp - cy * sp)
|
|
||||||
local rotatedZ = offset.x * (-sr) + offset.y * (cr * sp) + offset.z * (cr * cp)
|
|
||||||
|
|
||||||
return vec3(
|
|
||||||
coords.x + rotatedX,
|
|
||||||
coords.y + rotatedY,
|
|
||||||
coords.z + rotatedZ
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
offset = offset or rotation
|
|
||||||
local x, y, z, w = coords.x, coords.y, coords.z, type(rotation) == 'number' and rotation or coords.w
|
|
||||||
|
|
||||||
local sin, cos = glm_sincos(glm_rad(w))
|
|
||||||
local relativeX = offset.x * cos - offset.y * sin
|
|
||||||
local relativeY = offset.x * sin + offset.y * cos
|
|
||||||
|
|
||||||
return coords.w and vec4(
|
|
||||||
x + relativeX,
|
|
||||||
y + relativeY,
|
|
||||||
z + offset.z,
|
|
||||||
w
|
|
||||||
) or vec3(
|
|
||||||
x + relativeX,
|
|
||||||
y + relativeY,
|
|
||||||
z + offset.z
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
return lib.getRelativeCoords
|
|
||||||
@ -1,194 +0,0 @@
|
|||||||
--[[
|
|
||||||
Based on PolyZone's grid system (https://github.com/mkafrin/PolyZone/blob/master/ComboZone.lua)
|
|
||||||
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2019-2021 Michael Afrin
|
|
||||||
|
|
||||||
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 mapMinX = -3700
|
|
||||||
local mapMinY = -4400
|
|
||||||
local mapMaxX = 4500
|
|
||||||
local mapMaxY = 8000
|
|
||||||
local xDelta = (mapMaxX - mapMinX) / 34
|
|
||||||
local yDelta = (mapMaxY - mapMinY) / 50
|
|
||||||
local grid = {}
|
|
||||||
local lastCell = {}
|
|
||||||
local gridCache = {}
|
|
||||||
local entrySet = {}
|
|
||||||
|
|
||||||
lib.grid = {}
|
|
||||||
|
|
||||||
---@class GridEntry
|
|
||||||
---@field coords vector
|
|
||||||
---@field length? number
|
|
||||||
---@field width? number
|
|
||||||
---@field radius? number
|
|
||||||
---@field [string] any
|
|
||||||
|
|
||||||
---@param point vector
|
|
||||||
---@param length number
|
|
||||||
---@param width number
|
|
||||||
---@return number, number, number, number
|
|
||||||
local function getGridDimensions(point, length, width)
|
|
||||||
local minX = (point.x - width - mapMinX) // xDelta
|
|
||||||
local maxX = (point.x + width - mapMinX) // xDelta
|
|
||||||
local minY = (point.y - length - mapMinY) // yDelta
|
|
||||||
local maxY = (point.y + length - mapMinY) // yDelta
|
|
||||||
|
|
||||||
return minX, maxX, minY, maxY
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param point vector
|
|
||||||
---@return number, number
|
|
||||||
function lib.grid.getCellPosition(point)
|
|
||||||
local x = (point.x - mapMinX) // xDelta
|
|
||||||
local y = (point.y - mapMinY) // yDelta
|
|
||||||
|
|
||||||
return x, y
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param point vector
|
|
||||||
---@return GridEntry[]
|
|
||||||
function lib.grid.getCell(point)
|
|
||||||
local x, y = lib.grid.getCellPosition(point)
|
|
||||||
|
|
||||||
if lastCell.x ~= x or lastCell.y ~= y then
|
|
||||||
lastCell.x = x
|
|
||||||
lastCell.y = y
|
|
||||||
lastCell.cell = grid[y] and grid[y][x] or {}
|
|
||||||
end
|
|
||||||
|
|
||||||
return lastCell.cell
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param point vector
|
|
||||||
---@param filter? fun(entry: GridEntry): boolean
|
|
||||||
---@return Array<GridEntry>
|
|
||||||
function lib.grid.getNearbyEntries(point, filter)
|
|
||||||
local minX, maxX, minY, maxY = getGridDimensions(point, xDelta, yDelta)
|
|
||||||
|
|
||||||
if gridCache.filter == filter and
|
|
||||||
gridCache.minX == minX and
|
|
||||||
gridCache.maxX == maxX and
|
|
||||||
gridCache.minY == minY and
|
|
||||||
gridCache.maxY == maxY then
|
|
||||||
return gridCache.entries
|
|
||||||
end
|
|
||||||
|
|
||||||
local entries = lib.array:new()
|
|
||||||
local n = 0
|
|
||||||
|
|
||||||
table.wipe(entrySet)
|
|
||||||
|
|
||||||
for y = minY, maxY do
|
|
||||||
local row = grid[y]
|
|
||||||
|
|
||||||
for x = minX, maxX do
|
|
||||||
local cell = row and row[x]
|
|
||||||
|
|
||||||
if cell then
|
|
||||||
for j = 1, #cell do
|
|
||||||
local entry = cell[j]
|
|
||||||
|
|
||||||
if not entrySet[entry] and (not filter or filter(entry)) then
|
|
||||||
n = n + 1
|
|
||||||
entrySet[entry] = true
|
|
||||||
entries[n] = entry
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
gridCache.minX = minX
|
|
||||||
gridCache.maxX = maxX
|
|
||||||
gridCache.minY = minY
|
|
||||||
gridCache.maxY = maxY
|
|
||||||
gridCache.entries = entries
|
|
||||||
gridCache.filter = filter
|
|
||||||
|
|
||||||
return entries
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param entry { coords: vector, length?: number, width?: number, radius?: number, [string]: any }
|
|
||||||
function lib.grid.addEntry(entry)
|
|
||||||
entry.length = entry.length or entry.radius * 2
|
|
||||||
entry.width = entry.width or entry.radius * 2
|
|
||||||
local minX, maxX, minY, maxY = getGridDimensions(entry.coords, entry.length, entry.width)
|
|
||||||
|
|
||||||
for y = minY, maxY do
|
|
||||||
local row = grid[y] or {}
|
|
||||||
|
|
||||||
for x = minX, maxX do
|
|
||||||
local cell = row[x] or {}
|
|
||||||
|
|
||||||
cell[#cell + 1] = entry
|
|
||||||
row[x] = cell
|
|
||||||
end
|
|
||||||
|
|
||||||
grid[y] = row
|
|
||||||
|
|
||||||
table.wipe(gridCache)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param entry table A table that was added to the grid previously.
|
|
||||||
function lib.grid.removeEntry(entry)
|
|
||||||
local minX, maxX, minY, maxY = getGridDimensions(entry.coords, entry.length, entry.width)
|
|
||||||
local success = false
|
|
||||||
|
|
||||||
for y = minY, maxY do
|
|
||||||
local row = grid[y]
|
|
||||||
|
|
||||||
if not row then goto continue end
|
|
||||||
|
|
||||||
for x = minX, maxX do
|
|
||||||
local cell = row[x]
|
|
||||||
|
|
||||||
if cell then
|
|
||||||
for i = 1, #cell do
|
|
||||||
if cell[i] == entry then
|
|
||||||
table.remove(cell, i)
|
|
||||||
success = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if #cell == 0 then
|
|
||||||
row[x] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not next(row) then
|
|
||||||
grid[y] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
::continue::
|
|
||||||
end
|
|
||||||
|
|
||||||
table.wipe(gridCache)
|
|
||||||
|
|
||||||
return success
|
|
||||||
end
|
|
||||||
|
|
||||||
return lib.grid
|
|
||||||
@ -5,6 +5,9 @@ local defaultRotation = vector3(0, 0, 0)
|
|||||||
local defaultDirection = vector3(0, 0, 0)
|
local defaultDirection = vector3(0, 0, 0)
|
||||||
local defaultColor = { r = 255, g = 255, b = 255, a = 100 }
|
local defaultColor = { r = 255, g = 255, b = 255, a = 100 }
|
||||||
local defaultSize = { width = 2, height = 1 }
|
local defaultSize = { width = 2, height = 1 }
|
||||||
|
local defaultBobUpAndDown = false
|
||||||
|
local defaultFaceCamera = true
|
||||||
|
local defaultRotate = false
|
||||||
local defaultTextureDict = nil
|
local defaultTextureDict = nil
|
||||||
local defaultTextureName = nil
|
local defaultTextureName = nil
|
||||||
|
|
||||||
@ -149,9 +152,9 @@ function lib.marker.new(options)
|
|||||||
self.height = options.height or defaultSize.height
|
self.height = options.height or defaultSize.height
|
||||||
self.rotation = options.rotation or defaultRotation
|
self.rotation = options.rotation or defaultRotation
|
||||||
self.direction = options.direction or defaultDirection
|
self.direction = options.direction or defaultDirection
|
||||||
self.bobUpAndDown = type(options.bobUpAndDown) == 'boolean' and options.bobUpAndDown
|
self.bobUpAndDown = options.bobUpAndDown or defaultBobUpAndDown
|
||||||
self.faceCamera = type(options.faceCamera) ~= 'boolean' or options.faceCamera
|
self.faceCamera = options.faceCamera or defaultFaceCamera
|
||||||
self.rotate = type(options.rotate) == 'boolean' and options.rotate
|
self.rotate = options.rotate or defaultRotate
|
||||||
self.textureDict = options.textureDict or defaultTextureDict
|
self.textureDict = options.textureDict or defaultTextureDict
|
||||||
self.textureName = options.textureName or defaultTextureName
|
self.textureName = options.textureName or defaultTextureName
|
||||||
self.draw = drawMarker
|
self.draw = drawMarker
|
||||||
|
|||||||
@ -26,8 +26,6 @@ local function removePoint(self)
|
|||||||
closestPoint = nil
|
closestPoint = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
lib.grid.removeEntry(self)
|
|
||||||
|
|
||||||
points[self.id] = nil
|
points[self.id] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -39,41 +37,25 @@ CreateThread(function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local coords = GetEntityCoords(cache.ped)
|
local coords = GetEntityCoords(cache.ped)
|
||||||
local newPoints = lib.grid.getNearbyEntries(coords, function(entry) return entry.remove == removePoint end) --[[@as CPoint[] ]]
|
|
||||||
local cellX, cellY = lib.grid.getCellPosition(coords)
|
|
||||||
cache.coords = coords
|
cache.coords = coords
|
||||||
|
|
||||||
|
if closestPoint and #(coords - closestPoint.coords) > closestPoint.distance then
|
||||||
closestPoint = nil
|
closestPoint = nil
|
||||||
|
end
|
||||||
|
|
||||||
if cellX ~= cache.lastCellX or cellY ~= cache.lastCellY then
|
for _, point in pairs(points) do
|
||||||
for i = 1, #nearbyPoints do
|
|
||||||
local point = nearbyPoints[i]
|
|
||||||
|
|
||||||
if point.inside then
|
|
||||||
local distance = #(coords - point.coords)
|
local distance = #(coords - point.coords)
|
||||||
|
|
||||||
if distance > point.radius then
|
if distance <= point.distance then
|
||||||
if point.onExit then point:onExit() end
|
|
||||||
|
|
||||||
point.inside = nil
|
|
||||||
point.currentDistance = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
cache.lastCellX = cellX
|
|
||||||
cache.lastCellY = cellY
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, #newPoints do
|
|
||||||
local point = newPoints[i]
|
|
||||||
local distance = #(coords - point.coords)
|
|
||||||
|
|
||||||
if distance <= point.radius then
|
|
||||||
point.currentDistance = distance
|
point.currentDistance = distance
|
||||||
|
|
||||||
if not closestPoint or distance < (closestPoint.currentDistance or point.radius) then
|
if closestPoint then
|
||||||
if closestPoint then closestPoint.isClosest = nil end
|
if distance < closestPoint.currentDistance then
|
||||||
|
closestPoint.isClosest = nil
|
||||||
|
point.isClosest = true
|
||||||
|
closestPoint = point
|
||||||
|
end
|
||||||
|
elseif distance < point.distance then
|
||||||
point.isClosest = true
|
point.isClosest = true
|
||||||
closestPoint = point
|
closestPoint = point
|
||||||
end
|
end
|
||||||
@ -89,7 +71,6 @@ CreateThread(function()
|
|||||||
end
|
end
|
||||||
elseif point.currentDistance then
|
elseif point.currentDistance then
|
||||||
if point.onExit then point:onExit() end
|
if point.onExit then point:onExit() end
|
||||||
|
|
||||||
point.inside = nil
|
point.inside = nil
|
||||||
point.currentDistance = nil
|
point.currentDistance = nil
|
||||||
end
|
end
|
||||||
@ -98,10 +79,10 @@ CreateThread(function()
|
|||||||
if not tick then
|
if not tick then
|
||||||
if nearbyCount ~= 0 then
|
if nearbyCount ~= 0 then
|
||||||
tick = SetInterval(function()
|
tick = SetInterval(function()
|
||||||
for i = nearbyCount, 1, -1 do
|
for i = 1, nearbyCount do
|
||||||
local point = nearbyPoints[i]
|
local point = nearbyPoints[i]
|
||||||
|
|
||||||
if point and point.nearby then
|
if point then
|
||||||
point:nearby()
|
point:nearby()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -129,13 +110,12 @@ local function toVector(coords)
|
|||||||
return coords
|
return coords
|
||||||
end
|
end
|
||||||
|
|
||||||
lib.points = {}
|
lib.points = {
|
||||||
|
---@return CPoint
|
||||||
---@return CPoint
|
---@overload fun(data: PointProperties): CPoint
|
||||||
---@overload fun(data: PointProperties): CPoint
|
---@overload fun(coords: vector3, distance: number, data?: PointProperties): CPoint
|
||||||
---@overload fun(coords: vector3, distance: number, data?: PointProperties): CPoint
|
new = function(...)
|
||||||
function lib.points.new(...)
|
local args = {...}
|
||||||
local args = { ... }
|
|
||||||
local id = #points + 1
|
local id = #points + 1
|
||||||
local self
|
local self
|
||||||
|
|
||||||
@ -155,7 +135,6 @@ function lib.points.new(...)
|
|||||||
|
|
||||||
self.coords = toVector(self.coords)
|
self.coords = toVector(self.coords)
|
||||||
self.distance = self.distance or args[2]
|
self.distance = self.distance or args[2]
|
||||||
self.radius = self.distance
|
|
||||||
|
|
||||||
if args[3] then
|
if args[3] then
|
||||||
for k, v in pairs(args[3]) do
|
for k, v in pairs(args[3]) do
|
||||||
@ -163,18 +142,18 @@ function lib.points.new(...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
lib.grid.addEntry(self)
|
|
||||||
points[id] = self
|
points[id] = self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end,
|
||||||
|
|
||||||
function lib.points.getAllPoints() return points end
|
getAllPoints = function() return points end,
|
||||||
|
|
||||||
function lib.points.getNearbyPoints() return nearbyPoints end
|
getNearbyPoints = function() return nearbyPoints end,
|
||||||
|
|
||||||
---@return CPoint?
|
---@return CPoint?
|
||||||
function lib.points.getClosestPoint() return closestPoint end
|
getClosestPoint = function() return closestPoint end,
|
||||||
|
}
|
||||||
|
|
||||||
---@deprecated
|
---@deprecated
|
||||||
lib.points.closest = lib.points.getClosestPoint
|
lib.points.closest = lib.points.getClosestPoint
|
||||||
|
|||||||
@ -14,12 +14,8 @@ local levelPrefixes = {
|
|||||||
'^4[VERBOSE]',
|
'^4[VERBOSE]',
|
||||||
'^6[DEBUG]',
|
'^6[DEBUG]',
|
||||||
}
|
}
|
||||||
local convarGlobal = 'ox:printlevel'
|
|
||||||
local convarResource = 'ox:printlevel:' .. cache.resource
|
local resourcePrintLevel = printLevel[GetConvar('ox:printlevel:' .. cache.resource, GetConvar('ox:printlevel', 'info'))]
|
||||||
local function getPrintLevelFromConvar()
|
|
||||||
return printLevel[GetConvar(convarResource, GetConvar(convarGlobal, 'info'))]
|
|
||||||
end
|
|
||||||
local resourcePrintLevel = getPrintLevelFromConvar()
|
|
||||||
local template = ('^5[%s] %%s %%s^7'):format(cache.resource)
|
local template = ('^5[%s] %%s %%s^7'):format(cache.resource)
|
||||||
local function handleException(reason, value)
|
local function handleException(reason, value)
|
||||||
if type(value) == 'function' then return tostring(value) end
|
if type(value) == 'function' then return tostring(value) end
|
||||||
@ -52,14 +48,4 @@ lib.print = {
|
|||||||
debug = function(...) libPrint(printLevel.debug, ...) end,
|
debug = function(...) libPrint(printLevel.debug, ...) end,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Update the print level when the convar changes
|
|
||||||
if (AddConvarChangeListener) then
|
|
||||||
AddConvarChangeListener('ox:printlevel*', function(convarName, reserved)
|
|
||||||
if (convarName ~= convarResource and convarName ~= convarGlobal) then return end
|
|
||||||
resourcePrintLevel = getPrintLevelFromConvar()
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
libPrint(printLevel.verbose, 'Convar change listener not available, print level will not update dynamically.')
|
|
||||||
end
|
|
||||||
|
|
||||||
return lib.print
|
return lib.print
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
function lib.requestAudioBank(audioBank, timeout)
|
function lib.requestAudioBank(audioBank, timeout)
|
||||||
return lib.waitFor(function()
|
return lib.waitFor(function()
|
||||||
if RequestScriptAudioBank(audioBank, false) then return audioBank end
|
if RequestScriptAudioBank(audioBank, false) then return audioBank end
|
||||||
end, ("failed to load audiobank '%s' - this may be caused by\n- too many loaded assets\n- oversized, invalid, or corrupted assets"):format(audioBank), timeout or 30000)
|
end, ("failed to load audiobank '%s'"):format(audioBank), timeout or 500)
|
||||||
end
|
end
|
||||||
|
|
||||||
return lib.requestAudioBank
|
return lib.requestAudioBank
|
||||||
|
|||||||
@ -1,224 +0,0 @@
|
|||||||
---@class renderTargetTable
|
|
||||||
---@field name string
|
|
||||||
---@field model string | number
|
|
||||||
|
|
||||||
---@class detailsTable
|
|
||||||
---@field name string
|
|
||||||
---@field fullScreen? boolean
|
|
||||||
---@field x? number
|
|
||||||
---@field y? number
|
|
||||||
---@field width? number
|
|
||||||
---@field height? number
|
|
||||||
---@field renderTarget? renderTargetTable
|
|
||||||
|
|
||||||
---@class Scaleform : OxClass
|
|
||||||
---@field scaleform number
|
|
||||||
---@field draw boolean
|
|
||||||
---@field target number
|
|
||||||
---@field targetName string
|
|
||||||
---@field sfHandle? number
|
|
||||||
---@field fullScreen boolean
|
|
||||||
---@field private private { isDrawing: boolean }
|
|
||||||
lib.scaleform = lib.class('Scaleform')
|
|
||||||
|
|
||||||
--- Converts the arguments into data types usable by scaleform
|
|
||||||
---@param argsTable (number | string | boolean)[]
|
|
||||||
local function convertArgs(argsTable)
|
|
||||||
for i = 1, #argsTable do
|
|
||||||
local arg = argsTable[i]
|
|
||||||
local argType = type(arg)
|
|
||||||
|
|
||||||
if argType == 'string' then
|
|
||||||
ScaleformMovieMethodAddParamPlayerNameString(arg)
|
|
||||||
elseif argType == 'number' then
|
|
||||||
if math.type(arg) == 'integer' then
|
|
||||||
ScaleformMovieMethodAddParamInt(arg)
|
|
||||||
else
|
|
||||||
ScaleformMovieMethodAddParamFloat(arg)
|
|
||||||
end
|
|
||||||
elseif argType == 'boolean' then
|
|
||||||
ScaleformMovieMethodAddParamBool(arg)
|
|
||||||
else
|
|
||||||
error(('Unsupported Parameter type [%s]'):format(argType))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param expectedType 'boolean' | 'integer' | 'string'
|
|
||||||
---@return boolean | integer | string
|
|
||||||
local function retrieveReturnValue(expectedType)
|
|
||||||
local result = EndScaleformMovieMethodReturnValue()
|
|
||||||
|
|
||||||
lib.waitFor(function()
|
|
||||||
if IsScaleformMovieMethodReturnValueReady(result) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end, "Failed to retrieve return value", 1000)
|
|
||||||
|
|
||||||
if expectedType == "integer" then
|
|
||||||
return GetScaleformMovieMethodReturnValueInt(result)
|
|
||||||
elseif expectedType == "boolean" then
|
|
||||||
return GetScaleformMovieMethodReturnValueBool(result)
|
|
||||||
else
|
|
||||||
return GetScaleformMovieMethodReturnValueString(result)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param details detailsTable | string
|
|
||||||
---@return nil
|
|
||||||
function lib.scaleform:constructor(details)
|
|
||||||
details = type(details) == 'table' and details or { name = details }
|
|
||||||
|
|
||||||
local scaleform = lib.requestScaleformMovie(details.name)
|
|
||||||
|
|
||||||
self.sfHandle = scaleform
|
|
||||||
self.private.isDrawing = false
|
|
||||||
|
|
||||||
self.fullScreen = details.fullScreen or false
|
|
||||||
self.x = details.x or 0
|
|
||||||
self.y = details.y or 0
|
|
||||||
self.width = details.width or 0
|
|
||||||
self.height = details.height or 0
|
|
||||||
|
|
||||||
if details.renderTarget then
|
|
||||||
self:setRenderTarget(details.renderTarget.name, details.renderTarget.model)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
---@param args? (number | string | boolean)[]
|
|
||||||
---@param returnValue? string
|
|
||||||
---@return any
|
|
||||||
function lib.scaleform:callMethod(name, args, returnValue)
|
|
||||||
if not self.sfHandle then
|
|
||||||
return error("attempted to call method with invalid scaleform handle")
|
|
||||||
end
|
|
||||||
|
|
||||||
BeginScaleformMovieMethod(self.sfHandle, name)
|
|
||||||
|
|
||||||
if args and type(args) == 'table' then
|
|
||||||
convertArgs(args)
|
|
||||||
end
|
|
||||||
|
|
||||||
if returnValue then
|
|
||||||
return retrieveReturnValue(returnValue)
|
|
||||||
end
|
|
||||||
|
|
||||||
EndScaleformMovieMethod()
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param isFullscreen boolean
|
|
||||||
---@return nil
|
|
||||||
function lib.scaleform:setFullScreen(isFullscreen)
|
|
||||||
self.fullScreen = isFullscreen
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param x number
|
|
||||||
---@param y number
|
|
||||||
---@param width number
|
|
||||||
---@param height number
|
|
||||||
---@return nil
|
|
||||||
function lib.scaleform:setProperties(x, y, width, height)
|
|
||||||
if self.fullScreen then
|
|
||||||
lib.print.info('Cannot set properties when full screen is enabled')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
self.width = width
|
|
||||||
self.height = height
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
---@param model string|number
|
|
||||||
---@return nil
|
|
||||||
function lib.scaleform:setRenderTarget(name, model)
|
|
||||||
if self.target then
|
|
||||||
ReleaseNamedRendertarget(self.targetName)
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(model) == 'string' then
|
|
||||||
model = joaat(model)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not IsNamedRendertargetRegistered(name) then
|
|
||||||
RegisterNamedRendertarget(name, false)
|
|
||||||
|
|
||||||
if not IsNamedRendertargetLinked(model) then
|
|
||||||
LinkNamedRendertarget(model)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.target = GetNamedRendertargetRenderId(name)
|
|
||||||
self.targetName = name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function lib.scaleform:isDrawing()
|
|
||||||
return self.private.isDrawing
|
|
||||||
end
|
|
||||||
|
|
||||||
function lib.scaleform:draw()
|
|
||||||
if self.target then
|
|
||||||
SetTextRenderId(self.target)
|
|
||||||
SetScriptGfxDrawOrder(4)
|
|
||||||
SetScriptGfxDrawBehindPausemenu(true)
|
|
||||||
SetScaleformFitRendertarget(self.sfHandle, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.fullScreen then
|
|
||||||
DrawScaleformMovieFullscreen(self.sfHandle, 255, 255, 255, 255, 0)
|
|
||||||
else
|
|
||||||
if not self.x or not self.y or not self.width or not self.height then
|
|
||||||
error('attempted to draw scaleform without setting properties')
|
|
||||||
else
|
|
||||||
DrawScaleformMovie(self.sfHandle, self.x, self.y, self.width, self.height, 255, 255, 255, 255, 0)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.target then
|
|
||||||
SetTextRenderId(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function lib.scaleform:startDrawing()
|
|
||||||
if self.private.isDrawing then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
self.private.isDrawing = true
|
|
||||||
|
|
||||||
CreateThread(function()
|
|
||||||
while self:isDrawing() do
|
|
||||||
self:draw()
|
|
||||||
Wait(0)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
---@return nil
|
|
||||||
function lib.scaleform:stopDrawing()
|
|
||||||
if not self.private.isDrawing then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
self.private.isDrawing = false
|
|
||||||
end
|
|
||||||
|
|
||||||
---@return nil
|
|
||||||
function lib.scaleform:dispose()
|
|
||||||
if self.sfHandle then
|
|
||||||
SetScaleformMovieAsNoLongerNeeded(self.sfHandle)
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.target then
|
|
||||||
ReleaseNamedRendertarget(self.targetName)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.sfHandle = nil
|
|
||||||
self.target = nil
|
|
||||||
self.private.isDrawing = false
|
|
||||||
end
|
|
||||||
|
|
||||||
---@return Scaleform
|
|
||||||
return lib.scaleform
|
|
||||||
@ -12,10 +12,12 @@ function lib.streamingRequest(request, hasLoaded, assetType, asset, timeout, ...
|
|||||||
|
|
||||||
request(asset, ...)
|
request(asset, ...)
|
||||||
|
|
||||||
|
-- i hate fivem developers
|
||||||
|
lib.print.verbose(("Loading %s '%s' - remember to release it when done."):format(assetType, asset))
|
||||||
|
|
||||||
return lib.waitFor(function()
|
return lib.waitFor(function()
|
||||||
if hasLoaded(asset) then return asset end
|
if hasLoaded(asset) then return asset end
|
||||||
end, ("failed to load %s '%s' - this may be caused by\n- too many loaded assets\n- oversized, invalid, or corrupted assets"):format(assetType, asset),
|
end, ("failed to load %s '%s' - this is likely caused by unreleased assets"):format(assetType, asset), timeout or 10000)
|
||||||
timeout or 30000)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return lib.streamingRequest
|
return lib.streamingRequest
|
||||||
|
|||||||
@ -11,27 +11,22 @@ local pairs = pairs
|
|||||||
local function contains(tbl, value)
|
local function contains(tbl, value)
|
||||||
if type(value) ~= 'table' then
|
if type(value) ~= 'table' then
|
||||||
for _, v in pairs(tbl) do
|
for _, v in pairs(tbl) do
|
||||||
if v == value then
|
if v == value then return true end
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
else
|
else
|
||||||
local set = {}
|
local matched_values = 0
|
||||||
|
local values = 0
|
||||||
|
for _, v1 in pairs(value) do
|
||||||
|
values += 1
|
||||||
|
|
||||||
for _, v in pairs(tbl) do
|
for _, v2 in pairs(tbl) do
|
||||||
set[v] = true
|
if v1 == v2 then matched_values += 1 end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if matched_values == values then return true end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, v in pairs(value) do
|
|
||||||
if not set[v] then
|
|
||||||
return false
|
return false
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param t1 any
|
---@param t1 any
|
||||||
@ -39,25 +34,19 @@ end
|
|||||||
---@return boolean
|
---@return boolean
|
||||||
---Compares if two values are equal, iterating over tables and matching both keys and values.
|
---Compares if two values are equal, iterating over tables and matching both keys and values.
|
||||||
local function table_matches(t1, t2)
|
local function table_matches(t1, t2)
|
||||||
local tabletype1 = table.type(t1)
|
local type1, type2 = type(t1), type(t2)
|
||||||
|
|
||||||
if not tabletype1 then return t1 == t2 end
|
if type1 ~= type2 then return false end
|
||||||
|
if type1 ~= 'table' and type2 ~= 'table' then return t1 == t2 end
|
||||||
|
|
||||||
if tabletype1 ~= table.type(t2) or (tabletype1 == 'array' and #t1 ~= #t2) then
|
for k1,v1 in pairs(t1) do
|
||||||
return false
|
local v2 = t2[k1]
|
||||||
|
if v2 == nil or not table_matches(v1,v2) then return false end
|
||||||
end
|
end
|
||||||
|
|
||||||
for k, v1 in pairs(t1) do
|
for k2,v2 in pairs(t2) do
|
||||||
local v2 = t2[k]
|
local v1 = t1[k2]
|
||||||
if v2 == nil or not table_matches(v1, v2) then
|
if v1 == nil or not table_matches(v1,v2) then return false end
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for k in pairs(t2) do
|
|
||||||
if t1[k] == nil then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -85,41 +74,27 @@ end
|
|||||||
---@return table
|
---@return table
|
||||||
---Merges two tables together. Defaults to adding duplicate keys together if they are numbers, otherwise they are overriden.
|
---Merges two tables together. Defaults to adding duplicate keys together if they are numbers, otherwise they are overriden.
|
||||||
local function table_merge(t1, t2, addDuplicateNumbers)
|
local function table_merge(t1, t2, addDuplicateNumbers)
|
||||||
addDuplicateNumbers = addDuplicateNumbers == nil or addDuplicateNumbers
|
if addDuplicateNumbers == nil then addDuplicateNumbers = true end
|
||||||
for k, v2 in pairs(t2) do
|
for k, v in pairs(t2) do
|
||||||
local v1 = t1[k]
|
local type1 = type(t1[k])
|
||||||
local type1 = type(v1)
|
local type2 = type(v)
|
||||||
local type2 = type(v2)
|
|
||||||
|
|
||||||
if type1 == 'table' and type2 == 'table' then
|
if type1 == 'table' and type2 == 'table' then
|
||||||
table_merge(v1, v2, addDuplicateNumbers)
|
table_merge(t1[k], v, addDuplicateNumbers)
|
||||||
elseif addDuplicateNumbers and (type1 == 'number' and type2 == 'number') then
|
elseif addDuplicateNumbers and (type1 == 'number' and type2 == 'number') then
|
||||||
t1[k] = v1 + v2
|
t1[k] += v
|
||||||
else
|
else
|
||||||
t1[k] = v2
|
t1[k] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return t1
|
return t1
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param tbl table
|
|
||||||
---@return table
|
|
||||||
---Shuffles the elements of a table randomly using the Fisher-Yates algorithm.
|
|
||||||
local function shuffle(tbl)
|
|
||||||
local len = #tbl
|
|
||||||
for i = len, 2, -1 do
|
|
||||||
local j = math.random(i)
|
|
||||||
tbl[i], tbl[j] = tbl[j], tbl[i]
|
|
||||||
end
|
|
||||||
return tbl
|
|
||||||
end
|
|
||||||
|
|
||||||
table.contains = contains
|
table.contains = contains
|
||||||
table.matches = table_matches
|
table.matches = table_matches
|
||||||
table.deepclone = table_deepclone
|
table.deepclone = table_deepclone
|
||||||
table.merge = table_merge
|
table.merge = table_merge
|
||||||
table.shuffle = shuffle
|
|
||||||
|
|
||||||
local frozenNewIndex = function(self) error(('cannot set values on a frozen table (%s)'):format(self), 2) end
|
local frozenNewIndex = function(self) error(('cannot set values on a frozen table (%s)'):format(self), 2) end
|
||||||
local _rawset = rawset
|
local _rawset = rawset
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---@class TimerPrivateProps
|
---@class TimerPrivateProps
|
||||||
---@field initialTime number the initial duration of the timer.
|
---@field initialTime number the initial duration of the timer.
|
||||||
|
---@field onEnd? fun() cb function triggered when the timer finishes
|
||||||
---@field async? boolean wether the timer should run asynchronously or not
|
---@field async? boolean wether the timer should run asynchronously or not
|
||||||
---@field startTime number the gametimer stamp of when the timer starts. changes when paused and played
|
---@field startTime number the gametimer stamp of when the timer starts. changes when paused and played
|
||||||
---@field triggerOnEnd boolean set in the forceEnd method using the optional param. wether or not the onEnd function is triggered when force ending the timer early
|
---@field triggerOnEnd boolean set in the forceEnd method using the optional param. wether or not the onEnd function is triggered when force ending the timer early
|
||||||
@ -9,7 +10,6 @@
|
|||||||
---@class OxTimer : OxClass
|
---@class OxTimer : OxClass
|
||||||
---@field private private TimerPrivateProps
|
---@field private private TimerPrivateProps
|
||||||
---@field start fun(self: self, async?: boolean) starts the timer
|
---@field start fun(self: self, async?: boolean) starts the timer
|
||||||
---@field onEnd? fun() cb function triggered when the timer finishes
|
|
||||||
---@field forceEnd fun(self: self, triggerOnEnd: boolean) end timer early and optionally trigger the onEnd function still
|
---@field forceEnd fun(self: self, triggerOnEnd: boolean) end timer early and optionally trigger the onEnd function still
|
||||||
---@field isPaused fun(self: self): boolean returns wether the timer is paused or not
|
---@field isPaused fun(self: self): boolean returns wether the timer is paused or not
|
||||||
---@field pause fun(self: self) pauses the timer until play method is called
|
---@field pause fun(self: self) pauses the timer until play method is called
|
||||||
@ -26,54 +26,58 @@ function timer:constructor(time, onEnd, async)
|
|||||||
assert(onEnd == nil or type(onEnd) == "function", "onEnd must be a function or nil")
|
assert(onEnd == nil or type(onEnd) == "function", "onEnd must be a function or nil")
|
||||||
assert(type(async) == "boolean" or async == nil, "async must be a boolean or nil")
|
assert(type(async) == "boolean" or async == nil, "async must be a boolean or nil")
|
||||||
|
|
||||||
self.onEnd = onEnd
|
|
||||||
self.private.initialTime = time
|
self.private.initialTime = time
|
||||||
self.private.currentTimeLeft = time
|
self.private.currentTimeLeft = time
|
||||||
self.private.startTime = 0
|
self.private.startTime = 0
|
||||||
self.private.paused = false
|
self.private.paused = false
|
||||||
|
self.private.onEnd = onEnd
|
||||||
self.private.triggerOnEnd = true
|
self.private.triggerOnEnd = true
|
||||||
|
|
||||||
self:start(async)
|
self:start(async)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@protected
|
|
||||||
function timer:run()
|
|
||||||
while self:isPaused() or self:getTimeLeft('ms') > 0 do
|
|
||||||
Wait(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.private.triggerOnEnd then
|
|
||||||
self:onEnd()
|
|
||||||
end
|
|
||||||
|
|
||||||
self.private.triggerOnEnd = true
|
|
||||||
end
|
|
||||||
|
|
||||||
function timer:start(async)
|
function timer:start(async)
|
||||||
if self.private.startTime > 0 then error('Cannot start a timer that is already running') end
|
if self.private.startTime > 0 then return end
|
||||||
|
|
||||||
self.private.startTime = GetGameTimer()
|
self.private.startTime = GetGameTimer()
|
||||||
|
|
||||||
if not async then return self:run() end
|
local function tick()
|
||||||
|
while self:getTimeLeft('ms') > 0 do
|
||||||
|
while self:isPaused() do
|
||||||
|
Wait(0)
|
||||||
|
end
|
||||||
|
Wait(0)
|
||||||
|
end
|
||||||
|
self:onEnd()
|
||||||
|
end
|
||||||
|
|
||||||
|
if async then
|
||||||
Citizen.CreateThreadNow(function()
|
Citizen.CreateThreadNow(function()
|
||||||
self:run()
|
tick()
|
||||||
end)
|
end)
|
||||||
|
else
|
||||||
|
tick()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function timer:onEnd()
|
||||||
|
if self:getTimeLeft('ms') > 0 then return end
|
||||||
|
|
||||||
|
if self.private.triggerOnEnd and self.private.onEnd then
|
||||||
|
self.private:onEnd()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function timer:forceEnd(triggerOnEnd)
|
function timer:forceEnd(triggerOnEnd)
|
||||||
if self:getTimeLeft('ms') <= 0 then return end
|
if self:getTimeLeft('ms') <= 0 then return end
|
||||||
|
self.private.triggerOnEnd = triggerOnEnd
|
||||||
self.private.paused = false
|
self.private.paused = false
|
||||||
self.private.currentTimeLeft = 0
|
self.private.currentTimeLeft = 0
|
||||||
self.private.triggerOnEnd = triggerOnEnd
|
|
||||||
|
|
||||||
Wait(0)
|
Wait(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
function timer:pause()
|
function timer:pause()
|
||||||
if self.private.paused then return end
|
if self.private.paused then return end
|
||||||
|
|
||||||
self.private.currentTimeLeft = self:getTimeLeft('ms') --[[@as number]]
|
self.private.currentTimeLeft = self:getTimeLeft('ms') --[[@as number]]
|
||||||
self.private.paused = true
|
self.private.paused = true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,20 +1,19 @@
|
|||||||
local glm = require 'glm'
|
local glm = require 'glm'
|
||||||
|
|
||||||
---@class ZoneProperties
|
---@class CZone
|
||||||
---@field debug? boolean
|
---@field id number
|
||||||
---@field debugColour? vector4
|
---@field coords vector3
|
||||||
|
---@field distance number
|
||||||
|
---@field __type 'poly' | 'sphere' | 'box'
|
||||||
|
---@field debugColour vector4?
|
||||||
|
---@field setDebug fun(self: CZone, enable?: boolean, colour?: vector)
|
||||||
|
---@field remove fun()
|
||||||
|
---@field contains fun(self: CZone, coords?: vector3): boolean
|
||||||
---@field onEnter fun(self: CZone)?
|
---@field onEnter fun(self: CZone)?
|
||||||
---@field onExit fun(self: CZone)?
|
---@field onExit fun(self: CZone)?
|
||||||
---@field inside fun(self: CZone)?
|
---@field inside fun(self: CZone)?
|
||||||
---@field [string] any
|
---@field [string] any
|
||||||
|
|
||||||
---@class CZone : PolyZone, BoxZone, SphereZone
|
|
||||||
---@field id number
|
|
||||||
---@field __type 'poly' | 'sphere' | 'box'
|
|
||||||
---@field remove fun(self: self)
|
|
||||||
---@field setDebug fun(self: CZone, enable?: boolean, colour?: vector)
|
|
||||||
---@field contains fun(self: CZone, coords?: vector3, updateDistance?: boolean): boolean
|
|
||||||
|
|
||||||
---@type table<number, CZone>
|
---@type table<number, CZone>
|
||||||
local Zones = {}
|
local Zones = {}
|
||||||
_ENV.Zones = Zones
|
_ENV.Zones = Zones
|
||||||
@ -97,66 +96,46 @@ local function getTriangles(polygon)
|
|||||||
return triangles
|
return triangles
|
||||||
end
|
end
|
||||||
|
|
||||||
local insideZones = lib.context == 'client' and {} --[[@as table<number, CZone>]]
|
---@type table<number, CZone>
|
||||||
local exitingZones = lib.context == 'client' and lib.array:new() --[[@as Array<CZone>]]
|
local insideZones = {}
|
||||||
local enteringZones = lib.context == 'client' and lib.array:new() --[[@as Array<CZone>]]
|
---@type table<number, CZone>
|
||||||
local nearbyZones = lib.array:new() --[[@as Array<CZone>]]
|
local enteringZones = {}
|
||||||
local glm_polygon_contains = glm.polygon.contains
|
---@type table<number, CZone>
|
||||||
|
local exitingZones = {}
|
||||||
|
local enteringSize = 0
|
||||||
|
local exitingSize = 0
|
||||||
local tick
|
local tick
|
||||||
|
local glm_polygon_contains = glm.polygon.contains
|
||||||
|
|
||||||
---@param zone CZone
|
local function removeZone(self)
|
||||||
local function removeZone(zone)
|
Zones[self.id] = nil
|
||||||
Zones[zone.id] = nil
|
insideZones[self.id] = nil
|
||||||
|
enteringZones[self.id] = nil
|
||||||
lib.grid.removeEntry(zone)
|
exitingZones[self.id] = nil
|
||||||
|
|
||||||
if lib.context == 'server' then return end
|
|
||||||
|
|
||||||
insideZones[zone.id] = nil
|
|
||||||
|
|
||||||
table.remove(exitingZones, exitingZones:indexOf(zone))
|
|
||||||
table.remove(enteringZones, enteringZones:indexOf(zone))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
if lib.context == 'server' then return end
|
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local coords = GetEntityCoords(cache.ped)
|
local coords = GetEntityCoords(cache.ped)
|
||||||
local zones = lib.grid.getNearbyEntries(coords, function(entry) return entry.remove == removeZone end) --[[@as Array<CZone>]]
|
|
||||||
local cellX, cellY = lib.grid.getCellPosition(coords)
|
|
||||||
cache.coords = coords
|
cache.coords = coords
|
||||||
|
|
||||||
if cellX ~= cache.lastCellX or cellY ~= cache.lastCellY then
|
for _, zone in pairs(Zones) do
|
||||||
for i = 1, #nearbyZones do
|
zone.distance = #(zone.coords - coords)
|
||||||
local zone = nearbyZones[i]
|
local radius, contains = zone.radius, nil
|
||||||
|
|
||||||
if zone.insideZone then
|
if radius then
|
||||||
local contains = zone:contains(coords, true)
|
contains = zone.distance < radius
|
||||||
|
else
|
||||||
if not contains then
|
contains = glm_polygon_contains(zone.polygon, coords, zone.thickness / 4)
|
||||||
zone.insideZone = false
|
|
||||||
insideZones[zone.id] = nil
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
cache.lastCellX = cellX
|
|
||||||
cache.lastCellY = cellY
|
|
||||||
end
|
|
||||||
|
|
||||||
nearbyZones = zones
|
|
||||||
|
|
||||||
for i = 1, #zones do
|
|
||||||
local zone = zones[i]
|
|
||||||
local contains = zone:contains(coords, true)
|
|
||||||
|
|
||||||
if contains then
|
if contains then
|
||||||
if not zone.insideZone then
|
if not zone.insideZone then
|
||||||
zone.insideZone = true
|
zone.insideZone = true
|
||||||
|
|
||||||
if zone.onEnter then
|
if zone.onEnter then
|
||||||
enteringZones:push(zone)
|
enteringSize += 1
|
||||||
|
enteringZones[enteringSize] = zone
|
||||||
end
|
end
|
||||||
|
|
||||||
if zone.inside or zone.debug then
|
if zone.inside or zone.debug then
|
||||||
@ -169,7 +148,8 @@ CreateThread(function()
|
|||||||
insideZones[zone.id] = nil
|
insideZones[zone.id] = nil
|
||||||
|
|
||||||
if zone.onExit then
|
if zone.onExit then
|
||||||
exitingZones:push(zone)
|
exitingSize += 1
|
||||||
|
exitingZones[exitingSize] = zone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -179,18 +159,16 @@ CreateThread(function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local exitingSize = #exitingZones
|
|
||||||
local enteringSize = #enteringZones
|
|
||||||
|
|
||||||
if exitingSize > 0 then
|
if exitingSize > 0 then
|
||||||
table.sort(exitingZones, function(a, b)
|
table.sort(exitingZones, function(a, b)
|
||||||
return a.distance < b.distance
|
return a.distance > b.distance
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for i = exitingSize, 1, -1 do
|
for i = 1, exitingSize do
|
||||||
exitingZones[i]:onExit()
|
exitingZones[i]:onExit()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
exitingSize = 0
|
||||||
table.wipe(exitingZones)
|
table.wipe(exitingZones)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -203,6 +181,7 @@ CreateThread(function()
|
|||||||
enteringZones[i]:onEnter()
|
enteringZones[i]:onEnter()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
enteringSize = 0
|
||||||
table.wipe(enteringZones)
|
table.wipe(enteringZones)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -263,18 +242,12 @@ local function debugSphere(self)
|
|||||||
self.debugColour.g, self.debugColour.b, self.debugColour.a, false, false, 0, false, false, false, false)
|
self.debugColour.g, self.debugColour.b, self.debugColour.a, false, false, 0, false, false, false, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function contains(self, coords, updateDistance)
|
local function contains(self, coords)
|
||||||
if updateDistance then self.distance = #(self.coords - coords) end
|
|
||||||
|
|
||||||
return glm_polygon_contains(self.polygon, coords, self.thickness / 4)
|
return glm_polygon_contains(self.polygon, coords, self.thickness / 4)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function insideSphere(self, coords, updateDistance)
|
local function insideSphere(self, coords)
|
||||||
local distance = #(self.coords - coords)
|
return #(self.coords - coords) < self.radius
|
||||||
|
|
||||||
if updateDistance then self.distance = distance end
|
|
||||||
|
|
||||||
return distance < self.radius
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function convertToVector(coords)
|
local function convertToVector(coords)
|
||||||
@ -318,40 +291,9 @@ local function setDebug(self, bool, colour)
|
|||||||
self.debug = self.__type == 'sphere' and debugSphere or debugPoly or nil
|
self.debug = self.__type == 'sphere' and debugSphere or debugPoly or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param data ZoneProperties
|
lib.zones = {
|
||||||
---@return CZone
|
---@return CZone
|
||||||
local function setZone(data)
|
poly = function(data)
|
||||||
---@cast data CZone
|
|
||||||
data.remove = removeZone
|
|
||||||
data.contains = data.contains or contains
|
|
||||||
|
|
||||||
if lib.context == 'client' then
|
|
||||||
data.setDebug = setDebug
|
|
||||||
|
|
||||||
if data.debug then
|
|
||||||
data.debug = nil
|
|
||||||
|
|
||||||
data:setDebug(true, data.debugColour)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
data.debug = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
Zones[data.id] = data
|
|
||||||
lib.grid.addEntry(data)
|
|
||||||
|
|
||||||
return data
|
|
||||||
end
|
|
||||||
|
|
||||||
lib.zones = {}
|
|
||||||
|
|
||||||
---@class PolyZone : ZoneProperties
|
|
||||||
---@field points vector3[]
|
|
||||||
---@field thickness? number
|
|
||||||
|
|
||||||
---@param data PolyZone
|
|
||||||
---@return CZone
|
|
||||||
function lib.zones.poly(data)
|
|
||||||
data.id = #Zones + 1
|
data.id = #Zones + 1
|
||||||
data.thickness = data.thickness or 4
|
data.thickness = data.thickness or 4
|
||||||
|
|
||||||
@ -391,7 +333,7 @@ function lib.zones.poly(data)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
local zCoord = coordsArray[1].coord
|
local zCoord = coordsArray[1].coord
|
||||||
local averageTo = 1
|
local averageTo
|
||||||
|
|
||||||
for i = 1, #coordsArray do
|
for i = 1, #coordsArray do
|
||||||
if coordsArray[i].count < coordsArray[1].count then
|
if coordsArray[i].count < coordsArray[1].count then
|
||||||
@ -409,7 +351,6 @@ function lib.zones.poly(data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for i = 1, pointN do
|
for i = 1, pointN do
|
||||||
---@diagnostic disable-next-line: param-type-mismatch
|
|
||||||
points[i] = vec3(data.points[i].xy, zCoord)
|
points[i] = vec3(data.points[i].xy, zCoord)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -418,60 +359,69 @@ function lib.zones.poly(data)
|
|||||||
|
|
||||||
data.coords = data.polygon:centroid()
|
data.coords = data.polygon:centroid()
|
||||||
data.__type = 'poly'
|
data.__type = 'poly'
|
||||||
data.radius = lib.array.reduce(data.polygon, function(acc, point)
|
data.remove = removeZone
|
||||||
local distance = #(point - data.coords)
|
data.contains = contains
|
||||||
return distance > acc and distance or acc
|
data.setDebug = setDebug
|
||||||
end, 0)
|
|
||||||
|
|
||||||
return setZone(data)
|
if data.debug then
|
||||||
end
|
data.debug = nil
|
||||||
|
|
||||||
---@class BoxZone : ZoneProperties
|
data:setDebug(true, data.debugColour)
|
||||||
---@field coords vector3
|
end
|
||||||
---@field size? vector3
|
|
||||||
---@field rotation? number | vector3 | vector4 | matrix
|
|
||||||
|
|
||||||
---@param data BoxZone
|
Zones[data.id] = data
|
||||||
---@return CZone
|
return data
|
||||||
function lib.zones.box(data)
|
end,
|
||||||
|
|
||||||
|
---@return CZone
|
||||||
|
box = function(data)
|
||||||
data.id = #Zones + 1
|
data.id = #Zones + 1
|
||||||
data.coords = convertToVector(data.coords)
|
data.coords = convertToVector(data.coords)
|
||||||
data.size = data.size and convertToVector(data.size) / 2 or vec3(2)
|
data.size = data.size and convertToVector(data.size) / 2 or vec3(2)
|
||||||
data.thickness = data.size.z * 2
|
data.thickness = data.size.z * 2 or 4
|
||||||
data.rotation = quat(data.rotation or 0, vec3(0, 0, 1))
|
data.rotation = quat(data.rotation or 0, vec3(0, 0, 1))
|
||||||
data.__type = 'box'
|
|
||||||
data.width = data.size.x * 2
|
|
||||||
data.length = data.size.y * 2
|
|
||||||
data.polygon = (data.rotation * glm.polygon.new({
|
data.polygon = (data.rotation * glm.polygon.new({
|
||||||
vec3(data.size.x, data.size.y, 0),
|
vec3(data.size.x, data.size.y, 0),
|
||||||
vec3(-data.size.x, data.size.y, 0),
|
vec3(-data.size.x, data.size.y, 0),
|
||||||
vec3(-data.size.x, -data.size.y, 0),
|
vec3(-data.size.x, -data.size.y, 0),
|
||||||
vec3(data.size.x, -data.size.y, 0),
|
vec3(data.size.x, -data.size.y, 0),
|
||||||
}) + data.coords)
|
}) + data.coords)
|
||||||
|
data.__type = 'box'
|
||||||
|
data.remove = removeZone
|
||||||
|
data.contains = contains
|
||||||
|
data.setDebug = setDebug
|
||||||
|
|
||||||
return setZone(data)
|
if data.debug then
|
||||||
end
|
data.debug = nil
|
||||||
|
|
||||||
---@class SphereZone : ZoneProperties
|
data:setDebug(true, data.debugColour)
|
||||||
---@field coords vector3
|
end
|
||||||
---@field radius? number
|
|
||||||
|
|
||||||
---@param data SphereZone
|
Zones[data.id] = data
|
||||||
---@return CZone
|
return data
|
||||||
function lib.zones.sphere(data)
|
end,
|
||||||
|
|
||||||
|
---@return CZone
|
||||||
|
sphere = function(data)
|
||||||
data.id = #Zones + 1
|
data.id = #Zones + 1
|
||||||
data.coords = convertToVector(data.coords)
|
data.coords = convertToVector(data.coords)
|
||||||
data.radius = (data.radius or 2) + 0.0
|
data.radius = (data.radius or 2) + 0.0
|
||||||
data.__type = 'sphere'
|
data.__type = 'sphere'
|
||||||
|
data.remove = removeZone
|
||||||
data.contains = insideSphere
|
data.contains = insideSphere
|
||||||
|
data.setDebug = setDebug
|
||||||
|
|
||||||
return setZone(data)
|
if data.debug then
|
||||||
end
|
data:setDebug(true, data.debugColour)
|
||||||
|
end
|
||||||
|
|
||||||
function lib.zones.getAllZones() return Zones end
|
Zones[data.id] = data
|
||||||
|
return data
|
||||||
|
end,
|
||||||
|
|
||||||
function lib.zones.getCurrentZones() return insideZones end
|
getAllZones = function() return Zones end,
|
||||||
|
|
||||||
function lib.zones.getNearbyZones() return nearbyZones end
|
getCurrentZones = function() return insideZones end,
|
||||||
|
}
|
||||||
|
|
||||||
return lib.zones
|
return lib.zones
|
||||||
110
resources/[core]/ox_lib/imports/zones/server.lua
Normal file
110
resources/[core]/ox_lib/imports/zones/server.lua
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
local glm = require 'glm'
|
||||||
|
|
||||||
|
---@type table<number, CZone>
|
||||||
|
local Zones = {}
|
||||||
|
_ENV.Zones = Zones
|
||||||
|
|
||||||
|
local function removeZone(self)
|
||||||
|
Zones[self.id] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local glm_polygon_contains = glm.polygon.contains
|
||||||
|
|
||||||
|
local function contains(self, coords)
|
||||||
|
return glm_polygon_contains(self.polygon, coords, self.thickness / 4)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function insideSphere(self, coords)
|
||||||
|
return #(self.coords - coords) < self.radius
|
||||||
|
end
|
||||||
|
|
||||||
|
local function convertToVector(coords)
|
||||||
|
local _type = type(coords)
|
||||||
|
|
||||||
|
if _type ~= 'vector3' then
|
||||||
|
if _type == 'table' or _type == 'vector4' then
|
||||||
|
return vec3(coords[1] or coords.x, coords[2] or coords.y, coords[3] or coords.z)
|
||||||
|
end
|
||||||
|
|
||||||
|
error(("expected type 'vector3' or 'table' (received %s)"):format(_type))
|
||||||
|
end
|
||||||
|
|
||||||
|
return coords
|
||||||
|
end
|
||||||
|
|
||||||
|
lib.zones = {
|
||||||
|
---@return CZone
|
||||||
|
poly = function(data)
|
||||||
|
data.id = #Zones + 1
|
||||||
|
data.thickness = data.thickness or 4
|
||||||
|
|
||||||
|
local pointN = #data.points
|
||||||
|
local points = table.create(pointN, 0)
|
||||||
|
|
||||||
|
for i = 1, pointN do
|
||||||
|
points[i] = convertToVector(data.points[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
data.polygon = glm.polygon.new(points)
|
||||||
|
data.coords = data.polygon:centroid()
|
||||||
|
data.type = 'poly'
|
||||||
|
data.remove = removeZone
|
||||||
|
data.contains = contains
|
||||||
|
data.debug = nil
|
||||||
|
data.debugColour = nil
|
||||||
|
data.inside = nil
|
||||||
|
data.onEnter = nil
|
||||||
|
data.onExit = nil
|
||||||
|
|
||||||
|
Zones[data.id] = data
|
||||||
|
return data
|
||||||
|
end,
|
||||||
|
|
||||||
|
---@return CZone
|
||||||
|
box = function(data)
|
||||||
|
data.id = #Zones + 1
|
||||||
|
data.coords = convertToVector(data.coords)
|
||||||
|
data.size = data.size and convertToVector(data.size) / 2 or vec3(2)
|
||||||
|
data.thickness = data.size.z * 2 or 4
|
||||||
|
data.rotation = quat(data.rotation or 0, vec3(0, 0, 1))
|
||||||
|
data.polygon = (data.rotation * glm.polygon.new({
|
||||||
|
vec3(data.size.x, data.size.y, 0),
|
||||||
|
vec3(-data.size.x, data.size.y, 0),
|
||||||
|
vec3(-data.size.x, -data.size.y, 0),
|
||||||
|
vec3(data.size.x, -data.size.y, 0),
|
||||||
|
}) + data.coords)
|
||||||
|
data.type = 'box'
|
||||||
|
data.remove = removeZone
|
||||||
|
data.contains = contains
|
||||||
|
data.debug = nil
|
||||||
|
data.debugColour = nil
|
||||||
|
data.inside = nil
|
||||||
|
data.onEnter = nil
|
||||||
|
data.onExit = nil
|
||||||
|
|
||||||
|
Zones[data.id] = data
|
||||||
|
return data
|
||||||
|
end,
|
||||||
|
|
||||||
|
---@return CZone
|
||||||
|
sphere = function(data)
|
||||||
|
data.id = #Zones + 1
|
||||||
|
data.coords = convertToVector(data.coords)
|
||||||
|
data.radius = (data.radius or 2) + 0.0
|
||||||
|
data.type = 'sphere'
|
||||||
|
data.remove = removeZone
|
||||||
|
data.contains = insideSphere
|
||||||
|
data.debug = nil
|
||||||
|
data.debugColour = nil
|
||||||
|
data.inside = nil
|
||||||
|
data.onEnter = nil
|
||||||
|
data.onExit = nil
|
||||||
|
|
||||||
|
Zones[data.id] = data
|
||||||
|
return data
|
||||||
|
end,
|
||||||
|
|
||||||
|
getAllZones = function() return Zones end,
|
||||||
|
}
|
||||||
|
|
||||||
|
return lib.zones
|
||||||
@ -96,6 +96,11 @@ local lib = setmetatable({
|
|||||||
__call = call,
|
__call = call,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
_ENV.lib = lib
|
||||||
|
|
||||||
|
-- Override standard Lua require with our own.
|
||||||
|
require = lib.require
|
||||||
|
|
||||||
local intervals = {}
|
local intervals = {}
|
||||||
--- Dream of a world where this PR gets accepted.
|
--- Dream of a world where this PR gets accepted.
|
||||||
---@param callback function | number
|
---@param callback function | number
|
||||||
@ -210,9 +215,7 @@ function lib.onCache(key, cb)
|
|||||||
table.insert(cacheEvents[key], cb)
|
table.insert(cacheEvents[key], cb)
|
||||||
end
|
end
|
||||||
|
|
||||||
_ENV.lib = lib
|
|
||||||
_ENV.cache = cache
|
_ENV.cache = cache
|
||||||
_ENV.require = lib.require
|
|
||||||
|
|
||||||
local notifyEvent = ('__ox_notify_%s'):format(cache.resource)
|
local notifyEvent = ('__ox_notify_%s'):format(cache.resource)
|
||||||
|
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"language": "Ελληνικά",
|
|
||||||
"settings": "Ρυθμίσεις",
|
|
||||||
"ui": {
|
|
||||||
"cancel": "Ακύρωση",
|
|
||||||
"close": "Κλείσιμο",
|
|
||||||
"confirm": "Επιβεβαίωση",
|
|
||||||
"more": "Περισσότερα...",
|
|
||||||
"settings": {
|
|
||||||
"locale": "Αλλαγή γλώσσας",
|
|
||||||
"locale_description": "Τρέχουσα γλώσσα: ${language} (%s)",
|
|
||||||
"notification_audio": "Ήχος ειδοποίησης",
|
|
||||||
"notification_position": "Θέση ειδοποίησης"
|
|
||||||
},
|
|
||||||
"position": {
|
|
||||||
"bottom": "Κάτω",
|
|
||||||
"bottom-left": "Κάτω αριστερά",
|
|
||||||
"bottom-right": "Κάτω δεξιά",
|
|
||||||
"center-left": "Κέντρο αριστερά",
|
|
||||||
"center-right": "Κέντρο δεξιά",
|
|
||||||
"top": "Πάνω",
|
|
||||||
"top-left": "Πάνω αριστερά",
|
|
||||||
"top-right": "Πάνω δεξιά"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"open_radial_menu": "Άνοιγμα κυκλικού μενού",
|
|
||||||
"cancel_progress": "Ακύρωση τρέχουσας γραμμής προόδου",
|
|
||||||
"txadmin_announcement": "Ανακοίνωση διακομιστή από τον %s",
|
|
||||||
"txadmin_dm": "Άμεσο μήνυμα από τον %s",
|
|
||||||
"txadmin_warn": "Έχετε προειδοποιηθεί από τον %s",
|
|
||||||
"txadmin_warn_content": "%s \nID Ενέργειας: %s",
|
|
||||||
"txadmin_scheduledrestart": "Προγραμματισμένη επανεκκίνηση"
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"language": "Lietuvių",
|
"language": "Lietuvių",
|
||||||
"settings": "Nustatymai",
|
|
||||||
"ui": {
|
"ui": {
|
||||||
"cancel": "Atšaukti",
|
"cancel": "Atšaukti",
|
||||||
"close": "Uždaryti",
|
"close": "Uždaryti",
|
||||||
@ -10,17 +9,17 @@
|
|||||||
"locale": "Pakeisti kalbą",
|
"locale": "Pakeisti kalbą",
|
||||||
"locale_description": "Dabartinė: ${language} (%s)",
|
"locale_description": "Dabartinė: ${language} (%s)",
|
||||||
"notification_audio": "Pranešimo garsas",
|
"notification_audio": "Pranešimo garsas",
|
||||||
"notification_position": "Pranešimo pozicija"
|
"notification_position": "Notification position"
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"bottom": "Apačioje",
|
"bottom": "Bottom",
|
||||||
"bottom-left": "Apačioje-kairėje",
|
"bottom-left": "Bottom-left",
|
||||||
"bottom-right": "Apačioje-dešinėje",
|
"bottom-right": "Bottom-right",
|
||||||
"center-left": "Centre-kairėje",
|
"center-left": "Center-left",
|
||||||
"center-right": "Centre-dešinėje",
|
"center-right": "Center-right",
|
||||||
"top": "Viršuje",
|
"top": "Top",
|
||||||
"top-left": "Viršuje-kairėje",
|
"top-left": "Top-left",
|
||||||
"top-right": "Viršuje-dešinėje"
|
"top-right": "Top-right"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"open_radial_menu": "Atidaryti radialinį meniu",
|
"open_radial_menu": "Atidaryti radialinį meniu",
|
||||||
|
|||||||
@ -1,30 +1,29 @@
|
|||||||
{
|
{
|
||||||
"language": "Nederlands",
|
"language": "Nederlands",
|
||||||
"settings": "Instellingen",
|
|
||||||
"ui": {
|
"ui": {
|
||||||
"cancel": "Annuleren",
|
"cancel": "Annuleren",
|
||||||
"close": "Sluiten",
|
"close": "Sluiten",
|
||||||
"confirm": "Bevestigen",
|
"confirm": "Bevestigen",
|
||||||
"more": "Meer...",
|
"more": "Meer...",
|
||||||
"settings": {
|
"settings": {
|
||||||
"locale": "Taal wijzigen",
|
"locale": "Change locale",
|
||||||
"locale_description": "Huidige taal: ${language} (%s)",
|
"locale_description": "Current language: ${language} (%s)",
|
||||||
"notification_audio": "Meldingsgeluid",
|
"notification_audio": "Notification audio",
|
||||||
"notification_position": "Meldingspositie"
|
"notification_position": "Notification position"
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"bottom": "Onder",
|
"bottom": "Bottom",
|
||||||
"bottom-left": "Linksonder",
|
"bottom-left": "Bottom-left",
|
||||||
"bottom-right": "Rechtsonder",
|
"bottom-right": "Bottom-right",
|
||||||
"center-left": "Linksmidden",
|
"center-left": "Center-left",
|
||||||
"center-right": "Rechtsmidden",
|
"center-right": "Center-right",
|
||||||
"top": "Boven",
|
"top": "Top",
|
||||||
"top-left": "Linksboven",
|
"top-left": "Top-left",
|
||||||
"top-right": "Rechtsboven"
|
"top-right": "Top-right"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"open_radial_menu": "Radiaal menu openen",
|
"open_radial_menu": "Open radial menu",
|
||||||
"cancel_progress": "Huidige voortgangsbalk annuleren",
|
"cancel_progress": "Cancel current progress bar",
|
||||||
"txadmin_announcement": "Server mededeling door %s",
|
"txadmin_announcement": "Server mededeling door %s",
|
||||||
"txadmin_dm": "Bericht van %s",
|
"txadmin_dm": "Bericht van %s",
|
||||||
"txadmin_warn": "Je hebt een waarschuwing gekregen van %s",
|
"txadmin_warn": "Je hebt een waarschuwing gekregen van %s",
|
||||||
|
|||||||
@ -6,27 +6,27 @@
|
|||||||
"confirm": "Confirmar",
|
"confirm": "Confirmar",
|
||||||
"more": "Mais...",
|
"more": "Mais...",
|
||||||
"settings": {
|
"settings": {
|
||||||
"locale": "Alterar idioma",
|
"locale": "Change locale",
|
||||||
"locale_description": "Idioma atual: ${language} (%s)",
|
"locale_description": "Current language: ${language} (%s)",
|
||||||
"notification_audio": "Áudio de notificação",
|
"notification_audio": "Notification audio",
|
||||||
"notification_position": "Posição da notificação"
|
"notification_position": "Notification position"
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"bottom": "Inferior",
|
"bottom": "Bottom",
|
||||||
"bottom-left": "Inferior esquerdo",
|
"bottom-left": "Bottom-left",
|
||||||
"bottom-right": "Inferior direito",
|
"bottom-right": "Bottom-right",
|
||||||
"center-left": "Centro-esquerdo",
|
"center-left": "Center-left",
|
||||||
"center-right": "Centro-direito",
|
"center-right": "Center-right",
|
||||||
"top": "Superior",
|
"top": "Top",
|
||||||
"top-left": "Superior esquerdo",
|
"top-left": "Top-left",
|
||||||
"top-right": "Superior direito"
|
"top-right": "Top-right"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"open_radial_menu": "Abrir menu radial",
|
"open_radial_menu": "Open radial menu",
|
||||||
"cancel_progress": "Cancelar barra de progresso atual",
|
"cancel_progress": "Cancel current progress bar",
|
||||||
"txadmin_announcement": "Anúncio por %s",
|
"txadmin_announcement": "Server announcement by %s",
|
||||||
"txadmin_dm": "Mensagem de %s",
|
"txadmin_dm": "Direct Message from %s",
|
||||||
"txadmin_warn": "Você foi alertado por %s",
|
"txadmin_warn": "You have been warned by %s",
|
||||||
"txadmin_warn_content": "%s \nID do aviso: %s",
|
"txadmin_warn_content": "%s \nAction ID: %s",
|
||||||
"txadmin_scheduledrestart": "Reinício agendado"
|
"txadmin_scheduledrestart": "Scheduled Restart"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"language": "Türkçe",
|
"language": "Türkçe",
|
||||||
"settings": "Ayarlar",
|
|
||||||
"ui": {
|
"ui": {
|
||||||
"cancel": "İptal",
|
"cancel": "İptal",
|
||||||
"close": "Kapat",
|
"close": "Kapat",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"language": "简体中文",
|
"language": "简体中文",
|
||||||
"settings": "设置",
|
|
||||||
"ui": {
|
"ui": {
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"close": "关闭",
|
"close": "关闭",
|
||||||
|
|||||||
@ -1,30 +1,29 @@
|
|||||||
{
|
{
|
||||||
"language": "繁體中文",
|
"language": "繁體中文",
|
||||||
"settings": "設置",
|
|
||||||
"ui": {
|
"ui": {
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"close": "關閉",
|
"close": "關閉",
|
||||||
"confirm": "確認",
|
"confirm": "確認",
|
||||||
"more": "更多...",
|
"more": "更多...",
|
||||||
"settings": {
|
"settings": {
|
||||||
"locale": "更改語言",
|
"locale": "Change locale",
|
||||||
"locale_description": "當前語言: ${language} (%s)",
|
"locale_description": "Current language: ${language} (%s)",
|
||||||
"notification_audio": "通知提示音",
|
"notification_audio": "Notification audio",
|
||||||
"notification_position": "通知位置"
|
"notification_position": "Notification position"
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"bottom": "底部",
|
"bottom": "Bottom",
|
||||||
"bottom-left": "左下",
|
"bottom-left": "Bottom-left",
|
||||||
"bottom-right": "右下",
|
"bottom-right": "Bottom-right",
|
||||||
"center-left": "左側居中",
|
"center-left": "Center-left",
|
||||||
"center-right": "右側居中",
|
"center-right": "Center-right",
|
||||||
"top": "頂部",
|
"top": "Top",
|
||||||
"top-left": "左上",
|
"top-left": "Top-left",
|
||||||
"top-right": "右上"
|
"top-right": "Top-right"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"open_radial_menu": "打開輪盤菜單",
|
"open_radial_menu": "Open radial menu",
|
||||||
"cancel_progress": "取消當前進度條",
|
"cancel_progress": "Cancel current progress bar",
|
||||||
"txadmin_announcement": "來自 %s 的伺服器通告",
|
"txadmin_announcement": "來自 %s 的伺服器通告",
|
||||||
"txadmin_dm": "來自 %s 的訊息",
|
"txadmin_dm": "來自 %s 的訊息",
|
||||||
"txadmin_warn": "您被 %s 警告了",
|
"txadmin_warn": "您被 %s 警告了",
|
||||||
|
|||||||
@ -26,10 +26,6 @@ CreateThread(function()
|
|||||||
local vehicle = GetVehiclePedIsIn(ped, false)
|
local vehicle = GetVehiclePedIsIn(ped, false)
|
||||||
|
|
||||||
if vehicle > 0 then
|
if vehicle > 0 then
|
||||||
if vehicle ~= cache.vehicle then
|
|
||||||
cache:set('seat', false)
|
|
||||||
end
|
|
||||||
|
|
||||||
cache:set('vehicle', vehicle)
|
cache:set('vehicle', vehicle)
|
||||||
|
|
||||||
if not cache.seat or GetPedInVehicleSeat(vehicle, cache.seat) ~= ped then
|
if not cache.seat or GetPedInVehicleSeat(vehicle, cache.seat) ~= ped then
|
||||||
|
|||||||
@ -1,57 +0,0 @@
|
|||||||
local registeredCallbacks = {}
|
|
||||||
|
|
||||||
AddEventHandler('onResourceStop', function(resourceName)
|
|
||||||
if cache.resource == resourceName then return end
|
|
||||||
|
|
||||||
for callbackName, resource in pairs(registeredCallbacks) do
|
|
||||||
if resource == resourceName then
|
|
||||||
registeredCallbacks[callbackName] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
---For internal use only.
|
|
||||||
---Sets a callback event as registered to a specific resource, preventing it from
|
|
||||||
---being overwritten. Any unknown callbacks will return an error to the caller.
|
|
||||||
---@param callbackName string
|
|
||||||
---@param isValid boolean
|
|
||||||
function lib.setValidCallback(callbackName, isValid)
|
|
||||||
local resourceName = GetInvokingResource() or cache.resource
|
|
||||||
local callbackResource = registeredCallbacks[callbackName]
|
|
||||||
|
|
||||||
if callbackResource then
|
|
||||||
if not isValid then
|
|
||||||
callbackResource[callbackName] = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if callbackResource == resourceName then return end
|
|
||||||
|
|
||||||
local errMessage = ("^1resource '%s' attempted to overwrite callback '%s' owned by resource '%s'^0"):format(resourceName, callbackName, callbackResource)
|
|
||||||
|
|
||||||
return print(('^1SCRIPT ERROR: %s^0\n%s'):format(errMessage,
|
|
||||||
Citizen.InvokeNative(`FORMAT_STACK_TRACE` & 0xFFFFFFFF, nil, 0, Citizen.ResultAsString()) or ''))
|
|
||||||
end
|
|
||||||
|
|
||||||
lib.print.verbose(("set valid callback '%s' for resource '%s'"):format(callbackName, resourceName))
|
|
||||||
|
|
||||||
registeredCallbacks[callbackName] = resourceName
|
|
||||||
end
|
|
||||||
|
|
||||||
function lib.isCallbackValid(callbackName)
|
|
||||||
return registeredCallbacks[callbackName] == GetInvokingResource() or cache.resource
|
|
||||||
end
|
|
||||||
|
|
||||||
local cbEvent = '__ox_cb_%s'
|
|
||||||
|
|
||||||
RegisterNetEvent('ox_lib:validateCallback', function(callbackName, invokingResource, key)
|
|
||||||
if registeredCallbacks[callbackName] then return end
|
|
||||||
|
|
||||||
local event = cbEvent:format(invokingResource)
|
|
||||||
|
|
||||||
if cache.game == 'fxserver' then
|
|
||||||
return TriggerClientEvent(event, source, key, 'cb_invalid')
|
|
||||||
end
|
|
||||||
|
|
||||||
TriggerServerEvent(event, key, 'cb_invalid')
|
|
||||||
end)
|
|
||||||
@ -49,11 +49,6 @@ function lib.showMenu(id, startIndex)
|
|||||||
if not menu then
|
if not menu then
|
||||||
error(('No menu with id %s was found'):format(id))
|
error(('No menu with id %s was found'):format(id))
|
||||||
end
|
end
|
||||||
|
|
||||||
if table.type(menu.options) == 'empty' then
|
|
||||||
error(('Can\'t open empty menu with id %s'):format(id))
|
|
||||||
end
|
|
||||||
|
|
||||||
if not openMenu then
|
if not openMenu then
|
||||||
local control = cache.game == 'fivem' and 140 or 0xE30CD707
|
local control = cache.game == 'fivem' and 140 or 0xE30CD707
|
||||||
|
|
||||||
|
|||||||
@ -30,8 +30,7 @@ local function createProp(ped, prop)
|
|||||||
local coords = GetEntityCoords(ped)
|
local coords = GetEntityCoords(ped)
|
||||||
local object = CreateObject(prop.model, coords.x, coords.y, coords.z, false, false, false)
|
local object = CreateObject(prop.model, coords.x, coords.y, coords.z, false, false, false)
|
||||||
|
|
||||||
AttachEntityToEntity(object, ped, GetPedBoneIndex(ped, prop.bone or 60309), prop.pos.x, prop.pos.y, prop.pos.z, prop.rot.x, prop.rot.y, prop.rot.z, true,
|
AttachEntityToEntity(object, ped, GetPedBoneIndex(ped, prop.bone or 60309), prop.pos.x, prop.pos.y, prop.pos.z, prop.rot.x, prop.rot.y, prop.rot.z, true, true, false, true, prop.rotOrder or 0, true)
|
||||||
true, false, true, prop.rotOrder or 0, true)
|
|
||||||
SetModelAsNoLongerNeeded(prop.model)
|
SetModelAsNoLongerNeeded(prop.model)
|
||||||
|
|
||||||
return object
|
return object
|
||||||
@ -63,7 +62,6 @@ local controls = {
|
|||||||
INPUT_VEH_MOUSE_CONTROL_OVERRIDE = isFivem and 106 or 0x39CCABD5
|
INPUT_VEH_MOUSE_CONTROL_OVERRIDE = isFivem and 106 or 0x39CCABD5
|
||||||
}
|
}
|
||||||
|
|
||||||
---@param data ProgressProps
|
|
||||||
local function startProgress(data)
|
local function startProgress(data)
|
||||||
playerState.invBusy = true
|
playerState.invBusy = true
|
||||||
progress = data
|
progress = data
|
||||||
@ -73,11 +71,10 @@ local function startProgress(data)
|
|||||||
if anim.dict then
|
if anim.dict then
|
||||||
lib.requestAnimDict(anim.dict)
|
lib.requestAnimDict(anim.dict)
|
||||||
|
|
||||||
TaskPlayAnim(cache.ped, anim.dict, anim.clip, anim.blendIn or 3.0, anim.blendOut or 1.0, anim.duration or -1, anim.flag or 49, anim.playbackRate or 0,
|
TaskPlayAnim(cache.ped, anim.dict, anim.clip, anim.blendIn or 3.0, anim.blendOut or 1.0, anim.duration or -1, anim.flag or 49, anim.playbackRate or 0, anim.lockX, anim.lockY, anim.lockZ)
|
||||||
anim.lockX, anim.lockY, anim.lockZ)
|
|
||||||
RemoveAnimDict(anim.dict)
|
RemoveAnimDict(anim.dict)
|
||||||
elseif anim.scenario then
|
elseif anim.scenario then
|
||||||
TaskStartScenarioInPlace(cache.ped, anim.scenario, 0, anim.playEnter == nil or anim.playEnter --[[@as boolean]])
|
TaskStartScenarioInPlace(cache.ped, anim.scenario, 0, anim.playEnter ~= nil and anim.playEnter or true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -86,7 +83,6 @@ local function startProgress(data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local disable = data.disable
|
local disable = data.disable
|
||||||
local startTime = GetGameTimer()
|
|
||||||
|
|
||||||
while progress do
|
while progress do
|
||||||
if disable then
|
if disable then
|
||||||
@ -142,9 +138,8 @@ local function startProgress(data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
playerState.invBusy = false
|
playerState.invBusy = false
|
||||||
local duration = progress ~= false and GetGameTimer() - startTime + 100 -- give slight leeway
|
|
||||||
|
|
||||||
if progress == false or duration <= data.duration then
|
if progress == false then
|
||||||
SendNUIMessage({ action = 'progressCancel' })
|
SendNUIMessage({ action = 'progressCancel' })
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -248,13 +243,13 @@ AddStateBagChangeHandler('lib:progressProps', nil, function(bagName, key, value,
|
|||||||
local playerProps = createdProps[serverId]
|
local playerProps = createdProps[serverId]
|
||||||
|
|
||||||
if value.model then
|
if value.model then
|
||||||
playerProps[#playerProps + 1] = createProp(ped, value)
|
playerProps[#playerProps+1] = createProp(ped, value)
|
||||||
else
|
else
|
||||||
for i = 1, #value do
|
for i = 1, #value do
|
||||||
local prop = value[i]
|
local prop = value[i]
|
||||||
|
|
||||||
if prop then
|
if prop then
|
||||||
playerProps[#playerProps + 1] = createProp(ped, prop)
|
playerProps[#playerProps+1] = createProp(ped, prop)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -80,7 +80,6 @@ if cache.game == 'redm' then return end
|
|||||||
---@field modLivery? number
|
---@field modLivery? number
|
||||||
---@field modRoofLivery? number
|
---@field modRoofLivery? number
|
||||||
---@field modLightbar? number
|
---@field modLightbar? number
|
||||||
---@field livery? number
|
|
||||||
---@field windows? number[]
|
---@field windows? number[]
|
||||||
---@field doors? number[]
|
---@field doors? number[]
|
||||||
---@field tyres? table<number | string, 1 | 2>
|
---@field tyres? table<number | string, 1 | 2>
|
||||||
@ -152,6 +151,13 @@ function lib.getVehicleProperties(vehicle)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local modLiveryCount = GetVehicleLiveryCount(vehicle)
|
||||||
|
local modLivery = GetVehicleLivery(vehicle)
|
||||||
|
|
||||||
|
if modLiveryCount == -1 or modLivery == -1 then
|
||||||
|
modLivery = GetVehicleMod(vehicle, 48)
|
||||||
|
end
|
||||||
|
|
||||||
local damage = {
|
local damage = {
|
||||||
windows = {},
|
windows = {},
|
||||||
doors = {},
|
doors = {},
|
||||||
@ -267,10 +273,9 @@ function lib.getVehicleProperties(vehicle)
|
|||||||
modTank = GetVehicleMod(vehicle, 45),
|
modTank = GetVehicleMod(vehicle, 45),
|
||||||
modWindows = GetVehicleMod(vehicle, 46),
|
modWindows = GetVehicleMod(vehicle, 46),
|
||||||
modDoorR = GetVehicleMod(vehicle, 47),
|
modDoorR = GetVehicleMod(vehicle, 47),
|
||||||
modLivery = GetVehicleMod(vehicle, 48),
|
modLivery = modLivery,
|
||||||
modRoofLivery = GetVehicleRoofLivery(vehicle),
|
modRoofLivery = GetVehicleRoofLivery(vehicle),
|
||||||
modLightbar = GetVehicleMod(vehicle, 49),
|
modLightbar = GetVehicleMod(vehicle, 49),
|
||||||
livery = GetVehicleLivery(vehicle),
|
|
||||||
windows = damage.windows,
|
windows = damage.windows,
|
||||||
doors = damage.doors,
|
doors = damage.doors,
|
||||||
tyres = damage.tyres,
|
tyres = damage.tyres,
|
||||||
@ -343,7 +348,7 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
|||||||
ClearVehicleCustomPrimaryColour(vehicle)
|
ClearVehicleCustomPrimaryColour(vehicle)
|
||||||
SetVehicleColours(vehicle, props.color1 --[[@as number]], colorSecondary --[[@as number]])
|
SetVehicleColours(vehicle, props.color1 --[[@as number]], colorSecondary --[[@as number]])
|
||||||
else
|
else
|
||||||
if props.paintType1 then SetVehicleModColor_1(vehicle, props.paintType1, 0, props.pearlescentColor or 0) end
|
if props.paintType1 then SetVehicleModColor_1(vehicle, props.paintType1, colorPrimary, pearlescentColor) end
|
||||||
|
|
||||||
SetVehicleCustomPrimaryColour(vehicle, props.color1[1], props.color1[2], props.color1[3])
|
SetVehicleCustomPrimaryColour(vehicle, props.color1[1], props.color1[2], props.color1[3])
|
||||||
end
|
end
|
||||||
@ -354,7 +359,7 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
|||||||
ClearVehicleCustomSecondaryColour(vehicle)
|
ClearVehicleCustomSecondaryColour(vehicle)
|
||||||
SetVehicleColours(vehicle, props.color1 or colorPrimary --[[@as number]], props.color2 --[[@as number]])
|
SetVehicleColours(vehicle, props.color1 or colorPrimary --[[@as number]], props.color2 --[[@as number]])
|
||||||
else
|
else
|
||||||
if props.paintType2 then SetVehicleModColor_2(vehicle, props.paintType2, 0) end
|
if props.paintType2 then SetVehicleModColor_2(vehicle, props.paintType2, colorSecondary) end
|
||||||
|
|
||||||
SetVehicleCustomSecondaryColour(vehicle, props.color2[1], props.color2[2], props.color2[3])
|
SetVehicleCustomSecondaryColour(vehicle, props.color2[1], props.color2[2], props.color2[3])
|
||||||
end
|
end
|
||||||
@ -618,6 +623,7 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
|||||||
|
|
||||||
if props.modLivery then
|
if props.modLivery then
|
||||||
SetVehicleMod(vehicle, 48, props.modLivery, false)
|
SetVehicleMod(vehicle, 48, props.modLivery, false)
|
||||||
|
SetVehicleLivery(vehicle, props.modLivery)
|
||||||
end
|
end
|
||||||
|
|
||||||
if props.modRoofLivery then
|
if props.modRoofLivery then
|
||||||
@ -628,10 +634,6 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
|||||||
SetVehicleMod(vehicle, 49, props.modLightbar, false)
|
SetVehicleMod(vehicle, 49, props.modLightbar, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
if props.livery then
|
|
||||||
SetVehicleLivery(vehicle, props.livery)
|
|
||||||
end
|
|
||||||
|
|
||||||
if props.bulletProofTyres ~= nil then
|
if props.bulletProofTyres ~= nil then
|
||||||
SetVehicleTyresCanBurst(vehicle, props.bulletProofTyres)
|
SetVehicleTyresCanBurst(vehicle, props.bulletProofTyres)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,10 +37,6 @@ exports.ox_target:addPolyZone({
|
|||||||
})
|
})
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local function formatNumber(num)
|
|
||||||
return tostring(num):gsub(",", ".")
|
|
||||||
end
|
|
||||||
|
|
||||||
local parse = {
|
local parse = {
|
||||||
poly = function(data)
|
poly = function(data)
|
||||||
local points = {}
|
local points = {}
|
||||||
@ -86,34 +82,18 @@ local parse = {
|
|||||||
pattern = {
|
pattern = {
|
||||||
'local box = lib.zones.box({\n',
|
'local box = lib.zones.box({\n',
|
||||||
('\tname = "%s",\n'):format(data.name),
|
('\tname = "%s",\n'):format(data.name),
|
||||||
('\tcoords = vec3(%s, %s, %s),\n'):format(
|
('\tcoords = vec3(%s, %s, %s),\n'):format(data.xCoord, data.yCoord, data.zCoord),
|
||||||
formatNumber(data.xCoord),
|
('\tsize = vec3(%s, %s, %s),\n'):format(data.width, data.length, data.height),
|
||||||
formatNumber(data.yCoord),
|
('\trotation = %s,\n'):format(data.heading),
|
||||||
formatNumber(data.zCoord)
|
|
||||||
),
|
|
||||||
('\tsize = vec3(%s, %s, %s),\n'):format(
|
|
||||||
formatNumber(data.width),
|
|
||||||
formatNumber(data.length),
|
|
||||||
formatNumber(data.height)
|
|
||||||
),
|
|
||||||
('\trotation = %s,\n'):format(formatNumber(data.heading)),
|
|
||||||
'})\n',
|
'})\n',
|
||||||
}
|
}
|
||||||
elseif data.format == 'array' then
|
elseif data.format == 'array' then
|
||||||
pattern = {
|
pattern = {
|
||||||
'{\n',
|
'{\n',
|
||||||
('\tname = "%s",\n'):format(data.name),
|
('\tname = "%s",\n'):format(data.name),
|
||||||
('\tcoords = vec3(%s, %s, %s),\n'):format(
|
('\tcoords = vec3(%s, %s, %s),\n'):format(data.xCoord, data.yCoord, data.zCoord),
|
||||||
formatNumber(data.xCoord),
|
('\tsize = vec3(%s, %s, %s),\n'):format(data.width, data.length, data.height),
|
||||||
formatNumber(data.yCoord),
|
('\trotation = %s,\n'):format(data.heading),
|
||||||
formatNumber(data.zCoord)
|
|
||||||
),
|
|
||||||
('\tsize = vec3(%s, %s, %s),\n'):format(
|
|
||||||
formatNumber(data.width),
|
|
||||||
formatNumber(data.length),
|
|
||||||
formatNumber(data.height)
|
|
||||||
),
|
|
||||||
('\trotation = %s,\n'):format(formatNumber(data.heading)),
|
|
||||||
'},\n',
|
'},\n',
|
||||||
}
|
}
|
||||||
elseif data.format == 'target' then
|
elseif data.format == 'target' then
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
@import"https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;500;700&display=swap";@import"https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500&display=swap";@import"https://fonts.googleapis.com/css2?family=Fira+Mono&display=swap";@import"https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap";@import"https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600;700&display=swap";@import"https://use.typekit.net/wxh5ury.css";@import"https://use.typekit.net/qgr5ebd.css";html{color-scheme:normal!important}body{background:none!important;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;height:100vh;user-select:none;overflow:hidden!important}p{margin:0}#root{height:100%}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}@keyframes progress-bar{0%{width:0%}to{width:100%}}::-webkit-scrollbar{background-color:transparent;padding:0;margin:0;width:0;height:0}.toast-inform{background-color:#2980b9}.toast-success{background-color:#27ae60}.toast-error{background-color:#c0392b}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1042
resources/[core]/ox_lib/web/build/assets/index-K9iBfj89.js
Normal file
1042
resources/[core]/ox_lib/web/build/assets/index-K9iBfj89.js
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,8 +5,8 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>NUI React Boilerplate</title>
|
<title>NUI React Boilerplate</title>
|
||||||
<script type="module" crossorigin src="./assets/index-DA6-Nmx5.js"></script>
|
<script type="module" crossorigin src="./assets/index-K9iBfj89.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="./assets/index-BgkLwDpx.css">
|
<link rel="stylesheet" crossorigin href="./assets/index-3x7-Y31P.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@ -24,11 +24,11 @@ add_ace group.admin command allow # allow all commands
|
|||||||
add_ace group.admin command.quit deny # but don't allow quit
|
add_ace group.admin command.quit deny # but don't allow quit
|
||||||
add_principal identifier.fivem:1 group.admin # add the admin to the group
|
add_principal identifier.fivem:1 group.admin # add the admin to the group
|
||||||
|
|
||||||
sv_maxclients 10
|
sv_maxclients 1
|
||||||
set steam_webApiKey ""
|
set steam_webApiKey ""
|
||||||
sv_licenseKey cfxk_1dpnFJLVxfm1CRkj7Fp3t_35Z3DX
|
sv_licenseKey cfxk_1dpnFJLVxfm1CRkj7Fp3t_35Z3DX
|
||||||
|
|
||||||
set mysql_connection_string "mysql://uirp_admin:740921nlnL!@157.90.252.24/uirp?waitForConnections=true&charset=utf8mb4"
|
set mysql_connection_string "mysql://uirp_admin:740921nlnL!@45.149.207.217/uirp?waitForConnections=true&charset=utf8mb4"
|
||||||
set mysql_ui true
|
set mysql_ui true
|
||||||
|
|
||||||
setr esx:locale "en"
|
setr esx:locale "en"
|
||||||
|
|||||||
@ -15,7 +15,7 @@ sv_hostname "United Islands DEV"
|
|||||||
sets sv_projectName "United Islands"
|
sets sv_projectName "United Islands"
|
||||||
sets sv_projectDesc "United Islands S4"
|
sets sv_projectDesc "United Islands S4"
|
||||||
sv_enforceGameBuild 3258
|
sv_enforceGameBuild 3258
|
||||||
load_server_icon icon.png
|
#load_server_icon myLogo.png
|
||||||
|
|
||||||
set temp_convar "hey world!"
|
set temp_convar "hey world!"
|
||||||
sv_master1 ""
|
sv_master1 ""
|
||||||
@ -28,7 +28,7 @@ sv_maxclients 1
|
|||||||
set steam_webApiKey ""
|
set steam_webApiKey ""
|
||||||
sv_licenseKey cfxk_1dpnFJLVxfm1CRkj7Fp3t_35Z3DX
|
sv_licenseKey cfxk_1dpnFJLVxfm1CRkj7Fp3t_35Z3DX
|
||||||
|
|
||||||
set mysql_connection_string "mysql://uirp_admin:740921nlnL!@157.90.252.24/uirp?waitForConnections=true&charset=utf8mb4"
|
set mysql_connection_string "mysql://uirp_admin:740921nlnL!@45.149.207.217/uirp?waitForConnections=true&charset=utf8mb4"
|
||||||
set mysql_ui true
|
set mysql_ui true
|
||||||
|
|
||||||
setr esx:locale "en"
|
setr esx:locale "en"
|
||||||
|
|||||||
@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"global": {
|
|
||||||
"serverName": "UIRP",
|
|
||||||
"language": "en",
|
|
||||||
"menuEnabled": true,
|
|
||||||
"menuAlignRight": false,
|
|
||||||
"menuPageKey": "Tab",
|
|
||||||
"hideDefaultAnnouncement": false,
|
|
||||||
"hideDefaultDirectMessage": false,
|
|
||||||
"hideDefaultWarning": false,
|
|
||||||
"hideDefaultScheduledRestartWarning": false
|
|
||||||
},
|
|
||||||
"logger": {},
|
|
||||||
"monitor": {
|
|
||||||
"restarterSchedule": [],
|
|
||||||
"resourceStartingTolerance": 120
|
|
||||||
},
|
|
||||||
"playerDatabase": {
|
|
||||||
"onJoinCheckBan": true,
|
|
||||||
"whitelistMode": "guildRoles",
|
|
||||||
"whitelistedDiscordRoles": [
|
|
||||||
"681944964506058753"
|
|
||||||
],
|
|
||||||
"whitelistRejectionMessage": "Please join https://discord.gg/6FUefh62Jn and request to be whitelisted.",
|
|
||||||
"requiredBanHwidMatches": 1,
|
|
||||||
"banRejectionMessage": "You can join https://discord.gg/6FUefh62Jn to appeal this ban."
|
|
||||||
},
|
|
||||||
"webServer": {
|
|
||||||
"disableNuiSourceCheck": false
|
|
||||||
},
|
|
||||||
"discordBot": {
|
|
||||||
"enabled": true,
|
|
||||||
"token": "NjQwMzIxNTY5NDUyNzIwMTI4.GJZPKz.T2Cj1dEai8eTmnVAngmZEoYb14rU_WO5SEyNXE",
|
|
||||||
"guild": "634812052233519114",
|
|
||||||
"announceChannel": "689904236724748387",
|
|
||||||
"embedJson": "{\n \"title\": \"United Islands 5M - Beta 1.12\",\n \"url\": \"{{serverBrowserUrl}}\",\n \"description\": \"\",\n \"fields\": [\n {\n \"name\": \"> СТАТУС\",\n \"value\": \"```\\n{{statusString}}\\n```\",\n \"inline\": true\n },\n {\n \"name\": \"> ИГРАЧИ\",\n \"value\": \"```\\n{{serverClients}}/{{serverMaxClients}}\\n```\",\n \"inline\": true\n },\n {\n \"name\": \"> F8 КОМАНДА\",\n \"value\": \"```\\nconnect 123.123.123.123\\n```\"\n },\n {\n \"name\": \"> СЛЕДВАЩ РЕСТАРТ\",\n \"value\": \"```\\n{{nextScheduledRestart}}\\n```\",\n \"inline\": true\n },\n {\n \"name\": \"> ОНЛАЙН ОТ\",\n \"value\": \"```\\n{{uptime}}\\n```\",\n \"inline\": true\n }\n ],\n \"image\": {\n \"url\": \"https://cdn2.steamgriddb.com/hero_thumb/ea8fcd92d59581717e06eb187f10666d.jpg\"\n },\n \"thumbnail\": {\n \"url\": \"https://cdn.discordapp.com/attachments/1294679345943543810/1337970509337333822/1739057725021a7fxlq4l-removebg-preview.png?ex=67a961a3&is=67a81023&hm=9707b7c9690d16ef72c7d55db107843f189467556bf4bef2b22977663bb8b2a7&\"\n }\n}",
|
|
||||||
"embedConfigJson": "{\n \"onlineString\": \"🟢 Онлайн\",\n \"onlineColor\": \"#0BA70B\",\n \"partialString\": \"🟡 Частично\",\n \"partialColor\": \"#FFF100\",\n \"offlineString\": \"🔴 Офлайн\",\n \"offlineColor\": \"#A70B28\",\n \"buttons\": [\n {\n \"emoji\": \"1062338355909640233\",\n \"label\": \"Connect\",\n \"url\": \"{{serverJoinUrl}}\"\n },\n {\n \"emoji\": \"1337930103887364186\",\n \"label\": \"Discord\",\n \"url\": \"https://discord.gg/6FUefh62Jn\"\n }\n ]\n}"
|
|
||||||
},
|
|
||||||
"fxRunner": {
|
|
||||||
"serverDataPath": "/home/UIRP-5M/",
|
|
||||||
"cfgPath": "/home/UIRP-5M/server.cfg",
|
|
||||||
"commandLine": "",
|
|
||||||
"onesync": "on",
|
|
||||||
"autostart": true,
|
|
||||||
"quiet": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +1,47 @@
|
|||||||
{
|
{
|
||||||
"version": 2,
|
"global": {
|
||||||
"general": {
|
"serverName": "UIRP",
|
||||||
"serverName": "UIRP"
|
"language": "en",
|
||||||
|
"menuEnabled": true,
|
||||||
|
"menuAlignRight": false,
|
||||||
|
"menuPageKey": "Tab",
|
||||||
|
"hideDefaultAnnouncement": false,
|
||||||
|
"hideDefaultDirectMessage": false,
|
||||||
|
"hideDefaultWarning": false,
|
||||||
|
"hideDefaultScheduledRestartWarning": false
|
||||||
},
|
},
|
||||||
"server": {
|
"logger": {},
|
||||||
"dataPath": "/home/UIRP-5M/",
|
"monitor": {
|
||||||
"cfgPath": "/home/UIRP-5M/server.cfg"
|
"restarterSchedule": [],
|
||||||
},
|
|
||||||
"restarter": {
|
|
||||||
"resourceStartingTolerance": 120
|
"resourceStartingTolerance": 120
|
||||||
},
|
},
|
||||||
"banlist": {
|
"playerDatabase": {
|
||||||
"rejectionMessage": "You can join https://discord.gg/6FUefh62Jn to appeal this ban."
|
"onJoinCheckBan": true,
|
||||||
},
|
"whitelistMode": "guildRoles",
|
||||||
"whitelist": {
|
"whitelistedDiscordRoles": [
|
||||||
"mode": "discordRoles",
|
|
||||||
"rejectionMessage": "Please join https://discord.gg/6FUefh62Jn and request to be whitelisted.",
|
|
||||||
"discordRoles": [
|
|
||||||
"681944964506058753"
|
"681944964506058753"
|
||||||
]
|
],
|
||||||
|
"whitelistRejectionMessage": "Please join https://discord.gg/6FUefh62Jn and request to be whitelisted.",
|
||||||
|
"requiredBanHwidMatches": 1,
|
||||||
|
"banRejectionMessage": "You can join https://discord.gg/6FUefh62Jn to appeal this ban."
|
||||||
|
},
|
||||||
|
"webServer": {
|
||||||
|
"disableNuiSourceCheck": false
|
||||||
},
|
},
|
||||||
"discordBot": {
|
"discordBot": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"token": "NjQwMzIxNTY5NDUyNzIwMTI4.GJZPKz.T2Cj1dEai8eTmnVAngmZEoYb14rU_WO5SEyNXE",
|
"token": "NjQwMzIxNTY5NDUyNzIwMTI4.GJZPKz.T2Cj1dEai8eTmnVAngmZEoYb14rU_WO5SEyNXE",
|
||||||
"guild": "634812052233519114",
|
"guild": "634812052233519114",
|
||||||
"warningsChannel": "689904236724748387",
|
"announceChannel": "689904236724748387",
|
||||||
"embedJson": "{\"title\":\"United Islands 5M - Beta 1.12\",\"url\":\"{{serverBrowserUrl}}\",\"description\":\"\",\"fields\":[{\"name\":\"> СТАТУС\",\"value\":\"```\\n{{statusString}}\\n```\",\"inline\":true},{\"name\":\"> ИГРАЧИ\",\"value\":\"```\\n{{serverClients}}/{{serverMaxClients}}\\n```\",\"inline\":true},{\"name\":\"> F8 КОМАНДА\",\"value\":\"```\\nconnect 123.123.123.123\\n```\"},{\"name\":\"> СЛЕДВАЩ РЕСТАРТ\",\"value\":\"```\\n{{nextScheduledRestart}}\\n```\",\"inline\":true},{\"name\":\"> ОНЛАЙН ОТ\",\"value\":\"```\\n{{uptime}}\\n```\",\"inline\":true}],\"image\":{\"url\":\"https://cdn2.steamgriddb.com/hero_thumb/ea8fcd92d59581717e06eb187f10666d.jpg\"},\"thumbnail\":{\"url\":\"https://cdn.discordapp.com/attachments/1294679345943543810/1337970509337333822/1739057725021a7fxlq4l-removebg-preview.png?ex=67a961a3&is=67a81023&hm=9707b7c9690d16ef72c7d55db107843f189467556bf4bef2b22977663bb8b2a7&\"}}",
|
"embedJson": "{\n \"title\": \"United Islands 5M - Beta 1.12\",\n \"url\": \"{{serverBrowserUrl}}\",\n \"description\": \"\",\n \"fields\": [\n {\n \"name\": \"> СТАТУС\",\n \"value\": \"```\\n{{statusString}}\\n```\",\n \"inline\": true\n },\n {\n \"name\": \"> ИГРАЧИ\",\n \"value\": \"```\\n{{serverClients}}/{{serverMaxClients}}\\n```\",\n \"inline\": true\n },\n {\n \"name\": \"> F8 КОМАНДА\",\n \"value\": \"```\\nconnect 123.123.123.123\\n```\"\n },\n {\n \"name\": \"> СЛЕДВАЩ РЕСТАРТ\",\n \"value\": \"```\\n{{nextScheduledRestart}}\\n```\",\n \"inline\": true\n },\n {\n \"name\": \"> ОНЛАЙН ОТ\",\n \"value\": \"```\\n{{uptime}}\\n```\",\n \"inline\": true\n }\n ],\n \"image\": {\n \"url\": \"https://cdn2.steamgriddb.com/hero_thumb/ea8fcd92d59581717e06eb187f10666d.jpg\"\n },\n \"thumbnail\": {\n \"url\": \"https://cdn.discordapp.com/attachments/1294679345943543810/1337970509337333822/1739057725021a7fxlq4l-removebg-preview.png?ex=67a961a3&is=67a81023&hm=9707b7c9690d16ef72c7d55db107843f189467556bf4bef2b22977663bb8b2a7&\"\n }\n}",
|
||||||
"embedConfigJson": "{\"onlineString\":\"🟢 Онлайн\",\"onlineColor\":\"#0BA70B\",\"partialString\":\"🟡 Частично\",\"partialColor\":\"#FFF100\",\"offlineString\":\"🔴 Офлайн\",\"offlineColor\":\"#A70B28\",\"buttons\":[{\"emoji\":\"1062338355909640233\",\"label\":\"Connect\",\"url\":\"{{serverJoinUrl}}\"},{\"emoji\":\"1337930103887364186\",\"label\":\"Discord\",\"url\":\"https://discord.gg/6FUefh62Jn\"}]}"
|
"embedConfigJson": "{\n \"onlineString\": \"🟢 Онлайн\",\n \"onlineColor\": \"#0BA70B\",\n \"partialString\": \"🟡 Частично\",\n \"partialColor\": \"#FFF100\",\n \"offlineString\": \"🔴 Офлайн\",\n \"offlineColor\": \"#A70B28\",\n \"buttons\": [\n {\n \"emoji\": \"1062338355909640233\",\n \"label\": \"Connect\",\n \"url\": \"{{serverJoinUrl}}\"\n },\n {\n \"emoji\": \"1337930103887364186\",\n \"label\": \"Discord\",\n \"url\": \"https://discord.gg/6FUefh62Jn\"\n }\n ]\n}"
|
||||||
|
},
|
||||||
|
"fxRunner": {
|
||||||
|
"serverDataPath": "/home/UIRP-5M/",
|
||||||
|
"cfgPath": "/home/UIRP-5M/server.cfg",
|
||||||
|
"commandLine": "",
|
||||||
|
"onesync": "on",
|
||||||
|
"autostart": true,
|
||||||
|
"quiet": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1 +1 @@
|
|||||||
[["deployer:recipe","none"],["fxsRuntime:maxClients",10],["fxsRuntime:cfxId","j98bka"],["discord:status:channelId","1294706634404134963"],["discord:status:messageId","1337969197694713926"],["admin:picture:androxaaa","https://forum.cfx.re/user_avatar/forum.cfx.re/androxaaa/256/4656663_2.png"],["fxsRuntime:projectName","United Islands"],["updateDelay","1742133240337,63"],["fxsRuntime:locale","bg-BG"],["fxsRuntime:projectDesc","United Islands S4"],["fxsRuntime:tags","roleplay, bulgaria"],["fxsRuntime:gameName","fivem"]]
|
[["deployer:recipe","none"],["fxsRuntime:maxClients",1],["fxsRuntime:cfxId","j98bka"],["discord:status:channelId","1294706634404134963"],["discord:status:messageId","1337969197694713926"],["admin:picture:androxaaa","https://forum.cfx.re/user_avatar/forum.cfx.re/androxaaa/256/4656663_2.png"],["fxsRuntime:projectName","United Islands"],["updateDelay","1742133240337,63"]]
|
||||||
@ -1 +1 @@
|
|||||||
{"version":5,"players":[{"license":"7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","ids":["license:7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","xbl:2535471814346052","live:985153852147864","discord:204287035987591169","license2:266e0bdda3f98a56fca20f8bc4251d75a2819f41"],"hwids":["2:44007ea6666276ebf25f523682ea1c7694c6f6a6433c5cbd40ee5998ebb59829","3:f2a0272555371d7e0c28698fa260a98da7183ffba67da9ba19cd781e135899ab","5:045407469998f20c4e8f3362cd4797612b4b6e76b3b6aa83f236e6943c484b48","4:fc6cd78b3ab00291fbe8c34c7b93998b63b115ef726cf4d2663cf941ba1565ed","4:a0c2274f9bc3518bd5d1135ea05482d41d5b79c0bc1b3ae06a6197255547dae6","4:1913d6cac172f9e9810fcb4a6d6c643656df5ec6baafe149da9a984030de7c06"],"displayName":"androxa","pureName":"androxa","playTime":78,"tsLastConnection":1742218003,"tsJoined":1742133685}],"actions":[],"whitelistApprovals":[],"whitelistRequests":[]}
|
{"version":5,"players":[{"license":"7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","ids":["license:7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","xbl:2535471814346052","live:985153852147864","discord:204287035987591169","license2:266e0bdda3f98a56fca20f8bc4251d75a2819f41"],"hwids":["2:44007ea6666276ebf25f523682ea1c7694c6f6a6433c5cbd40ee5998ebb59829","3:f2a0272555371d7e0c28698fa260a98da7183ffba67da9ba19cd781e135899ab","5:045407469998f20c4e8f3362cd4797612b4b6e76b3b6aa83f236e6943c484b48","4:fc6cd78b3ab00291fbe8c34c7b93998b63b115ef726cf4d2663cf941ba1565ed","4:a0c2274f9bc3518bd5d1135ea05482d41d5b79c0bc1b3ae06a6197255547dae6","4:1913d6cac172f9e9810fcb4a6d6c643656df5ec6baafe149da9a984030de7c06"],"displayName":"androxa","pureName":"androxa","playTime":76,"tsLastConnection":1742135405,"tsJoined":1742133685}],"actions":[],"whitelistApprovals":[],"whitelistRequests":[]}
|
||||||
@ -1 +1 @@
|
|||||||
{"version":5,"players":[{"license":"7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","ids":["license:7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","xbl:2535471814346052","live:985153852147864","discord:204287035987591169","license2:266e0bdda3f98a56fca20f8bc4251d75a2819f41"],"hwids":["2:44007ea6666276ebf25f523682ea1c7694c6f6a6433c5cbd40ee5998ebb59829","3:f2a0272555371d7e0c28698fa260a98da7183ffba67da9ba19cd781e135899ab","5:045407469998f20c4e8f3362cd4797612b4b6e76b3b6aa83f236e6943c484b48","4:fc6cd78b3ab00291fbe8c34c7b93998b63b115ef726cf4d2663cf941ba1565ed","4:a0c2274f9bc3518bd5d1135ea05482d41d5b79c0bc1b3ae06a6197255547dae6","4:1913d6cac172f9e9810fcb4a6d6c643656df5ec6baafe149da9a984030de7c06"],"displayName":"androxa","pureName":"androxa","playTime":78,"tsLastConnection":1742218003,"tsJoined":1742133685}],"actions":[],"whitelistApprovals":[],"whitelistRequests":[]}
|
{"version":5,"players":[{"license":"7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","ids":["license:7b8f7bc668c9006616d7cb66d081d22ca2fc6f17","xbl:2535471814346052","live:985153852147864","discord:204287035987591169","license2:266e0bdda3f98a56fca20f8bc4251d75a2819f41"],"hwids":["2:44007ea6666276ebf25f523682ea1c7694c6f6a6433c5cbd40ee5998ebb59829","3:f2a0272555371d7e0c28698fa260a98da7183ffba67da9ba19cd781e135899ab","5:045407469998f20c4e8f3362cd4797612b4b6e76b3b6aa83f236e6943c484b48","4:fc6cd78b3ab00291fbe8c34c7b93998b63b115ef726cf4d2663cf941ba1565ed","4:a0c2274f9bc3518bd5d1135ea05482d41d5b79c0bc1b3ae06a6197255547dae6","4:1913d6cac172f9e9810fcb4a6d6c643656df5ec6baafe149da9a984030de7c06"],"displayName":"androxa","pureName":"androxa","playTime":76,"tsLastConnection":1742135405,"tsJoined":1742133685}],"actions":[],"whitelistApprovals":[],"whitelistRequests":[]}
|
||||||
@ -1 +1 @@
|
|||||||
{"version":2,"lastGameVersion":"gta5:3258","lastServerVersion":"linux:12746","lastResourceList":["expolscout","bmwg07","m5g60","esx_menu_list/1.10.8","esx_menu_dialog/1.10.8","ui-base","ui-pressence/1.1","ui_hud/BETA","pma-voice","uf_mapdata/v1.5","cron/1.10.8","chat-theme-gtao/1.0.0","ox_inventory/2.42.3","ui_multicharacter/1.10.8","ui_skin/1.10.8","spawnmanager/1.0.0","ajaxon_mapdata/1.0.2","uf_fleecabank/v1.0","ui_progressbar/1.10.8","monitor/8.0.1","expolregent","webpack/1.0.0","esx_menu_default/1.10.8","oxmysql/2.11.2","ui_core/1.10.8","AutoExotic/1.4","ui_identity/1.10.8","chat/1.0.0","ox_lib/3.26.0","ui_context/1.10.8","ui_textui/1.10.8","PolyZone/2.6.1","ui_notify/1.10.8","ui_pmenu","ui-postals/1.1.1","screenshot-basic","xsound/1.4.3","sessionmanager/1.0.0","yarn/1.0.0","skinchanger/1.10.8","ui_lscreen","bob74_ipl/2.1.1","ui-faceremaster/v1.0","hardcap/1.0.0","dev_warehouse/1.0.0","Airport_Pegasus_LSIA","rconlog/1.0.0","TiboMLO_appart1/1.0.1","moreo_parkings/1.0.0","ajaxon_aldore_hospital"],"lastUnknownReasons":[],"log":[{"hour":"2025-03-16T13:00:00.000Z","changes":[],"crashTypes":[],"dropTypes":[],"resKicks":[]},{"hour":"2025-03-16T14:00:00.000Z","changes":[{"ts":1742134110967,"type":"resourcesChanged","resAdded":["ui_pmenu"],"resRemoved":[]},{"ts":1742135356824,"type":"resourcesChanged","resAdded":["expolscout","moreo_parkings/1.0.0","ui-postals/1.1.1","ui_hud/BETA","TiboMLO_appart1/1.0.1","ui_lscreen","expolregent","dev_warehouse/1.0.0","Airport_Pegasus_LSIA"],"resRemoved":["screenshot-basic","chat/1.0.0"]}],"crashTypes":[],"dropTypes":[["resource",1]],"resKicks":[["ui_pmenu",1]]},{"hour":"2025-03-16T15:00:00.000Z","changes":[],"crashTypes":[],"dropTypes":[["player",1]],"resKicks":[]},{"hour":"2025-03-17T13:00:00.000Z","changes":[{"ts":1742217542894,"type":"fxsChanged","oldVersion":"linux:12746","newVersion":"linux:13227"},{"ts":1742217542894,"type":"resourcesChanged","resAdded":["monitor/8.0.1"],"resRemoved":["monitor/7.3.2","webpack/1.0.0"]},{"ts":1742217889073,"type":"fxsChanged","oldVersion":"linux:13227","newVersion":"linux:12746"},{"ts":1742217889073,"type":"resourcesChanged","resAdded":["webpack/1.0.0","chat/1.0.0","screenshot-basic"],"resRemoved":[]}],"crashTypes":[],"dropTypes":[["player",1]],"resKicks":[]}]}
|
{"version":2,"lastGameVersion":"gta5:3258","lastServerVersion":"linux:12746","lastResourceList":["bmwg07","m5g60","expolscout","moreo_parkings/1.0.0","ui-postals/1.1.1","ui_pmenu","ui_hud/BETA","ui_skin/1.10.8","cron/1.10.8","chat-theme-gtao/1.0.0","ui_multicharacter/1.10.8","pma-voice","uf_mapdata/v1.5","sessionmanager/1.0.0","xsound/1.4.3","ui_textui/1.10.8","ui_context/1.10.8","TiboMLO_appart1/1.0.1","rconlog/1.0.0","ui_progressbar/1.10.8","AutoExotic/1.4","ui-pressence/1.1","ui-base","yarn/1.0.0","ui_lscreen","skinchanger/1.10.8","ui_core/1.10.8","oxmysql/2.11.2","esx_menu_dialog/1.10.8","ox_lib/3.26.0","ox_inventory/2.42.3","PolyZone/2.6.1","esx_menu_list/1.10.8","ui_identity/1.10.8","spawnmanager/1.0.0","ajaxon_mapdata/1.0.2","uf_fleecabank/v1.0","monitor/7.3.2","expolregent","esx_menu_default/1.10.8","webpack/1.0.0","ui-faceremaster/v1.0","bob74_ipl/2.1.1","ui_notify/1.10.8","ajaxon_aldore_hospital","hardcap/1.0.0","dev_warehouse/1.0.0","Airport_Pegasus_LSIA"],"lastUnknownReasons":[],"log":[{"hour":"2025-03-16T13:00:00.000Z","changes":[],"crashTypes":[],"dropTypes":[],"resKicks":[]},{"hour":"2025-03-16T14:00:00.000Z","changes":[{"ts":1742134110967,"type":"resourcesChanged","resAdded":["ui_pmenu"],"resRemoved":[]},{"ts":1742135356824,"type":"resourcesChanged","resAdded":["expolscout","moreo_parkings/1.0.0","ui-postals/1.1.1","ui_hud/BETA","TiboMLO_appart1/1.0.1","ui_lscreen","expolregent","dev_warehouse/1.0.0","Airport_Pegasus_LSIA"],"resRemoved":["screenshot-basic","chat/1.0.0"]}],"crashTypes":[],"dropTypes":[["resource",1]],"resKicks":[["ui_pmenu",1]]},{"hour":"2025-03-16T15:00:00.000Z","changes":[],"crashTypes":[],"dropTypes":[["player",1]],"resKicks":[]}]}
|
||||||
File diff suppressed because one or more lines are too long
@ -14,30 +14,3 @@
|
|||||||
================================================================
|
================================================================
|
||||||
======== txAdmin v7.3.2 atop fxserver 12746 Starting - 3/16/2025, 3:29:08 PM
|
======== txAdmin v7.3.2 atop fxserver 12746 Starting - 3/16/2025, 3:29:08 PM
|
||||||
================================================================
|
================================================================
|
||||||
================================================================
|
|
||||||
======== txAdmin v8.0.1 atop fxserver 13227 Starting - 3/17/2025, 1:18:59 PM
|
|
||||||
================================================================
|
|
||||||
[13:20:21][androxaaa] logged in from 217.120.27.16 via cfxre
|
|
||||||
[13:24:40][androxaaa] [androxaaa] executed "RESTART SERVER"
|
|
||||||
[13:25:13][androxaaa] [androxaaa] executed "RESTART SERVER"
|
|
||||||
================================================================
|
|
||||||
======== txAdmin v8.0.1 atop fxserver 12746 Starting - 3/17/2025, 1:29:19 PM
|
|
||||||
================================================================
|
|
||||||
[13:29:20][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:29:26][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:29:56][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:30:13][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:30:34][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:31:00][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:31:31][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:32:07][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:32:48][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:33:35][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:34:21][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:35:07][MONITOR] Restarting server: Server process close detected.
|
|
||||||
[13:35:28][androxaaa] logged in from 217.120.27.16 via cfxre
|
|
||||||
[13:35:53][MONITOR] Restarting server: Server process close detected.
|
|
||||||
================================================================
|
|
||||||
======== txAdmin v8.0.1 atop fxserver 12746 Starting - 3/17/2025, 1:36:25 PM
|
|
||||||
================================================================
|
|
||||||
[13:36:39][androxaaa] logged in from 217.120.27.16 via cfxre
|
|
||||||
|
|||||||
@ -539,917 +539,3 @@
|
|||||||
[ citizen-server-impl] sync thread hitch warning: timer interval of 111 milliseconds
|
[ citizen-server-impl] sync thread hitch warning: timer interval of 111 milliseconds
|
||||||
[ citizen-server-impl] sync thread hitch warning: timer interval of 106 milliseconds
|
[ citizen-server-impl] sync thread hitch warning: timer interval of 106 milliseconds
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 173 milliseconds
|
[ citizen-server-impl] server thread hitch warning: timer interval of 173 milliseconds
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [5803] FXServer Starting - 3/17/2025, 1:18:59 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ citizen-server-impl] The file icon.png must be a 96x96 PNG image to be used as icon.
|
|
||||||
[ c-scripting-core] Creating script environments for yarn
|
|
||||||
[ resources] Started resource yarn
|
|
||||||
[ citizen-server-impl] Running build tasks on resource webpack - it'll restart once completed.
|
|
||||||
[ c-resources-core] Could not start dependency webpack for resource chat.
|
|
||||||
[ citizen-server-impl] Couldn't start resource chat.
|
|
||||||
[ resources] Started resource spawnmanager
|
|
||||||
[ c-scripting-core] Creating script environments for hardcap
|
|
||||||
[ resources] Started resource hardcap
|
|
||||||
[ c-scripting-core] Creating script environments for rconlog
|
|
||||||
[ resources] Started resource rconlog
|
|
||||||
[ resources] Started resource chat-theme-gtao
|
|
||||||
[ c-scripting-core] Creating script environments for oxmysql
|
|
||||||
[ resources] Started resource oxmysql
|
|
||||||
[ c-scripting-core] Creating script environments for ui_core
|
|
||||||
[ resources] Started resource ui_core
|
|
||||||
[ c-scripting-core] Creating script environments for PolyZone
|
|
||||||
[ resources] Started resource PolyZone
|
|
||||||
[ c-scripting-core] Creating script environments for cron
|
|
||||||
[ resources] Started resource cron
|
|
||||||
[ resources] Started resource esx_menu_default
|
|
||||||
[ resources] Started resource esx_menu_dialog
|
|
||||||
[ resources] Started resource esx_menu_list
|
|
||||||
[ c-scripting-core] Creating script environments for ox_lib
|
|
||||||
[ resources] Started resource ox_lib
|
|
||||||
[ c-scripting-core] Creating script environments for ox_inventory
|
|
||||||
[ resources] Started resource ox_inventory
|
|
||||||
[ c-scripting-core] Creating script environments for pma-voice
|
|
||||||
[ resources] Started resource pma-voice
|
|
||||||
[ citizen-server-impl] Running build tasks on resource webpack - it'll restart once completed.
|
|
||||||
[ c-resources-core] Could not start dependency webpack for resource screenshot-basic.
|
|
||||||
[ citizen-server-impl] Couldn't start resource screenshot-basic.
|
|
||||||
[ resources] Started resource skinchanger
|
|
||||||
[ c-scripting-core] Creating script environments for ui-base
|
|
||||||
[ resources] Started resource ui-base
|
|
||||||
[ c-scripting-core] Creating script environments for ui_context
|
|
||||||
[ resources] Started resource ui_context
|
|
||||||
[ c-scripting-core] Creating script environments for ui_hud
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.png` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources] Started resource ui_hud (4 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_identity
|
|
||||||
[ resources] Started resource ui_identity
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:13)
|
|
||||||
[ resources] Started resource ui_lscreen (3 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_skin
|
|
||||||
[ resources] Started resource ui_skin
|
|
||||||
[ c-scripting-core] Creating script environments for ui_multicharacter
|
|
||||||
[ resources] Started resource ui_multicharacter
|
|
||||||
[ c-scripting-core] Creating script environments for ui_notify
|
|
||||||
[ resources] Started resource ui_notify
|
|
||||||
[ c-scripting-core] Creating script environments for ui_pmenu
|
|
||||||
[ resources] Started resource ui_pmenu
|
|
||||||
[ c-scripting-core] Creating script environments for ui_progressbar
|
|
||||||
[ resources] Started resource ui_progressbar
|
|
||||||
[ c-scripting-core] Creating script environments for ui_textui
|
|
||||||
[ resources] Started resource ui_textui
|
|
||||||
[ c-scripting-core] Creating script environments for xsound
|
|
||||||
[ resources] Started resource xsound
|
|
||||||
[ resources] Started resource bob74_ipl
|
|
||||||
[ citizen-server-impl] You lack the required entitlement to use ui-bodyremaster
|
|
||||||
[ citizen-server-impl] Couldn't start resource ui-bodyremaster.
|
|
||||||
[ resources] Started resource ui-faceremaster
|
|
||||||
[ resources] Started resource ui-pressence
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_furn.ydr uses 40.0 MiB of physical memory.
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_shell.ydr uses 42.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource Airport_Pegasus_LSIA (2 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for AutoExotic
|
|
||||||
[ script:AutoExotic] Map successfully loaded
|
|
||||||
[resources:AutoExotic] Asset AutoExotic/as_autoexotic_txt.ytd uses 22.5 MiB of physical memory.
|
|
||||||
[ resources] Started resource AutoExotic (1 warning)
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_shell.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_stairs.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource TiboMLO_appart1 (2 warnings)
|
|
||||||
[ resources] Started resource ajaxon_aldore_hospital
|
|
||||||
[ resources] Started resource ajaxon_mapdata
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07.ytd uses 31.8 MiB of physical memory.
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07_hi.yft uses 16.7 MiB of virtual memory.
|
|
||||||
[ resources] Started resource bmwg07 (2 warnings)
|
|
||||||
[ resources] Started resource dev_warehouse
|
|
||||||
[ resources] Started resource expolregent
|
|
||||||
[ resources] Started resource expolscout
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.yft uses 23.8 MiB of virtual memory.
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.ytd uses 62.0 MiB of physical memory. Oversized assets can and WILL lead to streaming issues (such as models not loading/rendering).
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60_hi.yft uses 20.2 MiB of virtual memory.
|
|
||||||
[ resources] Started resource m5g60 (3 warnings)
|
|
||||||
[ resources] Started resource moreo_parkings
|
|
||||||
[ resources] Started resource uf_fleecabank
|
|
||||||
[ resources] Started resource uf_mapdata
|
|
||||||
[ c-scripting-core] Creating script environments for ui-postals
|
|
||||||
[ resources] Started resource ui-postals
|
|
||||||
[ citizen-server-main] Warning: The players.json endpoint has been modified to no longer return the player identifiers without authentication.
|
|
||||||
[ citizen-server-main] To learn more about this change read our announcement at https://aka.cfx.re/players-json-privacy
|
|
||||||
[ script:yarn] [yarn] yarn install v1.22.5
|
|
||||||
[ script:yarn] [1/4] Resolving packages...
|
|
||||||
[ script:yarn] [2/4] Fetching packages...
|
|
||||||
[ script:yarn] [yarn] yarn install v1.22.5
|
|
||||||
[ script:yarn] Error: [yarn] warning Waiting for the other yarn instance to finish (pid undefined, inside undefined)
|
|
||||||
[ citizen-server-impl] fff
|
|
||||||
[ citizen-server-impl] cccc ff xx xx rr rr eee
|
|
||||||
[ citizen-server-impl] cc ffff xx rrr r ee e
|
|
||||||
[ citizen-server-impl] cc ff xx ... rr eeeee
|
|
||||||
[ citizen-server-impl] ccccc ff xx xx ... rr eeeee
|
|
||||||
[ citizen-server-impl]
|
|
||||||
[ citizen-server-impl] Authenticated with cfx.re Nucleus: https://androxaaa-j98bka.users.cfx.re/
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 503 milliseconds
|
|
||||||
[ script:ox_lib] An update is available for ox_lib (current version: 3.26.0)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_lib/releases/tag/v3.30.3
|
|
||||||
[ script:ox_lib] An update is available for ox_inventory (current version: 2.42.3)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_inventory/releases/tag/v2.44.1
|
|
||||||
[ script:oxmysql] An update is available for oxmysql (current version: 2.11.2)
|
|
||||||
[ script:oxmysql] https://github.com/overextended/oxmysql/releases/tag/v2.13.0
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 830 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 1442 milliseconds
|
|
||||||
[ script:oxmysql] ui_core took 2277.6683ms to execute a query!
|
|
||||||
[ script:oxmysql] SELECT * FROM jobs []
|
|
||||||
[ script:oxmysql] ui_multicharacter took 2278.3684ms to execute a query!
|
|
||||||
[ script:oxmysql] SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = "uirp" AND DATA_TYPE = "varchar" AND COLUMN_NAME IN (?) [["identifier","owner"]]
|
|
||||||
[ script:yarn] [yarn] info fsevents@2.3.1: The platform "linux" is incompatible with this module.
|
|
||||||
[ script:yarn] info "fsevents@2.3.1" is an optional dependency and failed compatibility check. Excluding it from installation.
|
|
||||||
[ script:yarn] info fsevents@1.2.13: The platform "linux" is incompatible with this module.
|
|
||||||
[ script:yarn] info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
|
|
||||||
[ script:yarn] [3/4] Linking dependencies...
|
|
||||||
[ script:yarn] [4/4] Building fresh packages...
|
|
||||||
[ script:yarn] Done in 4.08s.
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 354 milliseconds
|
|
||||||
[ script:oxmysql] [8.4.4] Database server connection established!
|
|
||||||
[ script:yarn] Error: [yarn] warning Ignored scripts due to flag.
|
|
||||||
[ script:oxmysql] [8.4.4] ox_inventory took 1814.7389ms to execute a query!
|
|
||||||
[ script:oxmysql] SELECT * FROM items []
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Database contains 48 items.
|
|
||||||
[ script:oxmysql] [8.4.4] ox_inventory took 1816.9589ms to execute a query!
|
|
||||||
[ script:oxmysql] SELECT 1 FROM ox_inventory []
|
|
||||||
[ script:oxmysql] [8.4.4] ox_inventory took 1818.4153ms to execute a query!
|
|
||||||
[ script:oxmysql] INSERT IGNORE INTO `licenses` (`type`, `label`) VALUES (?, ?) ["weapon","Weapon License"]
|
|
||||||
[ citizen-server-impl] Build tasks completed - starting resource webpack.
|
|
||||||
[ c-scripting-core] Creating script environments for webpack
|
|
||||||
[ citizen-server-impl] Running build tasks on resource chat - it'll restart once completed.
|
|
||||||
[ citizen-server-impl] Running build tasks on resource screenshot-basic - it'll restart once completed.
|
|
||||||
[ script:yarn] yarn is currently busy: we are waiting to compile screenshot-basic
|
|
||||||
[ resources] Started resource webpack
|
|
||||||
[ script:ui_core] [^ui_core] ^CORE 1.10.8 initialized!
|
|
||||||
[ script:yarn] [yarn] [1/4] Resolving packages...
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 810 milliseconds
|
|
||||||
[ script:yarn] [yarn] success Already up-to-date.
|
|
||||||
[ script:yarn] Done in 4.12s.
|
|
||||||
[ script:yarn] [yarn] yarn install v1.22.5
|
|
||||||
[ script:yarn] [1/4] Resolving packages...
|
|
||||||
[ script:yarn] [2/4] Fetching packages...
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 725 milliseconds
|
|
||||||
[ citizen-server-impl] Build tasks completed - starting resource webpack.
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Inventory has loaded 262 items
|
|
||||||
[ script:yarn] [yarn] yarn install v1.22.5
|
|
||||||
[ script:yarn] Error: [yarn] warning Waiting for the other yarn instance to finish (pid undefined, inside undefined)
|
|
||||||
[ script:yarn] [yarn] info fsevents@1.2.11: The platform "linux" is incompatible with this module.
|
|
||||||
[ script:yarn] [yarn] info "fsevents@1.2.11" is an optional dependency and failed compatibility check. Excluding it from installation.
|
|
||||||
[ script:yarn] [yarn] [3/4] Linking dependencies...
|
|
||||||
[ script:yarn] [yarn] [4/4] Building fresh packages...
|
|
||||||
[ script:yarn] Error: [yarn] warning Ignored scripts due to flag.
|
|
||||||
[ script:yarn] [yarn] Done in 6.50s.
|
|
||||||
[ script:webpack] chat: started building webpack.config.js
|
|
||||||
[ script:yarn] [yarn] [1/4] Resolving packages...
|
|
||||||
[ script:yarn] [2/4] Fetching packages...
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 424 milliseconds
|
|
||||||
[ script:yarn] [yarn] info fsevents@2.3.1: The platform "linux" is incompatible with this module.
|
|
||||||
[ script:yarn] [yarn] info "fsevents@2.3.1" is an optional dependency and failed compatibility check. Excluding it from installation.
|
|
||||||
[ script:yarn] [yarn] info fsevents@1.2.13: The platform "linux" is incompatible with this module.
|
|
||||||
[ script:yarn] info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
|
|
||||||
[ script:yarn] [yarn] [3/4] Linking dependencies...
|
|
||||||
[ script:yarn] [yarn] [4/4] Building fresh packages...
|
|
||||||
[ script:yarn] Error: [yarn] warning Ignored scripts due to flag.
|
|
||||||
[ script:yarn] [yarn] Done in 8.41s.
|
|
||||||
[ script:webpack] webpack is busy: we are waiting to compile screenshot-basic (client.config.js)
|
|
||||||
[ script:webpack] chat: built webpack.config.js
|
|
||||||
[ citizen-server-impl] Build tasks completed - starting resource chat.
|
|
||||||
[ c-scripting-core] Creating script environments for chat
|
|
||||||
[ resources] Started resource chat
|
|
||||||
[ script:webpack] screenshot-basic: started building client.config.js
|
|
||||||
[ script:webpack] webpack is busy: we are waiting to compile screenshot-basic (server.config.js)
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 323 milliseconds
|
|
||||||
[ script:webpack] screenshot-basic: built client.config.js
|
|
||||||
[ script:webpack] screenshot-basic: started building server.config.js
|
|
||||||
[ script:webpack] webpack is busy: we are waiting to compile screenshot-basic (ui.config.js)
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 191 milliseconds
|
|
||||||
[ script:webpack] webpack is busy: we are waiting to compile screenshot-basic (ui.config.js)
|
|
||||||
[ script:webpack] screenshot-basic: built server.config.js
|
|
||||||
[ script:webpack] screenshot-basic: started building ui.config.js
|
|
||||||
[ script:webpack] screenshot-basic: built ui.config.js
|
|
||||||
[ citizen-server-impl] Build tasks completed - starting resource screenshot-basic.
|
|
||||||
[ c-scripting-core] Creating script environments for screenshot-basic
|
|
||||||
[ resources] Started resource screenshot-basic
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 159 milliseconds
|
|
||||||
║ TXADMIN║ txaReportResources
|
|
||||||
[ script:monitor] [txAdmin] Sending resources list to txAdmin.
|
|
||||||
[ script:hardcap] Connecting: androxa
|
|
||||||
[script:ui_multichara] [INFO] Player androxa 1 has deleted a character (char2:7b8f7bc668c9006616d7cb66d081d22ca2fc6f17)
|
|
||||||
[ script:ui_core] [INFO] Player "Artem Medvedev" has connected to the server. ID: 1
|
|
||||||
[ script:chat] androxa: asd
|
|
||||||
[ script:ui_core] [ERROR] Tried to spawn invalid vehicle - divo!
|
|
||||||
║ TXADMIN║ txaEvent "serverShuttingDown" "{\"delay\":5000,\"author\":\"androxaaa\",\"message\":\"Server restarting (admin request).\"}"
|
|
||||||
[ script:monitor] [txAdmin] Server shutting down. Kicking all players.
|
|
||||||
[ script:ui_core] [INFO] Saved 1 player over 0.0 ms
|
|
||||||
[ script:ui_core] [INFO] Saved player "Artem Medvedev"
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [6350] FXServer Starting - 3/17/2025, 1:24:45 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ citizen-server-impl] The file icon.png must be a 96x96 PNG image to be used as icon.
|
|
||||||
[ c-scripting-core] Creating script environments for yarn
|
|
||||||
[ resources] Started resource yarn
|
|
||||||
[ c-scripting-core] Creating script environments for webpack
|
|
||||||
[ resources] Started resource webpack
|
|
||||||
[ c-scripting-core] Creating script environments for chat
|
|
||||||
[ resources] Started resource chat
|
|
||||||
[ resources] Started resource spawnmanager
|
|
||||||
[ c-scripting-core] Creating script environments for hardcap
|
|
||||||
[ resources] Started resource hardcap
|
|
||||||
[ c-scripting-core] Creating script environments for rconlog
|
|
||||||
[ resources] Started resource rconlog
|
|
||||||
[ resources] Started resource chat-theme-gtao
|
|
||||||
[ c-scripting-core] Creating script environments for oxmysql
|
|
||||||
[ resources] Started resource oxmysql
|
|
||||||
[ c-scripting-core] Creating script environments for ui_core
|
|
||||||
[ resources] Started resource ui_core
|
|
||||||
[ c-scripting-core] Creating script environments for PolyZone
|
|
||||||
[ resources] Started resource PolyZone
|
|
||||||
[ c-scripting-core] Creating script environments for cron
|
|
||||||
[ resources] Started resource cron
|
|
||||||
[ resources] Started resource esx_menu_default
|
|
||||||
[ resources] Started resource esx_menu_dialog
|
|
||||||
[ resources] Started resource esx_menu_list
|
|
||||||
[ c-scripting-core] Creating script environments for ox_lib
|
|
||||||
[ resources] Started resource ox_lib
|
|
||||||
[ c-scripting-core] Creating script environments for ox_inventory
|
|
||||||
[ resources] Started resource ox_inventory
|
|
||||||
[ c-scripting-core] Creating script environments for pma-voice
|
|
||||||
[ resources] Started resource pma-voice
|
|
||||||
[ c-scripting-core] Creating script environments for screenshot-basic
|
|
||||||
[ resources] Started resource screenshot-basic
|
|
||||||
[ resources] Started resource skinchanger
|
|
||||||
[ c-scripting-core] Creating script environments for ui-base
|
|
||||||
[ resources] Started resource ui-base
|
|
||||||
[ c-scripting-core] Creating script environments for ui_context
|
|
||||||
[ resources] Started resource ui_context
|
|
||||||
[ c-scripting-core] Creating script environments for ui_hud
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.png` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources] Started resource ui_hud (4 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_identity
|
|
||||||
[ resources] Started resource ui_identity
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:13)
|
|
||||||
[ resources] Started resource ui_lscreen (3 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_skin
|
|
||||||
[ resources] Started resource ui_skin
|
|
||||||
[ c-scripting-core] Creating script environments for ui_multicharacter
|
|
||||||
[ resources] Started resource ui_multicharacter
|
|
||||||
[ c-scripting-core] Creating script environments for ui_notify
|
|
||||||
[ resources] Started resource ui_notify
|
|
||||||
[ c-scripting-core] Creating script environments for ui_pmenu
|
|
||||||
[ resources] Started resource ui_pmenu
|
|
||||||
[ c-scripting-core] Creating script environments for ui_progressbar
|
|
||||||
[ resources] Started resource ui_progressbar
|
|
||||||
[ c-scripting-core] Creating script environments for ui_textui
|
|
||||||
[ resources] Started resource ui_textui
|
|
||||||
[ c-scripting-core] Creating script environments for xsound
|
|
||||||
[ resources] Started resource xsound
|
|
||||||
[ resources] Started resource bob74_ipl
|
|
||||||
[ citizen-server-impl] You lack the required entitlement to use ui-bodyremaster
|
|
||||||
[ citizen-server-impl] Couldn't start resource ui-bodyremaster.
|
|
||||||
[ resources] Started resource ui-faceremaster
|
|
||||||
[ resources] Started resource ui-pressence
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_furn.ydr uses 40.0 MiB of physical memory.
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_shell.ydr uses 42.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource Airport_Pegasus_LSIA (2 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for AutoExotic
|
|
||||||
[ script:AutoExotic] Map successfully loaded
|
|
||||||
[resources:AutoExotic] Asset AutoExotic/as_autoexotic_txt.ytd uses 22.5 MiB of physical memory.
|
|
||||||
[ resources] Started resource AutoExotic (1 warning)
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_shell.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_stairs.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource TiboMLO_appart1 (2 warnings)
|
|
||||||
[ resources] Started resource ajaxon_aldore_hospital
|
|
||||||
[ resources] Started resource ajaxon_mapdata
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07.ytd uses 31.8 MiB of physical memory.
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07_hi.yft uses 16.7 MiB of virtual memory.
|
|
||||||
[ resources] Started resource bmwg07 (2 warnings)
|
|
||||||
[ resources] Started resource dev_warehouse
|
|
||||||
[ resources] Started resource expolregent
|
|
||||||
[ resources] Started resource expolscout
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.yft uses 23.8 MiB of virtual memory.
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.ytd uses 62.0 MiB of physical memory. Oversized assets can and WILL lead to streaming issues (such as models not loading/rendering).
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60_hi.yft uses 20.2 MiB of virtual memory.
|
|
||||||
[ resources] Started resource m5g60 (3 warnings)
|
|
||||||
[ resources] Started resource moreo_parkings
|
|
||||||
[ resources] Started resource uf_fleecabank
|
|
||||||
[ resources] Started resource uf_mapdata
|
|
||||||
[ c-scripting-core] Creating script environments for ui-postals
|
|
||||||
[ resources] Started resource ui-postals
|
|
||||||
[ citizen-server-main] Warning: The players.json endpoint has been modified to no longer return the player identifiers without authentication.
|
|
||||||
[ citizen-server-main] To learn more about this change read our announcement at https://forum.cfx.re/t/celebrating-one-year-with-rockstar-games/5269938#fivem-and-redm-6
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 268 milliseconds
|
|
||||||
[ citizen-server-impl] fff
|
|
||||||
[ citizen-server-impl] cccc ff xx xx rr rr eee
|
|
||||||
[ citizen-server-impl] cc ffff xx rrr r ee e
|
|
||||||
[ citizen-server-impl] cc ff xx ... rr eeeee
|
|
||||||
[ citizen-server-impl] ccccc ff xx xx ... rr eeeee
|
|
||||||
[ citizen-server-impl]
|
|
||||||
[ citizen-server-impl] Authenticated with cfx.re Nucleus: https://androxaaa-j98bka.users.cfx.re/
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 205 milliseconds
|
|
||||||
[ script:oxmysql] [8.0.41-0ubuntu0.24.04.1] Database server connection established!
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Database contains 48 items.
|
|
||||||
[ script:ui_core] [^ui_core] ^CORE 1.10.8 initialized!
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 418 milliseconds
|
|
||||||
[ script:ox_lib] An update is available for ox_inventory (current version: 2.42.3)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_inventory/releases/tag/v2.44.1
|
|
||||||
[ script:ox_lib] An update is available for ox_lib (current version: 3.26.0)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_lib/releases/tag/v3.30.3
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 772 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 1365 milliseconds
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Inventory has loaded 262 items
|
|
||||||
[ script:oxmysql] An update is available for oxmysql (current version: 2.11.2)
|
|
||||||
[ script:oxmysql] https://github.com/overextended/oxmysql/releases/tag/v2.13.0
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 11524 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 279 milliseconds
|
|
||||||
║ TXADMIN║ txaEvent "serverShuttingDown" "{\"delay\":5000,\"author\":\"androxaaa\",\"message\":\"Server restarting (admin request).\"}"
|
|
||||||
[ script:monitor] [txAdmin] Server shutting down. Kicking all players.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [6502] FXServer Starting - 3/17/2025, 1:25:19 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ citizen-server-impl] The file icon.png must be a 96x96 PNG image to be used as icon.
|
|
||||||
[ c-scripting-core] Creating script environments for yarn
|
|
||||||
[ resources] Started resource yarn
|
|
||||||
[ c-scripting-core] Creating script environments for webpack
|
|
||||||
[ resources] Started resource webpack
|
|
||||||
[ c-scripting-core] Creating script environments for chat
|
|
||||||
[ resources] Started resource chat
|
|
||||||
[ resources] Started resource spawnmanager
|
|
||||||
[ c-scripting-core] Creating script environments for hardcap
|
|
||||||
[ resources] Started resource hardcap
|
|
||||||
[ c-scripting-core] Creating script environments for rconlog
|
|
||||||
[ resources] Started resource rconlog
|
|
||||||
[ resources] Started resource chat-theme-gtao
|
|
||||||
[ c-scripting-core] Creating script environments for oxmysql
|
|
||||||
[ resources] Started resource oxmysql
|
|
||||||
[ c-scripting-core] Creating script environments for ui_core
|
|
||||||
[ resources] Started resource ui_core
|
|
||||||
[ c-scripting-core] Creating script environments for PolyZone
|
|
||||||
[ resources] Started resource PolyZone
|
|
||||||
[ c-scripting-core] Creating script environments for cron
|
|
||||||
[ resources] Started resource cron
|
|
||||||
[ resources] Started resource esx_menu_default
|
|
||||||
[ resources] Started resource esx_menu_dialog
|
|
||||||
[ resources] Started resource esx_menu_list
|
|
||||||
[ c-scripting-core] Creating script environments for ox_lib
|
|
||||||
[ resources] Started resource ox_lib
|
|
||||||
[ c-scripting-core] Creating script environments for ox_inventory
|
|
||||||
[ resources] Started resource ox_inventory
|
|
||||||
[ c-scripting-core] Creating script environments for pma-voice
|
|
||||||
[ resources] Started resource pma-voice
|
|
||||||
[ c-scripting-core] Creating script environments for screenshot-basic
|
|
||||||
[ resources] Started resource screenshot-basic
|
|
||||||
[ resources] Started resource skinchanger
|
|
||||||
[ c-scripting-core] Creating script environments for ui-base
|
|
||||||
[ resources] Started resource ui-base
|
|
||||||
[ c-scripting-core] Creating script environments for ui_context
|
|
||||||
[ resources] Started resource ui_context
|
|
||||||
[ c-scripting-core] Creating script environments for ui_hud
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.png` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources] Started resource ui_hud (4 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_identity
|
|
||||||
[ resources] Started resource ui_identity
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:13)
|
|
||||||
[ resources] Started resource ui_lscreen (3 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_skin
|
|
||||||
[ resources] Started resource ui_skin
|
|
||||||
[ c-scripting-core] Creating script environments for ui_multicharacter
|
|
||||||
[ resources] Started resource ui_multicharacter
|
|
||||||
[ c-scripting-core] Creating script environments for ui_notify
|
|
||||||
[ resources] Started resource ui_notify
|
|
||||||
[ c-scripting-core] Creating script environments for ui_pmenu
|
|
||||||
[ resources] Started resource ui_pmenu
|
|
||||||
[ c-scripting-core] Creating script environments for ui_progressbar
|
|
||||||
[ resources] Started resource ui_progressbar
|
|
||||||
[ c-scripting-core] Creating script environments for ui_textui
|
|
||||||
[ resources] Started resource ui_textui
|
|
||||||
[ c-scripting-core] Creating script environments for xsound
|
|
||||||
[ resources] Started resource xsound
|
|
||||||
[ resources] Started resource bob74_ipl
|
|
||||||
[ citizen-server-impl] You lack the required entitlement to use ui-bodyremaster
|
|
||||||
[ citizen-server-impl] Couldn't start resource ui-bodyremaster.
|
|
||||||
[ resources] Started resource ui-faceremaster
|
|
||||||
[ resources] Started resource ui-pressence
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_furn.ydr uses 40.0 MiB of physical memory.
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_shell.ydr uses 42.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource Airport_Pegasus_LSIA (2 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for AutoExotic
|
|
||||||
[ script:AutoExotic] Map successfully loaded
|
|
||||||
[resources:AutoExotic] Asset AutoExotic/as_autoexotic_txt.ytd uses 22.5 MiB of physical memory.
|
|
||||||
[ resources] Started resource AutoExotic (1 warning)
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_shell.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_stairs.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource TiboMLO_appart1 (2 warnings)
|
|
||||||
[ resources] Started resource ajaxon_aldore_hospital
|
|
||||||
[ resources] Started resource ajaxon_mapdata
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07.ytd uses 31.8 MiB of physical memory.
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07_hi.yft uses 16.7 MiB of virtual memory.
|
|
||||||
[ resources] Started resource bmwg07 (2 warnings)
|
|
||||||
[ resources] Started resource dev_warehouse
|
|
||||||
[ resources] Started resource expolregent
|
|
||||||
[ resources] Started resource expolscout
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.yft uses 23.8 MiB of virtual memory.
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.ytd uses 62.0 MiB of physical memory. Oversized assets can and WILL lead to streaming issues (such as models not loading/rendering).
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60_hi.yft uses 20.2 MiB of virtual memory.
|
|
||||||
[ resources] Started resource m5g60 (3 warnings)
|
|
||||||
[ resources] Started resource moreo_parkings
|
|
||||||
[ resources] Started resource uf_fleecabank
|
|
||||||
[ resources] Started resource uf_mapdata
|
|
||||||
[ c-scripting-core] Creating script environments for ui-postals
|
|
||||||
[ resources] Started resource ui-postals
|
|
||||||
[ citizen-server-main] Warning: The players.json endpoint has been modified to no longer return the player identifiers without authentication.
|
|
||||||
[ citizen-server-main] To learn more about this change read our announcement at https://forum.cfx.re/t/celebrating-one-year-with-rockstar-games/5269938#fivem-and-redm-6
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 273 milliseconds
|
|
||||||
[ citizen-server-impl] fff
|
|
||||||
[ citizen-server-impl] cccc ff xx xx rr rr eee
|
|
||||||
[ citizen-server-impl] cc ffff xx rrr r ee e
|
|
||||||
[ citizen-server-impl] cc ff xx ... rr eeeee
|
|
||||||
[ citizen-server-impl] ccccc ff xx xx ... rr eeeee
|
|
||||||
[ citizen-server-impl]
|
|
||||||
[ citizen-server-impl] Authenticated with cfx.re Nucleus: https://androxaaa-j98bka.users.cfx.re/
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 204 milliseconds
|
|
||||||
[ script:oxmysql] [8.0.41-0ubuntu0.24.04.1] Database server connection established!
|
|
||||||
[ script:ui_core] [^ui_core] ^CORE 1.10.8 initialized!
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Database contains 48 items.
|
|
||||||
[ script:oxmysql] [8.0.41-0ubuntu0.24.04.1] ox_inventory took 1179.0976ms to execute a query!
|
|
||||||
[ script:oxmysql] DELETE FROM ox_inventory WHERE lastupdated < (NOW() - INTERVAL 6 MONTH) []
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 1200 milliseconds
|
|
||||||
[ script:ox_lib] An update is available for ox_lib (current version: 3.26.0)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_lib/releases/tag/v3.30.3
|
|
||||||
[ script:ox_lib] An update is available for ox_inventory (current version: 2.42.3)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_inventory/releases/tag/v2.44.1
|
|
||||||
[ script:oxmysql] An update is available for oxmysql (current version: 2.11.2)
|
|
||||||
[ script:oxmysql] https://github.com/overextended/oxmysql/releases/tag/v2.13.0
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 705 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 354 milliseconds
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Inventory has loaded 262 items
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 341 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 11676 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 240 milliseconds
|
|
||||||
[ script:hardcap] Connecting: androxa
|
|
||||||
[ script:hardcap] Connecting: androxa
|
|
||||||
[ script:ui_core] [INFO] Player "Artem Medvedev" has connected to the server. ID: 1
|
|
||||||
[ script:ui_core] [ERROR] Tried to spawn invalid vehicle - leegy!
|
|
||||||
[ script:ui_core] [INFO] Saved player "Artem Medvedev"
|
|
||||||
[ citizen-server-main] -> Quitting: SIGINT received
|
|
||||||
[ citizen-server-main] -> Quitting: host shutting down
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [6784] FXServer Starting - 3/17/2025, 1:29:19 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [6901] FXServer Starting - 3/17/2025, 1:29:25 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7028] FXServer Starting - 3/17/2025, 1:29:36 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7144] FXServer Starting - 3/17/2025, 1:30:12 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7263] FXServer Starting - 3/17/2025, 1:30:33 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7379] FXServer Starting - 3/17/2025, 1:30:59 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7522] FXServer Starting - 3/17/2025, 1:31:30 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7639] FXServer Starting - 3/17/2025, 1:32:06 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7769] FXServer Starting - 3/17/2025, 1:32:47 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [7889] FXServer Starting - 3/17/2025, 1:33:33 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [8018] FXServer Starting - 3/17/2025, 1:34:20 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [8136] FXServer Starting - 3/17/2025, 1:35:06 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [8254] FXServer Starting - 3/17/2025, 1:35:52 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ net-tcp-server] Listening on socket failed - libuv error EADDRINUSE.
|
|
||||||
[ net-tcp-server] error on connection: address already in use
|
|
||||||
║ STDERR║ Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl] Error: Could not bind on 0.0.0.0:30120 - is this address valid and not already in use?
|
|
||||||
[ citizen-server-impl]
|
|
||||||
║ TXADMIN║ Restarting server: Server process close detected.
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
║ TXADMIN║ ======== [8486] FXServer Starting - 3/17/2025, 1:36:26 PM
|
|
||||||
║ TXADMIN║ ================================================================
|
|
||||||
[ resources] Scanning resources.
|
|
||||||
[resources:oulsen_sat] Warning: oulsen_satmap-main does not have a resource manifest (fxmanifest.lua)
|
|
||||||
[ resources] Found 70 resources.
|
|
||||||
[ resources] 1 warning was encountered.
|
|
||||||
[ svadhesive] Authenticating server license key...
|
|
||||||
[ svadhesive] Server license key authentication succeeded. Welcome!
|
|
||||||
[ c-scripting-core] Creating script environments for sessionmanager
|
|
||||||
[ resources] Started resource sessionmanager
|
|
||||||
[ c-scripting-core] Creating script environments for monitor
|
|
||||||
[ script:monitor] [txAdmin] Resource v8.0.1 threads and commands set up. All Ready.
|
|
||||||
[ resources] Started resource monitor
|
|
||||||
[ citizen-server-impl] The file icon.png must be a 96x96 PNG image to be used as icon.
|
|
||||||
[ c-scripting-core] Creating script environments for yarn
|
|
||||||
[ resources] Started resource yarn
|
|
||||||
[ c-scripting-core] Creating script environments for webpack
|
|
||||||
[ resources] Started resource webpack
|
|
||||||
[ c-scripting-core] Creating script environments for chat
|
|
||||||
[ resources] Started resource chat
|
|
||||||
[ resources] Started resource spawnmanager
|
|
||||||
[ c-scripting-core] Creating script environments for hardcap
|
|
||||||
[ resources] Started resource hardcap
|
|
||||||
[ c-scripting-core] Creating script environments for rconlog
|
|
||||||
[ resources] Started resource rconlog
|
|
||||||
[ resources] Started resource chat-theme-gtao
|
|
||||||
[ c-scripting-core] Creating script environments for oxmysql
|
|
||||||
[ resources] Started resource oxmysql
|
|
||||||
[ c-scripting-core] Creating script environments for ui_core
|
|
||||||
[ resources] Started resource ui_core
|
|
||||||
[ c-scripting-core] Creating script environments for PolyZone
|
|
||||||
[ resources] Started resource PolyZone
|
|
||||||
[ c-scripting-core] Creating script environments for cron
|
|
||||||
[ resources] Started resource cron
|
|
||||||
[ resources] Started resource esx_menu_default
|
|
||||||
[ resources] Started resource esx_menu_dialog
|
|
||||||
[ resources] Started resource esx_menu_list
|
|
||||||
[ c-scripting-core] Creating script environments for ox_lib
|
|
||||||
[ resources] Started resource ox_lib
|
|
||||||
[ c-scripting-core] Creating script environments for ox_inventory
|
|
||||||
[ resources] Started resource ox_inventory
|
|
||||||
[ c-scripting-core] Creating script environments for pma-voice
|
|
||||||
[ resources] Started resource pma-voice
|
|
||||||
[ c-scripting-core] Creating script environments for screenshot-basic
|
|
||||||
[ resources] Started resource screenshot-basic
|
|
||||||
[ resources] Started resource skinchanger
|
|
||||||
[ c-scripting-core] Creating script environments for ui-base
|
|
||||||
[ resources] Started resource ui-base
|
|
||||||
[ c-scripting-core] Creating script environments for ui_context
|
|
||||||
[ resources] Started resource ui_context
|
|
||||||
[ c-scripting-core] Creating script environments for ui_hud
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources:ui_hud] Warning: could not find file `ui/dist/assets/*.png` (defined in fxmanifest.lua:25)
|
|
||||||
[ resources] Started resource ui_hud (4 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_identity
|
|
||||||
[ resources] Started resource ui_identity
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/index.html` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.css` (defined in fxmanifest.lua:13)
|
|
||||||
[resources:ui_lscreen] Warning: could not find file `ui/dist/assets/*.js` (defined in fxmanifest.lua:13)
|
|
||||||
[ resources] Started resource ui_lscreen (3 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for ui_skin
|
|
||||||
[ resources] Started resource ui_skin
|
|
||||||
[ c-scripting-core] Creating script environments for ui_multicharacter
|
|
||||||
[ resources] Started resource ui_multicharacter
|
|
||||||
[ c-scripting-core] Creating script environments for ui_notify
|
|
||||||
[ resources] Started resource ui_notify
|
|
||||||
[ c-scripting-core] Creating script environments for ui_pmenu
|
|
||||||
[ resources] Started resource ui_pmenu
|
|
||||||
[ c-scripting-core] Creating script environments for ui_progressbar
|
|
||||||
[ resources] Started resource ui_progressbar
|
|
||||||
[ c-scripting-core] Creating script environments for ui_textui
|
|
||||||
[ resources] Started resource ui_textui
|
|
||||||
[ c-scripting-core] Creating script environments for xsound
|
|
||||||
[ resources] Started resource xsound
|
|
||||||
[ resources] Started resource bob74_ipl
|
|
||||||
[ citizen-server-impl] You lack the required entitlement to use ui-bodyremaster
|
|
||||||
[ citizen-server-impl] Couldn't start resource ui-bodyremaster.
|
|
||||||
[ resources] Started resource ui-faceremaster
|
|
||||||
[ resources] Started resource ui-pressence
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_furn.ydr uses 40.0 MiB of physical memory.
|
|
||||||
[resources:Airport_Pe] Asset Airport_Pegasus_LSIA/t_aircraft_dealership_shell.ydr uses 42.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource Airport_Pegasus_LSIA (2 warnings)
|
|
||||||
[ c-scripting-core] Creating script environments for AutoExotic
|
|
||||||
[ script:AutoExotic] Map successfully loaded
|
|
||||||
[resources:AutoExotic] Asset AutoExotic/as_autoexotic_txt.ytd uses 22.5 MiB of physical memory.
|
|
||||||
[ resources] Started resource AutoExotic (1 warning)
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_shell.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[resources:TiboMLO_ap] Asset TiboMLO_appart1/appart_stairs.ydr uses 24.0 MiB of physical memory.
|
|
||||||
[ resources] Started resource TiboMLO_appart1 (2 warnings)
|
|
||||||
[ resources] Started resource ajaxon_aldore_hospital
|
|
||||||
[ resources] Started resource ajaxon_mapdata
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07.ytd uses 31.8 MiB of physical memory.
|
|
||||||
[resources:bmwg07:str] Asset bmwg07/bmwg07_hi.yft uses 16.7 MiB of virtual memory.
|
|
||||||
[ resources] Started resource bmwg07 (2 warnings)
|
|
||||||
[ resources] Started resource dev_warehouse
|
|
||||||
[ resources] Started resource expolregent
|
|
||||||
[ resources] Started resource expolscout
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.yft uses 23.8 MiB of virtual memory.
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60.ytd uses 62.0 MiB of physical memory. Oversized assets can and WILL lead to streaming issues (such as models not loading/rendering).
|
|
||||||
[resources:m5g60:stre] Asset m5g60/m5g60_hi.yft uses 20.2 MiB of virtual memory.
|
|
||||||
[ resources] Started resource m5g60 (3 warnings)
|
|
||||||
[ resources] Started resource moreo_parkings
|
|
||||||
[ resources] Started resource uf_fleecabank
|
|
||||||
[ resources] Started resource uf_mapdata
|
|
||||||
[ c-scripting-core] Creating script environments for ui-postals
|
|
||||||
[ resources] Started resource ui-postals
|
|
||||||
[ citizen-server-main] Warning: The players.json endpoint has been modified to no longer return the player identifiers without authentication.
|
|
||||||
[ citizen-server-main] To learn more about this change read our announcement at https://forum.cfx.re/t/celebrating-one-year-with-rockstar-games/5269938#fivem-and-redm-6
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 276 milliseconds
|
|
||||||
[ citizen-server-impl] fff
|
|
||||||
[ citizen-server-impl] cccc ff xx xx rr rr eee
|
|
||||||
[ citizen-server-impl] cc ffff xx rrr r ee e
|
|
||||||
[ citizen-server-impl] cc ff xx ... rr eeeee
|
|
||||||
[ citizen-server-impl] ccccc ff xx xx ... rr eeeee
|
|
||||||
[ citizen-server-impl]
|
|
||||||
[ citizen-server-impl] Authenticated with cfx.re Nucleus: https://androxaaa-j98bka.users.cfx.re/
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 223 milliseconds
|
|
||||||
[ script:oxmysql] [8.0.41-0ubuntu0.24.04.1] Database server connection established!
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Database contains 48 items.
|
|
||||||
[ script:ui_core] [^ui_core] ^CORE 1.10.8 initialized!
|
|
||||||
[ script:oxmysql] [8.0.41-0ubuntu0.24.04.1] ox_inventory took 1161.1394ms to execute a query!
|
|
||||||
[ script:oxmysql] DELETE FROM ox_inventory WHERE lastupdated < (NOW() - INTERVAL 6 MONTH) []
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 1520 milliseconds
|
|
||||||
[ script:ox_lib] An update is available for ox_lib (current version: 3.26.0)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_lib/releases/tag/v3.30.3
|
|
||||||
[ script:ox_lib] An update is available for ox_inventory (current version: 2.42.3)
|
|
||||||
[ script:ox_lib] https://github.com/overextended/ox_inventory/releases/tag/v2.44.1
|
|
||||||
[ script:oxmysql] An update is available for oxmysql (current version: 2.11.2)
|
|
||||||
[ script:oxmysql] https://github.com/overextended/oxmysql/releases/tag/v2.13.0
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 350 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 686 milliseconds
|
|
||||||
[ script:ox_inventory] [ox_inventory] [INFO] Inventory has loaded 262 items
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 11885 milliseconds
|
|
||||||
[ citizen-server-impl] server thread hitch warning: timer interval of 238 milliseconds
|
|
||||||
|
|||||||
@ -1673,22 +1673,3 @@
|
|||||||
[4:07:46 PM] [yNtpe#1] androxa: said "/-menu_default_backspace"
|
[4:07:46 PM] [yNtpe#1] androxa: said "/-menu_default_backspace"
|
||||||
[4:07:46 PM] [yNtpe#1] androxa: said "/-cancelprog"
|
[4:07:46 PM] [yNtpe#1] androxa: said "/-cancelprog"
|
||||||
[4:38:56 PM] [yNtpe#1] androxa: disconnected (Exiting)
|
[4:38:56 PM] [yNtpe#1] androxa: disconnected (Exiting)
|
||||||
================================================================
|
|
||||||
======== txAdmin v8.0.1 atop fxserver 13227 Starting - 3/17/2025, 1:18:59 PM
|
|
||||||
================================================================
|
|
||||||
[1:19:02 PM] txAdmin: Logger started
|
|
||||||
[1:22:49 PM] [mmTfi#1] androxa: joined with identifiers [license:7b8f…6f17, xbl:2535…6052, live:9851…7864, discord:2042…1169, license2:266e…9f41]
|
|
||||||
[1:23:53 PM] [mmTfi#1] androxa: said "asd"
|
|
||||||
[1:24:32 PM] [mmTfi#1] androxa: said "/exit"
|
|
||||||
[1:24:49 PM] txAdmin: Logger started
|
|
||||||
[1:25:22 PM] txAdmin: Logger started
|
|
||||||
[1:26:42 PM] [cE7cA#1] androxa: joined with identifiers [license:7b8f…6f17, xbl:2535…6052, live:9851…7864, discord:2042…1169, license2:266e…9f41]
|
|
||||||
[1:27:09 PM] [cE7cA#1] androxa: said "/ui"
|
|
||||||
[1:28:39 PM] [cE7cA#1] androxa: disconnected (Exiting)
|
|
||||||
================================================================
|
|
||||||
======== txAdmin v8.0.1 atop fxserver 12746 Starting - 3/17/2025, 1:29:19 PM
|
|
||||||
================================================================
|
|
||||||
================================================================
|
|
||||||
======== txAdmin v8.0.1 atop fxserver 12746 Starting - 3/17/2025, 1:36:25 PM
|
|
||||||
================================================================
|
|
||||||
[1:36:29 PM] txAdmin: Logger started
|
|
||||||
|
|||||||
Reference in New Issue
Block a user