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"
|
||||
### 2025-03-16 15:09:04.329
|
||||
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'
|
||||
author 'Overextended'
|
||||
version '3.30.3'
|
||||
version '3.26.0'
|
||||
license 'LGPL-3.0-or-later'
|
||||
repository 'https://github.com/overextended/ox_lib'
|
||||
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')
|
||||
|
||||
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 }
|
||||
|
||||
---@private
|
||||
@ -25,63 +19,18 @@ function lib.array:__newindex(index, value)
|
||||
rawset(self, index, value)
|
||||
end
|
||||
|
||||
---Creates a new array from an iteratable value.
|
||||
---@param iter table | function | string
|
||||
---@return Array
|
||||
function lib.array:from(iter)
|
||||
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)
|
||||
---Create a new array containing the elements from two arrays.
|
||||
---@param arr ArrayLike
|
||||
function lib.array:merge(arr)
|
||||
local newArr = table.clone(self)
|
||||
local length = #self
|
||||
local arrays = { ... }
|
||||
|
||||
for i = 1, #arrays do
|
||||
local arr = arrays[i]
|
||||
|
||||
for j = 1, #arr do
|
||||
length += 1
|
||||
newArr[length] = arr[j]
|
||||
end
|
||||
for i = 1, #arr do
|
||||
length += 1
|
||||
newArr[length] = arr[i]
|
||||
end
|
||||
|
||||
return lib.array:new(table_unpack(newArr))
|
||||
return lib.array:new(table.unpack(newArr))
|
||||
end
|
||||
|
||||
---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
|
||||
end
|
||||
|
||||
---Sets all elements within a range to the given value and returns the modified array.
|
||||
---@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.
|
||||
---Creates a new array containing the elements from an array thtat pass the test of the provided function.
|
||||
---@param testFn fun(element: unknown): boolean
|
||||
function lib.array:filter(testFn)
|
||||
local newArr = {}
|
||||
@ -130,7 +60,7 @@ function lib.array:filter(testFn)
|
||||
end
|
||||
end
|
||||
|
||||
return lib.array:new(table_unpack(newArr))
|
||||
return lib.array:new(table.unpack(newArr))
|
||||
end
|
||||
|
||||
---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]
|
||||
|
||||
if element == value then
|
||||
return i
|
||||
return element
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -192,38 +122,15 @@ function lib.array:forEach(cb)
|
||||
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.
|
||||
---@param seperator? string
|
||||
function lib.array:join(seperator)
|
||||
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))
|
||||
return table.concat(self, seperator or ',')
|
||||
end
|
||||
|
||||
---Removes the last element from an array and returns the removed element.
|
||||
function lib.array:pop()
|
||||
return table_remove(self)
|
||||
return table.remove(self)
|
||||
end
|
||||
|
||||
---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
|
||||
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.
|
||||
---@generic T
|
||||
---@param reducer fun(accumulator: T, currentValue: T, index?: number): T
|
||||
---@param initialValue? T
|
||||
---@param reverse? boolean Iterate over the array from right-to-left.
|
||||
---@return T
|
||||
function lib.array:reduce(reducer, initialValue, reverse)
|
||||
local length = #self
|
||||
function lib.array:reduce(reducer, initialValue)
|
||||
local initialIndex = initialValue and 1 or 2
|
||||
local accumulator = initialValue or self[1]
|
||||
|
||||
if reverse then
|
||||
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)
|
||||
end
|
||||
for i = initialIndex, #self do
|
||||
accumulator = reducer(accumulator, self[i], i)
|
||||
end
|
||||
|
||||
return accumulator
|
||||
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.
|
||||
---@param tbl ArrayLike
|
||||
---@return boolean
|
||||
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
|
||||
return true
|
||||
|
||||
@ -5,12 +5,9 @@ local callbackTimeout = GetConvarInt('ox:callbackTimeout', 300000)
|
||||
|
||||
RegisterNetEvent(cbEvent:format(cache.resource), function(key, ...)
|
||||
local cb = pendingCallbacks[key]
|
||||
|
||||
if not cb then return end
|
||||
|
||||
pendingCallbacks[key] = nil
|
||||
|
||||
cb(...)
|
||||
return cb and cb(...)
|
||||
end)
|
||||
|
||||
---@param event string
|
||||
@ -44,19 +41,12 @@ local function triggerServerCallback(_, event, delay, cb, ...)
|
||||
key = ('%s:%s'):format(event, math.random(0, 100000))
|
||||
until not pendingCallbacks[key]
|
||||
|
||||
TriggerServerEvent('ox_lib:validateCallback', event, cache.resource, key)
|
||||
TriggerServerEvent(cbEvent:format(event), cache.resource, key, ...)
|
||||
|
||||
---@type promise | false
|
||||
local promise = not cb and promise.new()
|
||||
|
||||
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, ... }
|
||||
|
||||
if promise then
|
||||
@ -84,10 +74,6 @@ lib.callback = setmetatable({}, {
|
||||
else
|
||||
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))
|
||||
end
|
||||
|
||||
@ -123,11 +109,7 @@ local pcall = pcall
|
||||
---Registers an event handler and callback function to respond to server requests.
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function lib.callback.register(name, cb)
|
||||
event = cbEvent:format(name)
|
||||
|
||||
lib.setValidCallback(name, true)
|
||||
|
||||
RegisterNetEvent(event, function(resource, key, ...)
|
||||
RegisterNetEvent(cbEvent:format(name), function(resource, key, ...)
|
||||
TriggerServerEvent(cbEvent:format(resource), key, callbackResponse(pcall(cb, ...)))
|
||||
end)
|
||||
end
|
||||
|
||||
@ -4,12 +4,9 @@ local callbackTimeout = GetConvarInt('ox:callbackTimeout', 300000)
|
||||
|
||||
RegisterNetEvent(cbEvent:format(cache.resource), function(key, ...)
|
||||
local cb = pendingCallbacks[key]
|
||||
|
||||
if not cb then return end
|
||||
|
||||
pendingCallbacks[key] = nil
|
||||
|
||||
cb(...)
|
||||
return cb and cb(...)
|
||||
end)
|
||||
|
||||
---@param _ any
|
||||
@ -27,19 +24,12 @@ local function triggerClientCallback(_, event, playerId, cb, ...)
|
||||
key = ('%s:%s:%s'):format(event, math.random(0, 100000), playerId)
|
||||
until not pendingCallbacks[key]
|
||||
|
||||
TriggerClientEvent('ox_lib:validateCallback', playerId, event, cache.resource, key)
|
||||
TriggerClientEvent(cbEvent:format(event), playerId, cache.resource, key, ...)
|
||||
|
||||
---@type promise | false
|
||||
local promise = not cb and promise.new()
|
||||
|
||||
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, ... }
|
||||
|
||||
if promise then
|
||||
@ -67,10 +57,6 @@ lib.callback = setmetatable({}, {
|
||||
else
|
||||
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))
|
||||
end
|
||||
|
||||
@ -106,11 +92,7 @@ local pcall = pcall
|
||||
---Registers an event handler and callback function to respond to client requests.
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function lib.callback.register(name, cb)
|
||||
event = cbEvent:format(name)
|
||||
|
||||
lib.setValidCallback(name, true)
|
||||
|
||||
RegisterNetEvent(event, function(resource, key, ...)
|
||||
RegisterNetEvent(cbEvent:format(name), function(resource, key, ...)
|
||||
TriggerClientEvent(cbEvent:format(resource), source, key, callbackResponse(pcall(cb, source, ...)))
|
||||
end)
|
||||
end
|
||||
|
||||
@ -55,8 +55,10 @@ local function void() return '' end
|
||||
---@return T
|
||||
function mixins.new(class, ...)
|
||||
local constructor = getConstructor(class)
|
||||
local private = {}
|
||||
local obj = setmetatable({ private = private }, class)
|
||||
|
||||
local obj = setmetatable({
|
||||
private = {}
|
||||
}, class)
|
||||
|
||||
if constructor then
|
||||
local parent = class
|
||||
@ -73,8 +75,8 @@ function mixins.new(class, ...)
|
||||
|
||||
rawset(obj, 'super', nil)
|
||||
|
||||
if private ~= obj.private or next(obj.private) then
|
||||
private = table.clone(obj.private)
|
||||
if next(obj.private) then
|
||||
local private = table.clone(obj.private)
|
||||
|
||||
table.wipe(obj.private)
|
||||
setmetatable(obj.private, {
|
||||
|
||||
@ -7,27 +7,28 @@ local currentDate = {}
|
||||
setmetatable(currentDate, {
|
||||
__index = function(self, index)
|
||||
local newDate = os.date('*t') --[[@as Date]]
|
||||
|
||||
for k, v in pairs(newDate) do
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
SetTimeout(1000, function() table.wipe(self) end)
|
||||
|
||||
return self[index]
|
||||
end
|
||||
})
|
||||
|
||||
---@class OxTaskProperties
|
||||
---@field minute? number|string|function
|
||||
---@field hour? number|string|function
|
||||
---@field day? number|string|function
|
||||
---@field month? number|string|function
|
||||
---@field year? number|string|function
|
||||
---@field weekday? number|string|function
|
||||
---@field minute? number | string
|
||||
---@field hour? number | string
|
||||
---@field day? number | string
|
||||
---@field month? number | string
|
||||
---@field year? number | string
|
||||
---@field weekday? number | string
|
||||
---@field job fun(task: OxTask, date: osdate)
|
||||
---@field isActive boolean
|
||||
---@field id number
|
||||
---@field debug? boolean
|
||||
---@field lastRun? number
|
||||
---@field maxDelay? number Maximum allowed delay in seconds before skipping (0 to disable)
|
||||
|
||||
---@class OxTask : OxTaskProperties
|
||||
---@field expression string
|
||||
@ -35,14 +36,6 @@ setmetatable(currentDate, {
|
||||
local 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 = {
|
||||
min = 60,
|
||||
hour = 24,
|
||||
@ -51,23 +44,7 @@ local maxUnits = {
|
||||
month = 12,
|
||||
}
|
||||
|
||||
local weekdayMap = {
|
||||
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
|
||||
--- Gets the amount of days in certain month
|
||||
---@param month number
|
||||
---@param year? 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]]
|
||||
end
|
||||
|
||||
---@param value string|number
|
||||
---@param value string | number | nil
|
||||
---@param unit string
|
||||
---@return boolean
|
||||
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
|
||||
---@return string | number | false | nil
|
||||
local function getTimeUnit(value, unit)
|
||||
local currentTime = currentDate[unit]
|
||||
|
||||
@ -172,24 +62,25 @@ local function getTimeUnit(value, unit)
|
||||
return unit == 'min' and currentTime + 1 or currentTime
|
||||
end
|
||||
|
||||
if type(value) == 'function' then
|
||||
return value()
|
||||
end
|
||||
|
||||
local unitMax = maxUnits[unit]
|
||||
|
||||
if type(value) == 'string' then
|
||||
local stepValue = string.match(value, '*/(%d+)')
|
||||
|
||||
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
|
||||
if i % step == 0 then return i end
|
||||
-- if i is divisible by stepValue
|
||||
if i % stepValue == 0 then return i end
|
||||
end
|
||||
return step + unitMax
|
||||
|
||||
return stepValue + unitMax
|
||||
end
|
||||
|
||||
local range = string.match(value, '%d+-%d+')
|
||||
|
||||
if range then
|
||||
local min, max = string.strsplit('-', range)
|
||||
min, max = tonumber(min, 10), tonumber(max, 10)
|
||||
@ -206,15 +97,12 @@ local function getTimeUnit(value, unit)
|
||||
end
|
||||
|
||||
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
|
||||
local listValue = values[i]
|
||||
if list then
|
||||
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 currentTime < listValue then
|
||||
return listValue
|
||||
@ -224,47 +112,56 @@ local function getTimeUnit(value, unit)
|
||||
end
|
||||
end
|
||||
|
||||
return values[1] + unitMax
|
||||
-- if iterator failed, return the first value in the list
|
||||
return tonumber(string.match(value, '%d+')) + unitMax
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if unit == 'min' then
|
||||
return value <= currentTime and value + unitMax or value --[[@as number]]
|
||||
return value <= currentTime and value + unitMax or value
|
||||
end
|
||||
|
||||
return value < currentTime and value + unitMax or value --[[@as number]]
|
||||
return value < currentTime and value + unitMax or value
|
||||
end
|
||||
|
||||
---Get a timestamp for the next time to run the task today.
|
||||
---@return number?
|
||||
function OxTask:getNextTime()
|
||||
if not self.isActive then return end
|
||||
|
||||
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
|
||||
-- Should probably be used month from getTimeUnit, but don't want to reorder this code.
|
||||
day = getMaxDaysInMonth(currentDate.month)
|
||||
end
|
||||
|
||||
if day ~= currentDate.day then return end
|
||||
|
||||
local month = getTimeUnit(self.month, 'month')
|
||||
|
||||
if month ~= currentDate.month then return end
|
||||
|
||||
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')
|
||||
|
||||
if not minute then return end
|
||||
|
||||
local hour = getTimeUnit(self.hour, 'hour')
|
||||
|
||||
if not hour then return end
|
||||
|
||||
if minute >= maxUnits.min then
|
||||
if not self.hour then
|
||||
hour += math.floor(minute / maxUnits.min)
|
||||
end
|
||||
|
||||
minute = minute % maxUnits.min
|
||||
end
|
||||
|
||||
@ -272,31 +169,20 @@ function OxTask:getNextTime()
|
||||
if not self.day then
|
||||
day += math.floor(hour / maxUnits.hour)
|
||||
end
|
||||
|
||||
hour = hour % maxUnits.hour
|
||||
end
|
||||
|
||||
local nextTime = os.time({
|
||||
return os.time({
|
||||
min = minute,
|
||||
hour = hour,
|
||||
day = day or currentDate.day,
|
||||
month = month or currentDate.month,
|
||||
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
|
||||
|
||||
---Get timestamp for next time to run task at any day.
|
||||
---@return number
|
||||
function OxTask:getAbsoluteNextTime()
|
||||
local minute = getTimeUnit(self.minute, 'min')
|
||||
@ -305,6 +191,7 @@ function OxTask:getAbsoluteNextTime()
|
||||
local month = getTimeUnit(self.month, 'month')
|
||||
local year = getTimeUnit(self.year, 'year')
|
||||
|
||||
-- To avoid modifying getTimeUnit function, the day is adjusted here if needed.
|
||||
if self.day then
|
||||
if currentDate.hour < hour or (currentDate.hour == hour and currentDate.min < minute) then
|
||||
day = day - 1
|
||||
@ -322,6 +209,7 @@ function OxTask:getAbsoluteNextTime()
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if time will be in next year.
|
||||
---@diagnostic disable-next-line: assign-type-mismatch
|
||||
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
|
||||
@ -354,50 +242,40 @@ function OxTask:scheduleTask()
|
||||
local sleep = runAt - currentTime
|
||||
|
||||
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))
|
||||
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
|
||||
return self:stop(self.debug and ('scheduled time expired %s seconds ago'):format(-sleep))
|
||||
end
|
||||
|
||||
local timeAsString = self:getTimeAsString(runAt)
|
||||
|
||||
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 / 60))
|
||||
end
|
||||
|
||||
if sleep > 0 then
|
||||
Wait(sleep * 1000)
|
||||
else
|
||||
Wait(0)
|
||||
else -- will this even happen?
|
||||
Wait(1000)
|
||||
return true
|
||||
end
|
||||
|
||||
if self.isActive 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
|
||||
|
||||
Citizen.CreateThreadNow(function()
|
||||
self:job(currentDate)
|
||||
self.lastRun = os.time()
|
||||
end)
|
||||
|
||||
-- Wait(30000)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
---Start an inactive task.
|
||||
function OxTask:run()
|
||||
if self.isActive then return end
|
||||
|
||||
@ -413,20 +291,58 @@ function OxTask:stop(msg)
|
||||
|
||||
if self.debug 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
|
||||
|
||||
lib.print.debug(('stopping task %s'):format(self.id))
|
||||
print(('stopping task %s'):format(self.id))
|
||||
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 job fun(task: OxTask, date: osdate)
|
||||
---@param options? { debug?: boolean }
|
||||
---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`.
|
||||
---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)
|
||||
if not job or type(job) ~= 'function' then
|
||||
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.id = #tasks + 1
|
||||
task.job = job
|
||||
task.lastRun = nil
|
||||
task.maxDelay = task.maxDelay or 1
|
||||
tasks[task.id] = task
|
||||
task:run()
|
||||
|
||||
@ -456,6 +370,7 @@ end
|
||||
lib.cron.new('0 0 * * *', function()
|
||||
for i = 1, #tasks do
|
||||
local task = tasks[i]
|
||||
|
||||
if not task.isActive then
|
||||
task:run()
|
||||
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 defaultColor = { r = 255, g = 255, b = 255, a = 100 }
|
||||
local defaultSize = { width = 2, height = 1 }
|
||||
local defaultBobUpAndDown = false
|
||||
local defaultFaceCamera = true
|
||||
local defaultRotate = false
|
||||
local defaultTextureDict = nil
|
||||
local defaultTextureName = nil
|
||||
|
||||
@ -149,9 +152,9 @@ function lib.marker.new(options)
|
||||
self.height = options.height or defaultSize.height
|
||||
self.rotation = options.rotation or defaultRotation
|
||||
self.direction = options.direction or defaultDirection
|
||||
self.bobUpAndDown = type(options.bobUpAndDown) == 'boolean' and options.bobUpAndDown
|
||||
self.faceCamera = type(options.faceCamera) ~= 'boolean' or options.faceCamera
|
||||
self.rotate = type(options.rotate) == 'boolean' and options.rotate
|
||||
self.bobUpAndDown = options.bobUpAndDown or defaultBobUpAndDown
|
||||
self.faceCamera = options.faceCamera or defaultFaceCamera
|
||||
self.rotate = options.rotate or defaultRotate
|
||||
self.textureDict = options.textureDict or defaultTextureDict
|
||||
self.textureName = options.textureName or defaultTextureName
|
||||
self.draw = drawMarker
|
||||
|
||||
@ -26,93 +26,74 @@ local function removePoint(self)
|
||||
closestPoint = nil
|
||||
end
|
||||
|
||||
lib.grid.removeEntry(self)
|
||||
|
||||
points[self.id] = nil
|
||||
points[self.id] = nil
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
while true do
|
||||
while true do
|
||||
if nearbyCount ~= 0 then
|
||||
table.wipe(nearbyPoints)
|
||||
nearbyCount = 0
|
||||
table.wipe(nearbyPoints)
|
||||
nearbyCount = 0
|
||||
end
|
||||
|
||||
local coords = GetEntityCoords(cache.ped)
|
||||
cache.coords = coords
|
||||
|
||||
if closestPoint and #(coords - closestPoint.coords) > closestPoint.distance then
|
||||
closestPoint = nil
|
||||
end
|
||||
|
||||
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
|
||||
closestPoint = nil
|
||||
for _, point in pairs(points) do
|
||||
local distance = #(coords - point.coords)
|
||||
|
||||
if cellX ~= cache.lastCellX or cellY ~= cache.lastCellY then
|
||||
for i = 1, #nearbyPoints do
|
||||
local point = nearbyPoints[i]
|
||||
if distance <= point.distance then
|
||||
point.currentDistance = distance
|
||||
|
||||
if point.inside then
|
||||
local distance = #(coords - point.coords)
|
||||
|
||||
if distance > point.radius then
|
||||
if point.onExit then point:onExit() end
|
||||
|
||||
point.inside = nil
|
||||
point.currentDistance = nil
|
||||
if closestPoint then
|
||||
if distance < closestPoint.currentDistance then
|
||||
closestPoint.isClosest = nil
|
||||
point.isClosest = true
|
||||
closestPoint = point
|
||||
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
|
||||
|
||||
if not closestPoint or distance < (closestPoint.currentDistance or point.radius) then
|
||||
if closestPoint then closestPoint.isClosest = nil end
|
||||
|
||||
elseif distance < point.distance then
|
||||
point.isClosest = true
|
||||
closestPoint = point
|
||||
end
|
||||
|
||||
if point.nearby then
|
||||
if point.nearby then
|
||||
nearbyCount += 1
|
||||
nearbyPoints[nearbyCount] = point
|
||||
end
|
||||
|
||||
if point.onEnter and not point.inside then
|
||||
point.inside = true
|
||||
point:onEnter()
|
||||
end
|
||||
elseif point.currentDistance then
|
||||
if point.onExit then point:onExit() end
|
||||
if point.onEnter and not point.inside then
|
||||
point.inside = true
|
||||
point:onEnter()
|
||||
end
|
||||
elseif point.currentDistance then
|
||||
if point.onExit then point:onExit() end
|
||||
point.inside = nil
|
||||
point.currentDistance = nil
|
||||
end
|
||||
end
|
||||
|
||||
point.inside = nil
|
||||
point.currentDistance = nil
|
||||
end
|
||||
end
|
||||
|
||||
if not tick then
|
||||
if nearbyCount ~= 0 then
|
||||
tick = SetInterval(function()
|
||||
for i = nearbyCount, 1, -1 do
|
||||
if not tick then
|
||||
if nearbyCount ~= 0 then
|
||||
tick = SetInterval(function()
|
||||
for i = 1, nearbyCount do
|
||||
local point = nearbyPoints[i]
|
||||
|
||||
if point and point.nearby then
|
||||
if point then
|
||||
point:nearby()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
elseif nearbyCount == 0 then
|
||||
tick = ClearInterval(tick)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
elseif nearbyCount == 0 then
|
||||
tick = ClearInterval(tick)
|
||||
end
|
||||
|
||||
Wait(300)
|
||||
end
|
||||
Wait(300)
|
||||
end
|
||||
end)
|
||||
|
||||
local function toVector(coords)
|
||||
@ -129,52 +110,50 @@ local function toVector(coords)
|
||||
return coords
|
||||
end
|
||||
|
||||
lib.points = {}
|
||||
lib.points = {
|
||||
---@return CPoint
|
||||
---@overload fun(data: PointProperties): CPoint
|
||||
---@overload fun(coords: vector3, distance: number, data?: PointProperties): CPoint
|
||||
new = function(...)
|
||||
local args = {...}
|
||||
local id = #points + 1
|
||||
local self
|
||||
|
||||
---@return CPoint
|
||||
---@overload fun(data: PointProperties): CPoint
|
||||
---@overload fun(coords: vector3, distance: number, data?: PointProperties): CPoint
|
||||
function lib.points.new(...)
|
||||
local args = { ... }
|
||||
local id = #points + 1
|
||||
local self
|
||||
-- Support sending a single argument containing point data
|
||||
if type(args[1]) == 'table' then
|
||||
self = args[1]
|
||||
self.id = id
|
||||
self.remove = removePoint
|
||||
else
|
||||
-- Backwards compatibility for original implementation (args: coords, distance, data)
|
||||
self = {
|
||||
id = id,
|
||||
coords = args[1],
|
||||
remove = removePoint,
|
||||
}
|
||||
end
|
||||
|
||||
-- Support sending a single argument containing point data
|
||||
if type(args[1]) == 'table' then
|
||||
self = args[1]
|
||||
self.id = id
|
||||
self.remove = removePoint
|
||||
else
|
||||
-- Backwards compatibility for original implementation (args: coords, distance, data)
|
||||
self = {
|
||||
id = id,
|
||||
coords = args[1],
|
||||
remove = removePoint,
|
||||
}
|
||||
end
|
||||
self.coords = toVector(self.coords)
|
||||
self.distance = self.distance or args[2]
|
||||
|
||||
self.coords = toVector(self.coords)
|
||||
self.distance = self.distance or args[2]
|
||||
self.radius = self.distance
|
||||
if args[3] then
|
||||
for k, v in pairs(args[3]) do
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
if args[3] then
|
||||
for k, v in pairs(args[3]) do
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
points[id] = self
|
||||
|
||||
lib.grid.addEntry(self)
|
||||
points[id] = self
|
||||
return self
|
||||
end,
|
||||
|
||||
return self
|
||||
end
|
||||
getAllPoints = function() return points end,
|
||||
|
||||
function lib.points.getAllPoints() return points end
|
||||
getNearbyPoints = function() return nearbyPoints end,
|
||||
|
||||
function lib.points.getNearbyPoints() return nearbyPoints end
|
||||
|
||||
---@return CPoint?
|
||||
function lib.points.getClosestPoint() return closestPoint end
|
||||
---@return CPoint?
|
||||
getClosestPoint = function() return closestPoint end,
|
||||
}
|
||||
|
||||
---@deprecated
|
||||
lib.points.closest = lib.points.getClosestPoint
|
||||
|
||||
@ -14,12 +14,8 @@ local levelPrefixes = {
|
||||
'^4[VERBOSE]',
|
||||
'^6[DEBUG]',
|
||||
}
|
||||
local convarGlobal = 'ox:printlevel'
|
||||
local convarResource = 'ox:printlevel:' .. cache.resource
|
||||
local function getPrintLevelFromConvar()
|
||||
return printLevel[GetConvar(convarResource, GetConvar(convarGlobal, 'info'))]
|
||||
end
|
||||
local resourcePrintLevel = getPrintLevelFromConvar()
|
||||
|
||||
local resourcePrintLevel = printLevel[GetConvar('ox:printlevel:' .. cache.resource, GetConvar('ox:printlevel', 'info'))]
|
||||
local template = ('^5[%s] %%s %%s^7'):format(cache.resource)
|
||||
local function handleException(reason, value)
|
||||
if type(value) == 'function' then return tostring(value) end
|
||||
@ -52,14 +48,4 @@ lib.print = {
|
||||
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
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
function lib.requestAudioBank(audioBank, timeout)
|
||||
return lib.waitFor(function()
|
||||
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
|
||||
|
||||
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, ...)
|
||||
|
||||
-- i hate fivem developers
|
||||
lib.print.verbose(("Loading %s '%s' - remember to release it when done."):format(assetType, asset))
|
||||
|
||||
return lib.waitFor(function()
|
||||
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),
|
||||
timeout or 30000)
|
||||
if hasLoaded(asset) then return asset end
|
||||
end, ("failed to load %s '%s' - this is likely caused by unreleased assets"):format(assetType, asset), timeout or 10000)
|
||||
end
|
||||
|
||||
return lib.streamingRequest
|
||||
|
||||
@ -9,29 +9,24 @@ local pairs = pairs
|
||||
---@return boolean
|
||||
---Checks if tbl contains the given values. Only intended for simple values and unnested tables.
|
||||
local function contains(tbl, value)
|
||||
if type(value) ~= 'table' then
|
||||
for _, v in pairs(tbl) do
|
||||
if v == value then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if type(value) ~= 'table' then
|
||||
for _, v in pairs(tbl) do
|
||||
if v == value then return true end
|
||||
end
|
||||
else
|
||||
local matched_values = 0
|
||||
local values = 0
|
||||
for _, v1 in pairs(value) do
|
||||
values += 1
|
||||
|
||||
return false
|
||||
else
|
||||
local set = {}
|
||||
for _, v2 in pairs(tbl) do
|
||||
if v1 == v2 then matched_values += 1 end
|
||||
end
|
||||
end
|
||||
if matched_values == values then return true end
|
||||
end
|
||||
|
||||
for _, v in pairs(tbl) do
|
||||
set[v] = true
|
||||
end
|
||||
|
||||
for _, v in pairs(value) do
|
||||
if not set[v] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---@param t1 any
|
||||
@ -39,28 +34,22 @@ end
|
||||
---@return boolean
|
||||
---Compares if two values are equal, iterating over tables and matching both keys and values.
|
||||
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
|
||||
return false
|
||||
end
|
||||
for k1,v1 in pairs(t1) do
|
||||
local v2 = t2[k1]
|
||||
if v2 == nil or not table_matches(v1,v2) then return false end
|
||||
end
|
||||
|
||||
for k, v1 in pairs(t1) do
|
||||
local v2 = t2[k]
|
||||
if v2 == nil or not table_matches(v1, v2) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
for k2,v2 in pairs(t2) do
|
||||
local v1 = t1[k2]
|
||||
if v1 == nil or not table_matches(v1,v2) then return false end
|
||||
end
|
||||
|
||||
for k in pairs(t2) do
|
||||
if t1[k] == nil then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
return true
|
||||
end
|
||||
|
||||
---@generic T
|
||||
@ -68,15 +57,15 @@ end
|
||||
---@return T
|
||||
---Recursively clones a table to ensure no table references.
|
||||
local function table_deepclone(tbl)
|
||||
tbl = table.clone(tbl)
|
||||
tbl = table.clone(tbl)
|
||||
|
||||
for k, v in pairs(tbl) do
|
||||
if type(v) == 'table' then
|
||||
tbl[k] = table_deepclone(v)
|
||||
end
|
||||
end
|
||||
for k, v in pairs(tbl) do
|
||||
if type(v) == 'table' then
|
||||
tbl[k] = table_deepclone(v)
|
||||
end
|
||||
end
|
||||
|
||||
return tbl
|
||||
return tbl
|
||||
end
|
||||
|
||||
---@param t1 table
|
||||
@ -85,41 +74,27 @@ end
|
||||
---@return table
|
||||
---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)
|
||||
addDuplicateNumbers = addDuplicateNumbers == nil or addDuplicateNumbers
|
||||
for k, v2 in pairs(t2) do
|
||||
local v1 = t1[k]
|
||||
local type1 = type(v1)
|
||||
local type2 = type(v2)
|
||||
if addDuplicateNumbers == nil then addDuplicateNumbers = true end
|
||||
for k, v in pairs(t2) do
|
||||
local type1 = type(t1[k])
|
||||
local type2 = type(v)
|
||||
|
||||
if type1 == 'table' and type2 == 'table' then
|
||||
table_merge(v1, v2, addDuplicateNumbers)
|
||||
if type1 == 'table' and type2 == 'table' then
|
||||
table_merge(t1[k], v, addDuplicateNumbers)
|
||||
elseif addDuplicateNumbers and (type1 == 'number' and type2 == 'number') then
|
||||
t1[k] = v1 + v2
|
||||
else
|
||||
t1[k] = v2
|
||||
t1[k] += v
|
||||
else
|
||||
t1[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return t1
|
||||
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.matches = table_matches
|
||||
table.deepclone = table_deepclone
|
||||
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 _rawset = rawset
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
---@class TimerPrivateProps
|
||||
---@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 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
|
||||
@ -9,7 +10,6 @@
|
||||
---@class OxTimer : OxClass
|
||||
---@field private private TimerPrivateProps
|
||||
---@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 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
|
||||
@ -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(type(async) == "boolean" or async == nil, "async must be a boolean or nil")
|
||||
|
||||
self.onEnd = onEnd
|
||||
self.private.initialTime = time
|
||||
self.private.currentTimeLeft = time
|
||||
self.private.startTime = 0
|
||||
self.private.paused = false
|
||||
self.private.onEnd = onEnd
|
||||
self.private.triggerOnEnd = true
|
||||
|
||||
self:start(async)
|
||||
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)
|
||||
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()
|
||||
|
||||
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
|
||||
|
||||
Citizen.CreateThreadNow(function()
|
||||
self:run()
|
||||
end)
|
||||
if async then
|
||||
Citizen.CreateThreadNow(function()
|
||||
tick()
|
||||
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
|
||||
|
||||
function timer:forceEnd(triggerOnEnd)
|
||||
if self:getTimeLeft('ms') <= 0 then return end
|
||||
|
||||
self.private.triggerOnEnd = triggerOnEnd
|
||||
self.private.paused = false
|
||||
self.private.currentTimeLeft = 0
|
||||
self.private.triggerOnEnd = triggerOnEnd
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
function timer:pause()
|
||||
if self.private.paused then return end
|
||||
|
||||
self.private.currentTimeLeft = self:getTimeLeft('ms') --[[@as number]]
|
||||
self.private.paused = true
|
||||
end
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
local glm = require 'glm'
|
||||
|
||||
---@class ZoneProperties
|
||||
---@field debug? boolean
|
||||
---@field debugColour? vector4
|
||||
---@class CZone
|
||||
---@field id number
|
||||
---@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 onExit fun(self: CZone)?
|
||||
---@field inside fun(self: CZone)?
|
||||
---@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>
|
||||
local Zones = {}
|
||||
_ENV.Zones = Zones
|
||||
@ -97,66 +96,46 @@ local function getTriangles(polygon)
|
||||
return triangles
|
||||
end
|
||||
|
||||
local insideZones = lib.context == 'client' and {} --[[@as table<number, CZone>]]
|
||||
local exitingZones = lib.context == 'client' and lib.array:new() --[[@as Array<CZone>]]
|
||||
local enteringZones = lib.context == 'client' and lib.array:new() --[[@as Array<CZone>]]
|
||||
local nearbyZones = lib.array:new() --[[@as Array<CZone>]]
|
||||
local glm_polygon_contains = glm.polygon.contains
|
||||
---@type table<number, CZone>
|
||||
local insideZones = {}
|
||||
---@type table<number, CZone>
|
||||
local enteringZones = {}
|
||||
---@type table<number, CZone>
|
||||
local exitingZones = {}
|
||||
local enteringSize = 0
|
||||
local exitingSize = 0
|
||||
local tick
|
||||
local glm_polygon_contains = glm.polygon.contains
|
||||
|
||||
---@param zone CZone
|
||||
local function removeZone(zone)
|
||||
Zones[zone.id] = nil
|
||||
|
||||
lib.grid.removeEntry(zone)
|
||||
|
||||
if lib.context == 'server' then return end
|
||||
|
||||
insideZones[zone.id] = nil
|
||||
|
||||
table.remove(exitingZones, exitingZones:indexOf(zone))
|
||||
table.remove(enteringZones, enteringZones:indexOf(zone))
|
||||
local function removeZone(self)
|
||||
Zones[self.id] = nil
|
||||
insideZones[self.id] = nil
|
||||
enteringZones[self.id] = nil
|
||||
exitingZones[self.id] = nil
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
if lib.context == 'server' then return end
|
||||
|
||||
while true do
|
||||
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
|
||||
|
||||
if cellX ~= cache.lastCellX or cellY ~= cache.lastCellY then
|
||||
for i = 1, #nearbyZones do
|
||||
local zone = nearbyZones[i]
|
||||
for _, zone in pairs(Zones) do
|
||||
zone.distance = #(zone.coords - coords)
|
||||
local radius, contains = zone.radius, nil
|
||||
|
||||
if zone.insideZone then
|
||||
local contains = zone:contains(coords, true)
|
||||
|
||||
if not contains then
|
||||
zone.insideZone = false
|
||||
insideZones[zone.id] = nil
|
||||
end
|
||||
end
|
||||
if radius then
|
||||
contains = zone.distance < radius
|
||||
else
|
||||
contains = glm_polygon_contains(zone.polygon, coords, zone.thickness / 4)
|
||||
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 not zone.insideZone then
|
||||
zone.insideZone = true
|
||||
|
||||
if zone.onEnter then
|
||||
enteringZones:push(zone)
|
||||
enteringSize += 1
|
||||
enteringZones[enteringSize] = zone
|
||||
end
|
||||
|
||||
if zone.inside or zone.debug then
|
||||
@ -169,7 +148,8 @@ CreateThread(function()
|
||||
insideZones[zone.id] = nil
|
||||
|
||||
if zone.onExit then
|
||||
exitingZones:push(zone)
|
||||
exitingSize += 1
|
||||
exitingZones[exitingSize] = zone
|
||||
end
|
||||
end
|
||||
|
||||
@ -179,18 +159,16 @@ CreateThread(function()
|
||||
end
|
||||
end
|
||||
|
||||
local exitingSize = #exitingZones
|
||||
local enteringSize = #enteringZones
|
||||
|
||||
if exitingSize > 0 then
|
||||
table.sort(exitingZones, function(a, b)
|
||||
return a.distance < b.distance
|
||||
return a.distance > b.distance
|
||||
end)
|
||||
|
||||
for i = exitingSize, 1, -1 do
|
||||
for i = 1, exitingSize do
|
||||
exitingZones[i]:onExit()
|
||||
end
|
||||
|
||||
exitingSize = 0
|
||||
table.wipe(exitingZones)
|
||||
end
|
||||
|
||||
@ -203,6 +181,7 @@ CreateThread(function()
|
||||
enteringZones[i]:onEnter()
|
||||
end
|
||||
|
||||
enteringSize = 0
|
||||
table.wipe(enteringZones)
|
||||
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)
|
||||
end
|
||||
|
||||
local function contains(self, coords, updateDistance)
|
||||
if updateDistance then self.distance = #(self.coords - coords) end
|
||||
|
||||
local function contains(self, coords)
|
||||
return glm_polygon_contains(self.polygon, coords, self.thickness / 4)
|
||||
end
|
||||
|
||||
local function insideSphere(self, coords, updateDistance)
|
||||
local distance = #(self.coords - coords)
|
||||
|
||||
if updateDistance then self.distance = distance end
|
||||
|
||||
return distance < self.radius
|
||||
local function insideSphere(self, coords)
|
||||
return #(self.coords - coords) < self.radius
|
||||
end
|
||||
|
||||
local function convertToVector(coords)
|
||||
@ -318,14 +291,76 @@ local function setDebug(self, bool, colour)
|
||||
self.debug = self.__type == 'sphere' and debugSphere or debugPoly or nil
|
||||
end
|
||||
|
||||
---@param data ZoneProperties
|
||||
---@return CZone
|
||||
local function setZone(data)
|
||||
---@cast data CZone
|
||||
data.remove = removeZone
|
||||
data.contains = data.contains or contains
|
||||
lib.zones = {
|
||||
---@return CZone
|
||||
poly = function(data)
|
||||
data.id = #Zones + 1
|
||||
data.thickness = data.thickness or 4
|
||||
|
||||
if lib.context == 'client' then
|
||||
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)
|
||||
|
||||
if not data.polygon:isPlanar() then
|
||||
local zCoords = {}
|
||||
|
||||
for i = 1, pointN do
|
||||
local zCoord = points[i].z
|
||||
|
||||
if zCoords[zCoord] then
|
||||
zCoords[zCoord] += 1
|
||||
else
|
||||
zCoords[zCoord] = 1
|
||||
end
|
||||
end
|
||||
|
||||
local coordsArray = {}
|
||||
|
||||
for coord, count in pairs(zCoords) do
|
||||
coordsArray[#coordsArray + 1] = {
|
||||
coord = coord,
|
||||
count = count
|
||||
}
|
||||
end
|
||||
|
||||
table.sort(coordsArray, function(a, b)
|
||||
return a.count > b.count
|
||||
end)
|
||||
|
||||
local zCoord = coordsArray[1].coord
|
||||
local averageTo
|
||||
|
||||
for i = 1, #coordsArray do
|
||||
if coordsArray[i].count < coordsArray[1].count then
|
||||
averageTo = i - 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if averageTo > 1 then
|
||||
for i = 2, averageTo do
|
||||
zCoord += coordsArray[i].coord
|
||||
end
|
||||
|
||||
zCoord /= averageTo
|
||||
end
|
||||
|
||||
for i = 1, pointN do
|
||||
points[i] = vec3(data.points[i].xy, zCoord)
|
||||
end
|
||||
|
||||
data.polygon = glm.polygon.new(points)
|
||||
end
|
||||
|
||||
data.coords = data.polygon:centroid()
|
||||
data.__type = 'poly'
|
||||
data.remove = removeZone
|
||||
data.contains = contains
|
||||
data.setDebug = setDebug
|
||||
|
||||
if data.debug then
|
||||
@ -333,145 +368,60 @@ local function setZone(data)
|
||||
|
||||
data:setDebug(true, data.debugColour)
|
||||
end
|
||||
else
|
||||
data.debug = nil
|
||||
end
|
||||
|
||||
Zones[data.id] = data
|
||||
lib.grid.addEntry(data)
|
||||
Zones[data.id] = data
|
||||
return data
|
||||
end,
|
||||
|
||||
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.setDebug = setDebug
|
||||
|
||||
lib.zones = {}
|
||||
if data.debug then
|
||||
data.debug = nil
|
||||
|
||||
---@class PolyZone : ZoneProperties
|
||||
---@field points vector3[]
|
||||
---@field thickness? number
|
||||
|
||||
---@param data PolyZone
|
||||
---@return CZone
|
||||
function lib.zones.poly(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)
|
||||
|
||||
if not data.polygon:isPlanar() then
|
||||
local zCoords = {}
|
||||
|
||||
for i = 1, pointN do
|
||||
local zCoord = points[i].z
|
||||
|
||||
if zCoords[zCoord] then
|
||||
zCoords[zCoord] += 1
|
||||
else
|
||||
zCoords[zCoord] = 1
|
||||
end
|
||||
data:setDebug(true, data.debugColour)
|
||||
end
|
||||
|
||||
local coordsArray = {}
|
||||
Zones[data.id] = data
|
||||
return data
|
||||
end,
|
||||
|
||||
for coord, count in pairs(zCoords) do
|
||||
coordsArray[#coordsArray + 1] = {
|
||||
coord = coord,
|
||||
count = count
|
||||
}
|
||||
---@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.setDebug = setDebug
|
||||
|
||||
if data.debug then
|
||||
data:setDebug(true, data.debugColour)
|
||||
end
|
||||
|
||||
table.sort(coordsArray, function(a, b)
|
||||
return a.count > b.count
|
||||
end)
|
||||
Zones[data.id] = data
|
||||
return data
|
||||
end,
|
||||
|
||||
local zCoord = coordsArray[1].coord
|
||||
local averageTo = 1
|
||||
getAllZones = function() return Zones end,
|
||||
|
||||
for i = 1, #coordsArray do
|
||||
if coordsArray[i].count < coordsArray[1].count then
|
||||
averageTo = i - 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if averageTo > 1 then
|
||||
for i = 2, averageTo do
|
||||
zCoord += coordsArray[i].coord
|
||||
end
|
||||
|
||||
zCoord /= averageTo
|
||||
end
|
||||
|
||||
for i = 1, pointN do
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
points[i] = vec3(data.points[i].xy, zCoord)
|
||||
end
|
||||
|
||||
data.polygon = glm.polygon.new(points)
|
||||
end
|
||||
|
||||
data.coords = data.polygon:centroid()
|
||||
data.__type = 'poly'
|
||||
data.radius = lib.array.reduce(data.polygon, function(acc, point)
|
||||
local distance = #(point - data.coords)
|
||||
return distance > acc and distance or acc
|
||||
end, 0)
|
||||
|
||||
return setZone(data)
|
||||
end
|
||||
|
||||
---@class BoxZone : ZoneProperties
|
||||
---@field coords vector3
|
||||
---@field size? vector3
|
||||
---@field rotation? number | vector3 | vector4 | matrix
|
||||
|
||||
---@param data BoxZone
|
||||
---@return CZone
|
||||
function lib.zones.box(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
|
||||
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({
|
||||
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)
|
||||
|
||||
return setZone(data)
|
||||
end
|
||||
|
||||
---@class SphereZone : ZoneProperties
|
||||
---@field coords vector3
|
||||
---@field radius? number
|
||||
|
||||
---@param data SphereZone
|
||||
---@return CZone
|
||||
function lib.zones.sphere(data)
|
||||
data.id = #Zones + 1
|
||||
data.coords = convertToVector(data.coords)
|
||||
data.radius = (data.radius or 2) + 0.0
|
||||
data.__type = 'sphere'
|
||||
data.contains = insideSphere
|
||||
|
||||
return setZone(data)
|
||||
end
|
||||
|
||||
function lib.zones.getAllZones() return Zones end
|
||||
|
||||
function lib.zones.getCurrentZones() return insideZones end
|
||||
|
||||
function lib.zones.getNearbyZones() return nearbyZones end
|
||||
getCurrentZones = function() return insideZones end,
|
||||
}
|
||||
|
||||
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,
|
||||
})
|
||||
|
||||
_ENV.lib = lib
|
||||
|
||||
-- Override standard Lua require with our own.
|
||||
require = lib.require
|
||||
|
||||
local intervals = {}
|
||||
--- Dream of a world where this PR gets accepted.
|
||||
---@param callback function | number
|
||||
@ -210,9 +215,7 @@ function lib.onCache(key, cb)
|
||||
table.insert(cacheEvents[key], cb)
|
||||
end
|
||||
|
||||
_ENV.lib = lib
|
||||
_ENV.cache = cache
|
||||
_ENV.require = lib.require
|
||||
|
||||
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ų",
|
||||
"settings": "Nustatymai",
|
||||
"ui": {
|
||||
"cancel": "Atšaukti",
|
||||
"close": "Uždaryti",
|
||||
@ -10,17 +9,17 @@
|
||||
"locale": "Pakeisti kalbą",
|
||||
"locale_description": "Dabartinė: ${language} (%s)",
|
||||
"notification_audio": "Pranešimo garsas",
|
||||
"notification_position": "Pranešimo pozicija"
|
||||
"notification_position": "Notification position"
|
||||
},
|
||||
"position": {
|
||||
"bottom": "Apačioje",
|
||||
"bottom-left": "Apačioje-kairėje",
|
||||
"bottom-right": "Apačioje-dešinėje",
|
||||
"center-left": "Centre-kairėje",
|
||||
"center-right": "Centre-dešinėje",
|
||||
"top": "Viršuje",
|
||||
"top-left": "Viršuje-kairėje",
|
||||
"top-right": "Viršuje-dešinėje"
|
||||
"bottom": "Bottom",
|
||||
"bottom-left": "Bottom-left",
|
||||
"bottom-right": "Bottom-right",
|
||||
"center-left": "Center-left",
|
||||
"center-right": "Center-right",
|
||||
"top": "Top",
|
||||
"top-left": "Top-left",
|
||||
"top-right": "Top-right"
|
||||
}
|
||||
},
|
||||
"open_radial_menu": "Atidaryti radialinį meniu",
|
||||
|
||||
@ -1,30 +1,29 @@
|
||||
{
|
||||
"language": "Nederlands",
|
||||
"settings": "Instellingen",
|
||||
"ui": {
|
||||
"cancel": "Annuleren",
|
||||
"close": "Sluiten",
|
||||
"confirm": "Bevestigen",
|
||||
"more": "Meer...",
|
||||
"settings": {
|
||||
"locale": "Taal wijzigen",
|
||||
"locale_description": "Huidige taal: ${language} (%s)",
|
||||
"notification_audio": "Meldingsgeluid",
|
||||
"notification_position": "Meldingspositie"
|
||||
"locale": "Change locale",
|
||||
"locale_description": "Current language: ${language} (%s)",
|
||||
"notification_audio": "Notification audio",
|
||||
"notification_position": "Notification position"
|
||||
},
|
||||
"position": {
|
||||
"bottom": "Onder",
|
||||
"bottom-left": "Linksonder",
|
||||
"bottom-right": "Rechtsonder",
|
||||
"center-left": "Linksmidden",
|
||||
"center-right": "Rechtsmidden",
|
||||
"top": "Boven",
|
||||
"top-left": "Linksboven",
|
||||
"top-right": "Rechtsboven"
|
||||
"bottom": "Bottom",
|
||||
"bottom-left": "Bottom-left",
|
||||
"bottom-right": "Bottom-right",
|
||||
"center-left": "Center-left",
|
||||
"center-right": "Center-right",
|
||||
"top": "Top",
|
||||
"top-left": "Top-left",
|
||||
"top-right": "Top-right"
|
||||
}
|
||||
},
|
||||
"open_radial_menu": "Radiaal menu openen",
|
||||
"cancel_progress": "Huidige voortgangsbalk annuleren",
|
||||
"open_radial_menu": "Open radial menu",
|
||||
"cancel_progress": "Cancel current progress bar",
|
||||
"txadmin_announcement": "Server mededeling door %s",
|
||||
"txadmin_dm": "Bericht van %s",
|
||||
"txadmin_warn": "Je hebt een waarschuwing gekregen van %s",
|
||||
|
||||
@ -6,27 +6,27 @@
|
||||
"confirm": "Confirmar",
|
||||
"more": "Mais...",
|
||||
"settings": {
|
||||
"locale": "Alterar idioma",
|
||||
"locale_description": "Idioma atual: ${language} (%s)",
|
||||
"notification_audio": "Áudio de notificação",
|
||||
"notification_position": "Posição da notificação"
|
||||
"locale": "Change locale",
|
||||
"locale_description": "Current language: ${language} (%s)",
|
||||
"notification_audio": "Notification audio",
|
||||
"notification_position": "Notification position"
|
||||
},
|
||||
"position": {
|
||||
"bottom": "Inferior",
|
||||
"bottom-left": "Inferior esquerdo",
|
||||
"bottom-right": "Inferior direito",
|
||||
"center-left": "Centro-esquerdo",
|
||||
"center-right": "Centro-direito",
|
||||
"top": "Superior",
|
||||
"top-left": "Superior esquerdo",
|
||||
"top-right": "Superior direito"
|
||||
"bottom": "Bottom",
|
||||
"bottom-left": "Bottom-left",
|
||||
"bottom-right": "Bottom-right",
|
||||
"center-left": "Center-left",
|
||||
"center-right": "Center-right",
|
||||
"top": "Top",
|
||||
"top-left": "Top-left",
|
||||
"top-right": "Top-right"
|
||||
}
|
||||
},
|
||||
"open_radial_menu": "Abrir menu radial",
|
||||
"cancel_progress": "Cancelar barra de progresso atual",
|
||||
"txadmin_announcement": "Anúncio por %s",
|
||||
"txadmin_dm": "Mensagem de %s",
|
||||
"txadmin_warn": "Você foi alertado por %s",
|
||||
"txadmin_warn_content": "%s \nID do aviso: %s",
|
||||
"txadmin_scheduledrestart": "Reinício agendado"
|
||||
"open_radial_menu": "Open radial menu",
|
||||
"cancel_progress": "Cancel current progress bar",
|
||||
"txadmin_announcement": "Server announcement by %s",
|
||||
"txadmin_dm": "Direct Message from %s",
|
||||
"txadmin_warn": "You have been warned by %s",
|
||||
"txadmin_warn_content": "%s \nAction ID: %s",
|
||||
"txadmin_scheduledrestart": "Scheduled Restart"
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
{
|
||||
"language": "Türkçe",
|
||||
"settings": "Ayarlar",
|
||||
"ui": {
|
||||
"cancel": "İptal",
|
||||
"close": "Kapat",
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
{
|
||||
"language": "简体中文",
|
||||
"settings": "设置",
|
||||
"ui": {
|
||||
"cancel": "取消",
|
||||
"close": "关闭",
|
||||
|
||||
@ -1,30 +1,29 @@
|
||||
{
|
||||
"language": "繁體中文",
|
||||
"settings": "設置",
|
||||
"ui": {
|
||||
"cancel": "取消",
|
||||
"close": "關閉",
|
||||
"confirm": "確認",
|
||||
"more": "更多...",
|
||||
"settings": {
|
||||
"locale": "更改語言",
|
||||
"locale_description": "當前語言: ${language} (%s)",
|
||||
"notification_audio": "通知提示音",
|
||||
"notification_position": "通知位置"
|
||||
"locale": "Change locale",
|
||||
"locale_description": "Current language: ${language} (%s)",
|
||||
"notification_audio": "Notification audio",
|
||||
"notification_position": "Notification position"
|
||||
},
|
||||
"position": {
|
||||
"bottom": "底部",
|
||||
"bottom-left": "左下",
|
||||
"bottom-right": "右下",
|
||||
"center-left": "左側居中",
|
||||
"center-right": "右側居中",
|
||||
"top": "頂部",
|
||||
"top-left": "左上",
|
||||
"top-right": "右上"
|
||||
"bottom": "Bottom",
|
||||
"bottom-left": "Bottom-left",
|
||||
"bottom-right": "Bottom-right",
|
||||
"center-left": "Center-left",
|
||||
"center-right": "Center-right",
|
||||
"top": "Top",
|
||||
"top-left": "Top-left",
|
||||
"top-right": "Top-right"
|
||||
}
|
||||
},
|
||||
"open_radial_menu": "打開輪盤菜單",
|
||||
"cancel_progress": "取消當前進度條",
|
||||
"open_radial_menu": "Open radial menu",
|
||||
"cancel_progress": "Cancel current progress bar",
|
||||
"txadmin_announcement": "來自 %s 的伺服器通告",
|
||||
"txadmin_dm": "來自 %s 的訊息",
|
||||
"txadmin_warn": "您被 %s 警告了",
|
||||
|
||||
@ -26,10 +26,6 @@ CreateThread(function()
|
||||
local vehicle = GetVehiclePedIsIn(ped, false)
|
||||
|
||||
if vehicle > 0 then
|
||||
if vehicle ~= cache.vehicle then
|
||||
cache:set('seat', false)
|
||||
end
|
||||
|
||||
cache:set('vehicle', vehicle)
|
||||
|
||||
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
|
||||
error(('No menu with id %s was found'):format(id))
|
||||
end
|
||||
|
||||
if table.type(menu.options) == 'empty' then
|
||||
error(('Can\'t open empty menu with id %s'):format(id))
|
||||
end
|
||||
|
||||
if not openMenu then
|
||||
local control = cache.game == 'fivem' and 140 or 0xE30CD707
|
||||
|
||||
|
||||
@ -30,8 +30,7 @@ local function createProp(ped, prop)
|
||||
local coords = GetEntityCoords(ped)
|
||||
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,
|
||||
true, false, true, prop.rotOrder or 0, 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)
|
||||
SetModelAsNoLongerNeeded(prop.model)
|
||||
|
||||
return object
|
||||
@ -63,7 +62,6 @@ local controls = {
|
||||
INPUT_VEH_MOUSE_CONTROL_OVERRIDE = isFivem and 106 or 0x39CCABD5
|
||||
}
|
||||
|
||||
---@param data ProgressProps
|
||||
local function startProgress(data)
|
||||
playerState.invBusy = true
|
||||
progress = data
|
||||
@ -73,11 +71,10 @@ local function startProgress(data)
|
||||
if anim.dict then
|
||||
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,
|
||||
anim.lockX, anim.lockY, anim.lockZ)
|
||||
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)
|
||||
RemoveAnimDict(anim.dict)
|
||||
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
|
||||
|
||||
@ -86,7 +83,6 @@ local function startProgress(data)
|
||||
end
|
||||
|
||||
local disable = data.disable
|
||||
local startTime = GetGameTimer()
|
||||
|
||||
while progress do
|
||||
if disable then
|
||||
@ -142,9 +138,8 @@ local function startProgress(data)
|
||||
end
|
||||
|
||||
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' })
|
||||
return false
|
||||
end
|
||||
@ -248,13 +243,13 @@ AddStateBagChangeHandler('lib:progressProps', nil, function(bagName, key, value,
|
||||
local playerProps = createdProps[serverId]
|
||||
|
||||
if value.model then
|
||||
playerProps[#playerProps + 1] = createProp(ped, value)
|
||||
playerProps[#playerProps+1] = createProp(ped, value)
|
||||
else
|
||||
for i = 1, #value do
|
||||
local prop = value[i]
|
||||
|
||||
if prop then
|
||||
playerProps[#playerProps + 1] = createProp(ped, prop)
|
||||
playerProps[#playerProps+1] = createProp(ped, prop)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -80,7 +80,6 @@ if cache.game == 'redm' then return end
|
||||
---@field modLivery? number
|
||||
---@field modRoofLivery? number
|
||||
---@field modLightbar? number
|
||||
---@field livery? number
|
||||
---@field windows? number[]
|
||||
---@field doors? number[]
|
||||
---@field tyres? table<number | string, 1 | 2>
|
||||
@ -152,6 +151,13 @@ function lib.getVehicleProperties(vehicle)
|
||||
end
|
||||
end
|
||||
|
||||
local modLiveryCount = GetVehicleLiveryCount(vehicle)
|
||||
local modLivery = GetVehicleLivery(vehicle)
|
||||
|
||||
if modLiveryCount == -1 or modLivery == -1 then
|
||||
modLivery = GetVehicleMod(vehicle, 48)
|
||||
end
|
||||
|
||||
local damage = {
|
||||
windows = {},
|
||||
doors = {},
|
||||
@ -267,10 +273,9 @@ function lib.getVehicleProperties(vehicle)
|
||||
modTank = GetVehicleMod(vehicle, 45),
|
||||
modWindows = GetVehicleMod(vehicle, 46),
|
||||
modDoorR = GetVehicleMod(vehicle, 47),
|
||||
modLivery = GetVehicleMod(vehicle, 48),
|
||||
modLivery = modLivery,
|
||||
modRoofLivery = GetVehicleRoofLivery(vehicle),
|
||||
modLightbar = GetVehicleMod(vehicle, 49),
|
||||
livery = GetVehicleLivery(vehicle),
|
||||
windows = damage.windows,
|
||||
doors = damage.doors,
|
||||
tyres = damage.tyres,
|
||||
@ -343,7 +348,7 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
||||
ClearVehicleCustomPrimaryColour(vehicle)
|
||||
SetVehicleColours(vehicle, props.color1 --[[@as number]], colorSecondary --[[@as number]])
|
||||
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])
|
||||
end
|
||||
@ -354,7 +359,7 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
||||
ClearVehicleCustomSecondaryColour(vehicle)
|
||||
SetVehicleColours(vehicle, props.color1 or colorPrimary --[[@as number]], props.color2 --[[@as number]])
|
||||
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])
|
||||
end
|
||||
@ -618,6 +623,7 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
||||
|
||||
if props.modLivery then
|
||||
SetVehicleMod(vehicle, 48, props.modLivery, false)
|
||||
SetVehicleLivery(vehicle, props.modLivery)
|
||||
end
|
||||
|
||||
if props.modRoofLivery then
|
||||
@ -628,10 +634,6 @@ function lib.setVehicleProperties(vehicle, props, fixVehicle)
|
||||
SetVehicleMod(vehicle, 49, props.modLightbar, false)
|
||||
end
|
||||
|
||||
if props.livery then
|
||||
SetVehicleLivery(vehicle, props.livery)
|
||||
end
|
||||
|
||||
if props.bulletProofTyres ~= nil then
|
||||
SetVehicleTyresCanBurst(vehicle, props.bulletProofTyres)
|
||||
end
|
||||
|
||||
@ -37,10 +37,6 @@ exports.ox_target:addPolyZone({
|
||||
})
|
||||
]]
|
||||
|
||||
local function formatNumber(num)
|
||||
return tostring(num):gsub(",", ".")
|
||||
end
|
||||
|
||||
local parse = {
|
||||
poly = function(data)
|
||||
local points = {}
|
||||
@ -86,34 +82,18 @@ local parse = {
|
||||
pattern = {
|
||||
'local box = lib.zones.box({\n',
|
||||
('\tname = "%s",\n'):format(data.name),
|
||||
('\tcoords = vec3(%s, %s, %s),\n'):format(
|
||||
formatNumber(data.xCoord),
|
||||
formatNumber(data.yCoord),
|
||||
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)),
|
||||
('\tcoords = vec3(%s, %s, %s),\n'):format(data.xCoord, data.yCoord, data.zCoord),
|
||||
('\tsize = vec3(%s, %s, %s),\n'):format(data.width, data.length, data.height),
|
||||
('\trotation = %s,\n'):format(data.heading),
|
||||
'})\n',
|
||||
}
|
||||
elseif data.format == 'array' then
|
||||
pattern = {
|
||||
'{\n',
|
||||
('\tname = "%s",\n'):format(data.name),
|
||||
('\tcoords = vec3(%s, %s, %s),\n'):format(
|
||||
formatNumber(data.xCoord),
|
||||
formatNumber(data.yCoord),
|
||||
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)),
|
||||
('\tcoords = vec3(%s, %s, %s),\n'):format(data.xCoord, data.yCoord, data.zCoord),
|
||||
('\tsize = vec3(%s, %s, %s),\n'):format(data.width, data.length, data.height),
|
||||
('\trotation = %s,\n'):format(data.heading),
|
||||
'},\n',
|
||||
}
|
||||
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" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>NUI React Boilerplate</title>
|
||||
<script type="module" crossorigin src="./assets/index-DA6-Nmx5.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BgkLwDpx.css">
|
||||
<script type="module" crossorigin src="./assets/index-K9iBfj89.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-3x7-Y31P.css">
|
||||
</head>
|
||||
<body>
|
||||
<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_principal identifier.fivem:1 group.admin # add the admin to the group
|
||||
|
||||
sv_maxclients 10
|
||||
sv_maxclients 1
|
||||
set steam_webApiKey ""
|
||||
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
|
||||
|
||||
setr esx:locale "en"
|
||||
|
||||
@ -15,7 +15,7 @@ sv_hostname "United Islands DEV"
|
||||
sets sv_projectName "United Islands"
|
||||
sets sv_projectDesc "United Islands S4"
|
||||
sv_enforceGameBuild 3258
|
||||
load_server_icon icon.png
|
||||
#load_server_icon myLogo.png
|
||||
|
||||
set temp_convar "hey world!"
|
||||
sv_master1 ""
|
||||
@ -28,7 +28,7 @@ sv_maxclients 1
|
||||
set steam_webApiKey ""
|
||||
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
|
||||
|
||||
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,
|
||||
"general": {
|
||||
"serverName": "UIRP"
|
||||
"global": {
|
||||
"serverName": "UIRP",
|
||||
"language": "en",
|
||||
"menuEnabled": true,
|
||||
"menuAlignRight": false,
|
||||
"menuPageKey": "Tab",
|
||||
"hideDefaultAnnouncement": false,
|
||||
"hideDefaultDirectMessage": false,
|
||||
"hideDefaultWarning": false,
|
||||
"hideDefaultScheduledRestartWarning": false
|
||||
},
|
||||
"server": {
|
||||
"dataPath": "/home/UIRP-5M/",
|
||||
"cfgPath": "/home/UIRP-5M/server.cfg"
|
||||
},
|
||||
"restarter": {
|
||||
"logger": {},
|
||||
"monitor": {
|
||||
"restarterSchedule": [],
|
||||
"resourceStartingTolerance": 120
|
||||
},
|
||||
"banlist": {
|
||||
"rejectionMessage": "You can join https://discord.gg/6FUefh62Jn to appeal this ban."
|
||||
},
|
||||
"whitelist": {
|
||||
"mode": "discordRoles",
|
||||
"rejectionMessage": "Please join https://discord.gg/6FUefh62Jn and request to be whitelisted.",
|
||||
"discordRoles": [
|
||||
"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",
|
||||
"warningsChannel": "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&\"}}",
|
||||
"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\"}]}"
|
||||
"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 +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 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 106 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 "/-cancelprog"
|
||||
[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