diff --git a/fxmanifest.lua b/fxmanifest.lua index da4c5638b..498a15299 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -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.23.1' +version '3.24.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.' diff --git a/imports/__addCommand/server.lua b/imports/__addCommand/server.lua index 8f4d0c4ee..4fc32df63 100644 --- a/imports/__addCommand/server.lua +++ b/imports/__addCommand/server.lua @@ -7,7 +7,7 @@ SetTimeout(1000, function() TriggerClientEvent('chat:addSuggestions', -1, commands) end) -AddEventHandler('playerJoining', function(source) +AddEventHandler('playerJoining', function() TriggerClientEvent('chat:addSuggestions', source, commands) end) diff --git a/imports/addCommand/server.lua b/imports/addCommand/server.lua index 3144417a5..da5f90e6a 100644 --- a/imports/addCommand/server.lua +++ b/imports/addCommand/server.lua @@ -18,7 +18,7 @@ SetTimeout(1000, function() TriggerClientEvent('chat:addSuggestions', -1, registeredCommands) end) -AddEventHandler('playerJoining', function(source) +AddEventHandler('playerJoining', function() TriggerClientEvent('chat:addSuggestions', source, registeredCommands) end) diff --git a/imports/array/shared.lua b/imports/array/shared.lua index 18dd313e5..778cc3e49 100644 --- a/imports/array/shared.lua +++ b/imports/array/shared.lua @@ -1,10 +1,10 @@ ---@class Array : OxClass -local Array = lib.class('Array') +lib.array = lib.class('Array') ---@alias ArrayLike Array | { [number]: T } ---@private -function Array:constructor(...) +function lib.array:constructor(...) local arr = { ... } for i = 1, #arr do @@ -13,7 +13,7 @@ function Array:constructor(...) end ---@private -function Array:__newindex(index, value) +function lib.array:__newindex(index, value) if type(index) ~= 'number' then error(("Cannot insert non-number index '%s' into an array."):format(index)) end rawset(self, index, value) @@ -21,7 +21,7 @@ end ---Create a new array containing the elements from two arrays. ---@param arr ArrayLike -function Array:merge(arr) +function lib.array:merge(arr) local newArr = table.clone(self) local length = #self @@ -30,12 +30,12 @@ function Array:merge(arr) newArr[length] = arr[i] end - return 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. ---@param testFn fun(element: unknown): boolean -function Array:every(testFn) +function lib.array:every(testFn) for i = 1, #self do if not testFn(self[i]) then return false @@ -47,7 +47,7 @@ end ---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 Array:filter(testFn) +function lib.array:filter(testFn) local newArr = {} local length = 0 @@ -60,13 +60,13 @@ function Array:filter(testFn) end end - return 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. ---@param testFn fun(element: unknown): boolean ---@param last? boolean -function Array:find(testFn, last) +function lib.array:find(testFn, last) local a = last and #self or 1 local b = last and 1 or #self local c = last and -1 or 1 @@ -83,7 +83,7 @@ end ---Returns the first or last index of the first element of an array that passes the provided test function. ---@param testFn fun(element: unknown): boolean ---@param last? boolean -function Array:findIndex(testFn, last) +function lib.array:findIndex(testFn, last) local a = last and #self or 1 local b = last and 1 or #self local c = last and -1 or 1 @@ -100,7 +100,7 @@ end ---Returns the first or last index of the first element of an array that matches the provided value. ---@param value unknown ---@param last? boolean -function Array:indexOf(value, last) +function lib.array:indexOf(value, last) local a = last and #self or 1 local b = last and 1 or #self local c = last and -1 or 1 @@ -116,7 +116,7 @@ end ---Executes the provided function for each element in an array. ---@param cb fun(element: unknown) -function Array:forEach(cb) +function lib.array:forEach(cb) for i = 1, #self do cb(self[i]) end @@ -124,18 +124,18 @@ end ---Concatenates all array elements into a string, seperated by commas or the specified seperator. ---@param seperator? string -function Array:join(seperator) +function lib.array:join(seperator) return table.concat(self, seperator or ',') end ---Removes the last element from an array and returns the removed element. -function Array:pop() +function lib.array:pop() return table.remove(self) end ---Adds the given elements to the end of an array and returns the new array length. ---@param ... any -function Array:push(...) +function lib.array:push(...) local elements = { ... } local length = #self @@ -148,7 +148,7 @@ function Array:push(...) end ---Removes the first element from an array and returns the removed element. -function Array:shift() +function lib.array:shift() return table.remove(self, 1) end @@ -158,7 +158,7 @@ end ---@param reducer fun(accumulator: T, currentValue: T, index?: number): T ---@param initialValue? T ---@return T -function Array:reduce(reducer, initialValue) +function lib.array:reduce(reducer, initialValue) local initialIndex = initialValue and 1 or 2 local accumulator = initialValue or self[1] @@ -172,18 +172,16 @@ end ---Returns true if the given table is an instance of array or an array-like table. ---@param tbl ArrayLike ---@return boolean -function Array.isArray(tbl) +function lib.array.isArray(tbl) if not type(tbl) == 'table' then return false end local tableType = table.type(tbl) - if tableType == 'array' or tableType == 'empty' or Array.instanceOf(tbl, Array) then + if tableType == 'array' or tableType == 'empty' or lib.array.instanceOf(tbl, lib.array) then return true end return false end -lib.array = Array - return lib.array diff --git a/imports/class/shared.lua b/imports/class/shared.lua index 87816731b..bf91125d4 100644 --- a/imports/class/shared.lua +++ b/imports/class/shared.lua @@ -1,10 +1,6 @@ ---@diagnostic disable: invisible local getinfo = debug.getinfo -if not getinfo(1, 'S').source:match('^@@ox_lib') then - lib.print.warn('ox_lib\'s class module is experimental and may break without warning.') -end - ---Ensure the given argument or property has a valid type, otherwise throwing an error. ---@param id number | string ---@param var any @@ -132,8 +128,10 @@ end ---Creates a new class. ---@generic S : OxClass ----@param name string +---@generic T : string +---@param name `T` ---@param super? S +---@return `T` function lib.class(name, super) assertType(1, name, 'string') diff --git a/package/client/resource/interface/input.ts b/package/client/resource/interface/input.ts index b681d9dc6..313688bef 100644 --- a/package/client/resource/interface/input.ts +++ b/package/client/resource/interface/input.ts @@ -158,6 +158,6 @@ type inputDialog = ( allowCancel?: boolean; } ) => Promise | undefined>; -export const inputDialog: inputDialog = async (heading, rows) => await exports.ox_lib.inputDialog(heading, rows); +export const inputDialog: inputDialog = async (heading, rows, options) => await exports.ox_lib.inputDialog(heading, rows, options); export const closeInputDialog = () => exports.ox_lib.closeInputDialog(); diff --git a/package/server/resource/index.ts b/package/server/resource/index.ts index 8ed674a2e..c3d2e07ab 100644 --- a/package/server/resource/index.ts +++ b/package/server/resource/index.ts @@ -1,5 +1,11 @@ +import type { VehicleProperties } from 'shared'; + export * from './acl'; export * from './locale'; export * from './callback'; export * from './version'; -export * from './addCommand'; \ No newline at end of file +export * from './addCommand'; + +export function setVehicleProperties(vehicle: number, props: VehicleProperties) { + Entity(vehicle).state.set('ox_lib:setVehicleProperties', props, true) +} diff --git a/resource/vehicleProperties/client.lua b/resource/vehicleProperties/client.lua index ead1ce9da..9e15060b0 100644 --- a/resource/vehicleProperties/client.lua +++ b/resource/vehicleProperties/client.lua @@ -99,20 +99,29 @@ RegisterNetEvent('ox_lib:setVehicleProperties', function(netid, data) end end) ---[[ Alternative to NetEvent - disabled (at least for now?) -AddStateBagChangeHandler('setVehicleProperties', '', function(bagName, _, value) +AddStateBagChangeHandler('ox_lib:setVehicleProperties', '', function(bagName, _, value) if not value or not GetEntityFromStateBagName then return end - local entity = GetEntityFromStateBagName(bagName) - local networked = not bagName:find('localEntity') + while NetworkIsInTutorialSession() do Wait(0) end - if networked and NetworkGetEntityOwner(entity) ~= cache.playerId then return end + local entityExists, entity = pcall(lib.waitFor, function() + local entity = GetEntityFromStateBagName(bagName) - if lib.setVehicleProperties(entity, value) then - Entity(entity).state:set('setVehicleProperties', nil, true) + if entity > 0 then return entity end + end, '', 10000) + + if not entityExists then return end + + lib.setVehicleProperties(entity, value) + Wait(200) + + -- this delay and second-setting of vehicle properties hopefully counters the + -- weird sync/ownership/shitfuckery when setting props on server-side vehicles + if NetworkGetEntityOwner(entity) == cache.playerId then + lib.setVehicleProperties(entity, value) + Entity(entity).state:set('ox_lib:setVehicleProperties', nil, true) end end) -]] local gameBuild = GetGameBuildNumber() diff --git a/resource/vehicleProperties/server.lua b/resource/vehicleProperties/server.lua new file mode 100644 index 000000000..39faf7d8b --- /dev/null +++ b/resource/vehicleProperties/server.lua @@ -0,0 +1,6 @@ +---@param vehicle number +---@param props VehicleProperties +---@diagnostic disable-next-line: duplicate-set-field +function lib.setVehicleProperties(vehicle, props) + Entity(vehicle).state:set('ox_lib:setVehicleProperties', props, true) +end