From adcbc868eab94e3c331c55cf0268f7c0f8e83acc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 13 Dec 2025 16:50:13 +0000 Subject: [PATCH 1/6] Initial plan From c7eeb8367075d319b6b83518e40c67514b4de5ee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 13 Dec 2025 16:53:54 +0000 Subject: [PATCH 2/6] Add nil checks and error messages for MyVehicleConfig Co-authored-by: Flohhhhh <48927090+Flohhhhh@users.noreply.github.com> --- ulc/client/c_buttons.lua | 10 +++++++++- ulc/server/s_main.lua | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ulc/client/c_buttons.lua b/ulc/client/c_buttons.lua index cb529c7..27e6ab3 100644 --- a/ulc/client/c_buttons.lua +++ b/ulc/client/c_buttons.lua @@ -7,6 +7,10 @@ ------------------- function GetExtraByKey(key) + if not MyVehicleConfig then + print("[ULC:GetExtraByKey] ERROR: MyVehicleConfig is not loaded. This usually means there's a syntax error in your ulc.lua file. Check server console for details.") + return nil + end local result = nil for _, v in pairs(MyVehicleConfig.buttons) do if v.key == key then @@ -17,6 +21,10 @@ function GetExtraByKey(key) end function GetButtonByExtra(extra) + if not MyVehicleConfig then + print("[ULC:GetButtonByExtra] ERROR: MyVehicleConfig is not loaded. This usually means there's a syntax error in your ulc.lua file. Check server console for details.") + return nil + end local result = nil for _, v in pairs(MyVehicleConfig.buttons) do if v.extra == extra then @@ -126,7 +134,7 @@ function ULC:SetStage(extra, action, playSound, extraOnly, repair, forceChange, ---------------------- -- smart stages stuff local key = button.key - if MyVehicleConfig.stages then + if MyVehicleConfig and MyVehicleConfig.stages then local keyStage = contains(MyVehicleConfig.stages.stageKeys, key) -- find whether MyVehicleConfig.stages.stageKeys contain the key -- # TODO we're not getting here for some reason when cycling stages at max stage diff --git a/ulc/server/s_main.lua b/ulc/server/s_main.lua index 4348db2..a90adba 100644 --- a/ulc/server/s_main.lua +++ b/ulc/server/s_main.lua @@ -327,7 +327,8 @@ local function LoadExternalVehicleConfig(resourceName) local f, err = load(data) if err then TriggerEvent("ulc:error", - '^1Could not load external configuration in: "' .. resourceName .. '"; error: "' .. err .. '"^0') + '^1Could not load external configuration in: "' .. resourceName .. '"; SYNTAX ERROR: ' .. err .. '^0') + print("^3[ULC] HINT: Check the ulc.lua file in '" .. resourceName .. "' for syntax errors like missing commas, brackets, or quotes.^0") return end if not f or not f() then From e582a9c617a3a1c9489eecee65ea4653f719435e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:00:05 +0000 Subject: [PATCH 3/6] Add comprehensive nil checks for MyVehicleConfig across all client files Co-authored-by: Flohhhhh <48927090+Flohhhhh@users.noreply.github.com> --- ulc/client/c_brake.lua | 10 ++++++---- ulc/client/c_cruise.lua | 7 +++++-- ulc/client/c_doors.lua | 3 ++- ulc/client/c_horn.lua | 4 ++-- ulc/client/c_park.lua | 4 ++-- ulc/client/c_reverse.lua | 2 ++ ulc/client/c_signals.lua | 5 +++++ ulc/client/c_stages.lua | 5 +++++ 8 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ulc/client/c_brake.lua b/ulc/client/c_brake.lua index ed7b1a9..ff82a25 100644 --- a/ulc/client/c_brake.lua +++ b/ulc/client/c_brake.lua @@ -1,6 +1,7 @@ --print("[ULC] Brake Extras Loaded") local realBrakeThreshold = 3 local shouldUseRealBrakes = function() + if not MyVehicleConfig then return false end return (MyVehicleConfig.brakeConfig.speedThreshold or 3) <= realBrakeThreshold end local braking = false @@ -12,6 +13,7 @@ local braking = false local disabledExtras = {} local function setBrakeExtras(newState) + if not MyVehicleConfig then return end for _, v in pairs(MyVehicleConfig.brakeConfig.brakeExtras) do local currentState if IsVehicleExtraTurnedOn(MyVehicle, v) then currentState = 0 else currentState = 1 end @@ -63,7 +65,7 @@ if shouldUseRealBrakes then sleep = 1000 goto continue end - if not MyVehicleConfig.brakeConfig.useBrakes then + if not MyVehicleConfig or not MyVehicleConfig.brakeConfig.useBrakes then sleep = 1000 goto continue end @@ -87,7 +89,7 @@ if shouldUseRealBrakes then Wait(0) -- Nedded as GetEntityFromStateBagName sometimes returns 0 on first frame mode = "RBL" -- set mode to RBL to disable manual checking if not MyVehicle then return end - if not MyVehicleConfig.brakeConfig.useBrakes then return end + if not MyVehicleConfig or not MyVehicleConfig.brakeConfig.useBrakes then return end local vehicle = GetEntityFromStateBagName(bagName) --print("state changed for vehicle") if vehicle == 0 or vehicle ~= MyVehicle then return end @@ -105,7 +107,7 @@ end -- pressed brakes RegisterCommand('+ulc:brakePattern', function() braking = true - if MyVehicle and MyVehicleConfig.brakeConfig.useBrakes then + if MyVehicle and MyVehicleConfig and MyVehicleConfig.brakeConfig.useBrakes then if GetVehicleCurrentGear(MyVehicle) == 0 then return end -- disable while reversing --print("Enabling brakes") local speed = GetVehicleSpeedConverted(MyVehicle) @@ -122,7 +124,7 @@ end) RegisterCommand('-ulc:brakePattern', function() braking = false - if MyVehicle and MyVehicleConfig.brakeConfig.useBrakes then + if MyVehicle and MyVehicleConfig and MyVehicleConfig.brakeConfig.useBrakes then local speed = GetVehicleSpeedConverted(MyVehicle) if shouldUseRealBrakes() and speed < realBrakeThreshold then return end --print("Disabling brakes") diff --git a/ulc/client/c_cruise.lua b/ulc/client/c_cruise.lua index d621fe8..46efbf5 100644 --- a/ulc/client/c_cruise.lua +++ b/ulc/client/c_cruise.lua @@ -5,6 +5,7 @@ local sbState = 1 -- 0 on, 1 off local function setCruiseLights(newState) + if not MyVehicleConfig then return end sbState = newState for _, v in pairs(MyVehicleConfig.steadyBurnConfig.sbExtras) do --print("Setting cruise lights extra: " .. v) @@ -13,6 +14,7 @@ local function setCruiseLights(newState) end local function getSteadyBurnState() + if not MyVehicleConfig then return 1 end if IsVehicleExtraTurnedOn(MyVehicle, MyVehicleConfig.steadyBurnConfig.sbExtras[1]) then return 0 else @@ -33,14 +35,14 @@ end) AddEventHandler('ulc:lightsOn', function() --print("Lights on") - if MyVehicle and (MyVehicleConfig.steadyBurnConfig.disableWithLights or false) then + if MyVehicle and MyVehicleConfig and (MyVehicleConfig.steadyBurnConfig.disableWithLights or false) then setCruiseLights(1) end end) AddEventHandler('ulc:lightsOff', function() --print("Lights off") - if MyVehicle and (MyVehicleConfig.steadyBurnConfig.disableWithLights or false) then + if MyVehicle and MyVehicleConfig and (MyVehicleConfig.steadyBurnConfig.disableWithLights or false) then TriggerEvent('ulc:CheckCruise') end end) @@ -48,6 +50,7 @@ end) AddEventHandler('ulc:CheckCruise', function() sbState = getSteadyBurnState() if not MyVehicle then return end + if not MyVehicleConfig then return end if Entity(MyVehicle).state.ulc_blackout == 0 then -- print("Blackout is on, disabling cruise lights") diff --git a/ulc/client/c_doors.lua b/ulc/client/c_doors.lua index d38c655..14acd80 100644 --- a/ulc/client/c_doors.lua +++ b/ulc/client/c_doors.lua @@ -17,6 +17,7 @@ end -- state 1 = closed, state 0 = open local function onDoorStateChange(door, newDoorState) + if not MyVehicleConfig then return end --print("Handling door change", door, newDoorState) if door == 0 or door == 2 then -- if driver side for _, v in pairs(MyVehicleConfig.doorConfig.driverSide.enable) do @@ -54,7 +55,7 @@ CreateThread(function() sleep = 1000 goto continue end - if not MyVehicleConfig.doorConfig or false then + if not MyVehicleConfig or not MyVehicleConfig.doorConfig or false then sleep = 1000 goto continue end diff --git a/ulc/client/c_horn.lua b/ulc/client/c_horn.lua index cb564fb..9c34327 100644 --- a/ulc/client/c_horn.lua +++ b/ulc/client/c_horn.lua @@ -53,13 +53,13 @@ RegisterCommand('+ulc:horn', function() --print('horn') extraStates = {} - if MyVehicle and MyVehicleConfig.hornConfig.useHorn then + if MyVehicle and MyVehicleConfig and MyVehicleConfig.hornConfig.useHorn then SetHornExtras(0) end end) RegisterCommand('-ulc:horn', function() - if MyVehicle and MyVehicleConfig.hornConfig.useHorn then + if MyVehicle and MyVehicleConfig and MyVehicleConfig.hornConfig.useHorn then SetHornExtras(1) end end) diff --git a/ulc/client/c_park.lua b/ulc/client/c_park.lua index 519e346..4fea768 100644 --- a/ulc/client/c_park.lua +++ b/ulc/client/c_park.lua @@ -45,7 +45,7 @@ AddEventHandler('ulc:vehPark', function() --print('[ulc:vehPark] My vehicle is parked.') parked = true - if MyVehicle and MyVehicleConfig.parkConfig.usePark then + if MyVehicle and MyVehicleConfig and MyVehicleConfig.parkConfig.usePark then -- enable pExtras for _, v in pairs(MyVehicleConfig.parkConfig.pExtras) do ULC:SetStage(v, 0, false, true, false, false, true, false) @@ -136,7 +136,7 @@ AddEventHandler('ulc:vehDrive', function() if Lights then --print('[ulc:vehDrive] My vehicle is driving.') parked = false - if MyVehicle and MyVehicleConfig.parkConfig.usePark then + if MyVehicle and MyVehicleConfig and MyVehicleConfig.parkConfig.usePark then -- disable pExtras for _, v in pairs(MyVehicleConfig.parkConfig.pExtras) do ULC:SetStage(v, 1, false, true, false, false, true, false) diff --git a/ulc/client/c_reverse.lua b/ulc/client/c_reverse.lua index b6e3f7b..29ea879 100644 --- a/ulc/client/c_reverse.lua +++ b/ulc/client/c_reverse.lua @@ -5,6 +5,7 @@ local disabledExtras = {} local timerExpired = false function setReverseExtras(newState) + if not MyVehicleConfig then return end -- set enable extras to match the new state for _, v in ipairs(MyVehicleConfig.reverseConfig.reverseExtras) do ULC:SetStage(v, newState, false, true, false, false, true, false) @@ -36,6 +37,7 @@ AddEventHandler('ulc:StartCheckingReverseState', function() if not IsPedInAnyVehicle(PlayerPedId()) then return end -- this feels unncessary, but I think some people may not have .reverseConfig if not MyVehicle then return end + if not MyVehicleConfig then return end if not MyVehicleConfig.reverseConfig then return end if not MyVehicleConfig.reverseConfig.useReverse then return end local gear = GetVehicleCurrentGear(MyVehicle) diff --git a/ulc/client/c_signals.lua b/ulc/client/c_signals.lua index 871aa6c..f447dbf 100644 --- a/ulc/client/c_signals.lua +++ b/ulc/client/c_signals.lua @@ -4,6 +4,9 @@ local combinedExtrasTable = {} AddEventHandler("ulc:SetupSignalExtrasTable", function() print('[ulc:SetupSignalExtrasTable] Setting up signal extras table') + if not MyVehicleConfig then return end + if not MyVehicleConfig.signalConfig then return end + local extras = {} @@ -41,6 +44,8 @@ IndicatorState = 0 local savedExtraStates = {} local function saveExtraStates() + if not MyVehicleConfig then return end + if not MyVehicleConfig.signalConfig then return end -- get states of all extras listed in signalConfig local extras = {} for _, side in pairs({ "left", "right", "hazard" }) do diff --git a/ulc/client/c_stages.lua b/ulc/client/c_stages.lua index 25e2fe9..0a066c9 100644 --- a/ulc/client/c_stages.lua +++ b/ulc/client/c_stages.lua @@ -11,6 +11,7 @@ currentStage = 0 -- helpers local function checks() if not MyVehicle then return false end + if not MyVehicleConfig then return false end if not MyVehicleConfig.stages then return false end if not MyVehicleConfig.stages.useStages then return false end if not MyVehicleConfig.stages.stageKeys then return false end @@ -19,6 +20,7 @@ end function getMaxStage() if not MyVehicle then return end + if not MyVehicleConfig then return end if not MyVehicleConfig.stages then return end if not MyVehicleConfig.stages.stageKeys then return end return #MyVehicleConfig.stages.stageKeys @@ -122,7 +124,9 @@ end) function getStageFromButton(button) if not button then return false end if not MyVehicle then return false end + if not MyVehicleConfig then return false end -- if MyVehicleConfig.stages.stageKeys is nil or doesn't contain the button.key return false + if not MyVehicleConfig.stages then return false end if not MyVehicleConfig.stages.stageKeys then return false end for i, key in pairs(MyVehicleConfig.stages.stageKeys) do if key == button.key then @@ -134,6 +138,7 @@ end function setDefaultStages() -- default stages + if not MyVehicleConfig then return end if not MyVehicleConfig.defaultStages or false then return end if not MyVehicleConfig.defaultStages.useDefaults then return end for _, e in pairs(MyVehicleConfig.defaultStages.enableKeys) do From 167b8f848234348c36e9c4ec6b493324cc974a08 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:01:13 +0000 Subject: [PATCH 4/6] Update comment to reflect current logic flow Co-authored-by: Flohhhhh <48927090+Flohhhhh@users.noreply.github.com> --- ulc/client/c_stages.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ulc/client/c_stages.lua b/ulc/client/c_stages.lua index 0a066c9..d7cdbc5 100644 --- a/ulc/client/c_stages.lua +++ b/ulc/client/c_stages.lua @@ -125,8 +125,8 @@ function getStageFromButton(button) if not button then return false end if not MyVehicle then return false end if not MyVehicleConfig then return false end - -- if MyVehicleConfig.stages.stageKeys is nil or doesn't contain the button.key return false if not MyVehicleConfig.stages then return false end + -- if stageKeys doesn't exist or doesn't contain the button.key return false if not MyVehicleConfig.stages.stageKeys then return false end for i, key in pairs(MyVehicleConfig.stages.stageKeys) do if key == button.key then From 1f53b1545d4a52040b2ce1fb4c577f78c35496d8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:12:05 +0000 Subject: [PATCH 5/6] Add verbose warning messages when functions are called with nil MyVehicleConfig Co-authored-by: Flohhhhh <48927090+Flohhhhh@users.noreply.github.com> --- ulc/client/c_brake.lua | 10 ++++++++-- ulc/client/c_cruise.lua | 15 ++++++++++++--- ulc/client/c_doors.lua | 5 ++++- ulc/client/c_reverse.lua | 5 ++++- ulc/client/c_signals.lua | 10 ++++++++-- ulc/client/c_stages.lua | 5 ++++- 6 files changed, 40 insertions(+), 10 deletions(-) diff --git a/ulc/client/c_brake.lua b/ulc/client/c_brake.lua index ff82a25..45e063c 100644 --- a/ulc/client/c_brake.lua +++ b/ulc/client/c_brake.lua @@ -1,7 +1,10 @@ --print("[ULC] Brake Extras Loaded") local realBrakeThreshold = 3 local shouldUseRealBrakes = function() - if not MyVehicleConfig then return false end + if not MyVehicleConfig then + print("[ULC:shouldUseRealBrakes] WARNING: Function called but MyVehicleConfig is not loaded. Check server console for configuration errors.") + return false + end return (MyVehicleConfig.brakeConfig.speedThreshold or 3) <= realBrakeThreshold end local braking = false @@ -13,7 +16,10 @@ local braking = false local disabledExtras = {} local function setBrakeExtras(newState) - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:setBrakeExtras] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") + return + end for _, v in pairs(MyVehicleConfig.brakeConfig.brakeExtras) do local currentState if IsVehicleExtraTurnedOn(MyVehicle, v) then currentState = 0 else currentState = 1 end diff --git a/ulc/client/c_cruise.lua b/ulc/client/c_cruise.lua index 46efbf5..eb08cbd 100644 --- a/ulc/client/c_cruise.lua +++ b/ulc/client/c_cruise.lua @@ -5,7 +5,10 @@ local sbState = 1 -- 0 on, 1 off local function setCruiseLights(newState) - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:setCruiseLights] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") + return + end sbState = newState for _, v in pairs(MyVehicleConfig.steadyBurnConfig.sbExtras) do --print("Setting cruise lights extra: " .. v) @@ -14,7 +17,10 @@ local function setCruiseLights(newState) end local function getSteadyBurnState() - if not MyVehicleConfig then return 1 end + if not MyVehicleConfig then + print("[ULC:getSteadyBurnState] WARNING: Function called but MyVehicleConfig is not loaded. Check server console for configuration errors.") + return 1 + end if IsVehicleExtraTurnedOn(MyVehicle, MyVehicleConfig.steadyBurnConfig.sbExtras[1]) then return 0 else @@ -50,7 +56,10 @@ end) AddEventHandler('ulc:CheckCruise', function() sbState = getSteadyBurnState() if not MyVehicle then return end - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:CheckCruise] WARNING: Event handler called but MyVehicleConfig is not loaded. This should not happen.") + return + end if Entity(MyVehicle).state.ulc_blackout == 0 then -- print("Blackout is on, disabling cruise lights") diff --git a/ulc/client/c_doors.lua b/ulc/client/c_doors.lua index 14acd80..8b03c2c 100644 --- a/ulc/client/c_doors.lua +++ b/ulc/client/c_doors.lua @@ -17,7 +17,10 @@ end -- state 1 = closed, state 0 = open local function onDoorStateChange(door, newDoorState) - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:onDoorStateChange] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") + return + end --print("Handling door change", door, newDoorState) if door == 0 or door == 2 then -- if driver side for _, v in pairs(MyVehicleConfig.doorConfig.driverSide.enable) do diff --git a/ulc/client/c_reverse.lua b/ulc/client/c_reverse.lua index 29ea879..383a311 100644 --- a/ulc/client/c_reverse.lua +++ b/ulc/client/c_reverse.lua @@ -5,7 +5,10 @@ local disabledExtras = {} local timerExpired = false function setReverseExtras(newState) - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:setReverseExtras] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") + return + end -- set enable extras to match the new state for _, v in ipairs(MyVehicleConfig.reverseConfig.reverseExtras) do ULC:SetStage(v, newState, false, true, false, false, true, false) diff --git a/ulc/client/c_signals.lua b/ulc/client/c_signals.lua index f447dbf..3a763f2 100644 --- a/ulc/client/c_signals.lua +++ b/ulc/client/c_signals.lua @@ -4,7 +4,10 @@ local combinedExtrasTable = {} AddEventHandler("ulc:SetupSignalExtrasTable", function() print('[ulc:SetupSignalExtrasTable] Setting up signal extras table') - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:SetupSignalExtrasTable] WARNING: Event handler called but MyVehicleConfig is not loaded. This should not happen.") + return + end if not MyVehicleConfig.signalConfig then return end local extras = {} @@ -44,7 +47,10 @@ IndicatorState = 0 local savedExtraStates = {} local function saveExtraStates() - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:saveExtraStates] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") + return + end if not MyVehicleConfig.signalConfig then return end -- get states of all extras listed in signalConfig local extras = {} diff --git a/ulc/client/c_stages.lua b/ulc/client/c_stages.lua index d7cdbc5..85536b6 100644 --- a/ulc/client/c_stages.lua +++ b/ulc/client/c_stages.lua @@ -138,7 +138,10 @@ end function setDefaultStages() -- default stages - if not MyVehicleConfig then return end + if not MyVehicleConfig then + print("[ULC:setDefaultStages] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") + return + end if not MyVehicleConfig.defaultStages or false then return end if not MyVehicleConfig.defaultStages.useDefaults then return end for _, e in pairs(MyVehicleConfig.defaultStages.enableKeys) do From bbeecc654abf817723cb98d54ce7a76c18d61d3f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:13:56 +0000 Subject: [PATCH 6/6] Standardize warning message format for consistency Co-authored-by: Flohhhhh <48927090+Flohhhhh@users.noreply.github.com> --- ulc/client/c_brake.lua | 2 +- ulc/client/c_cruise.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ulc/client/c_brake.lua b/ulc/client/c_brake.lua index 45e063c..fc148ed 100644 --- a/ulc/client/c_brake.lua +++ b/ulc/client/c_brake.lua @@ -2,7 +2,7 @@ local realBrakeThreshold = 3 local shouldUseRealBrakes = function() if not MyVehicleConfig then - print("[ULC:shouldUseRealBrakes] WARNING: Function called but MyVehicleConfig is not loaded. Check server console for configuration errors.") + print("[ULC:shouldUseRealBrakes] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") return false end return (MyVehicleConfig.brakeConfig.speedThreshold or 3) <= realBrakeThreshold diff --git a/ulc/client/c_cruise.lua b/ulc/client/c_cruise.lua index eb08cbd..64e51f8 100644 --- a/ulc/client/c_cruise.lua +++ b/ulc/client/c_cruise.lua @@ -18,7 +18,7 @@ end local function getSteadyBurnState() if not MyVehicleConfig then - print("[ULC:getSteadyBurnState] WARNING: Function called but MyVehicleConfig is not loaded. Check server console for configuration errors.") + print("[ULC:getSteadyBurnState] WARNING: Function called but MyVehicleConfig is not loaded. This function should not be called without a valid configuration.") return 1 end if IsVehicleExtraTurnedOn(MyVehicle, MyVehicleConfig.steadyBurnConfig.sbExtras[1]) then