From d9f93785042f9b9f1eee0d7eb09f35c93eec448a Mon Sep 17 00:00:00 2001 From: commy2 Date: Tue, 9 Aug 2016 18:46:30 +0200 Subject: [PATCH] allign CBA debug/warning/error messages to ACE versions --- addons/diagnostic/config.cpp | 1 + addons/diagnostic/fnc_error.sqf | 54 ++++++--- addons/diagnostic/fnc_log.sqf | 60 ++++------ addons/diagnostic/gui.hpp | 26 +++++ addons/diagnostic/script_component.hpp | 1 + addons/main/script_macros_common.hpp | 108 +++++++++--------- addons/settings/XEH_postInit.sqf | 4 +- addons/settings/XEH_preInit.sqf | 10 +- addons/settings/fnc_init.sqf | 3 +- addons/settings/fnc_parse.sqf | 6 +- addons/settings/fnc_set.sqf | 3 +- .../loadSettingsFile.sqf | 6 +- .../loadSettingsFile.sqf | 2 +- 13 files changed, 154 insertions(+), 130 deletions(-) create mode 100644 addons/diagnostic/gui.hpp diff --git a/addons/diagnostic/config.cpp b/addons/diagnostic/config.cpp index d4cc36a4c..2e8473aae 100644 --- a/addons/diagnostic/config.cpp +++ b/addons/diagnostic/config.cpp @@ -17,3 +17,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgDisplay3DEN.hpp" +#include "gui.hpp" diff --git a/addons/diagnostic/fnc_error.sqf b/addons/diagnostic/fnc_error.sqf index 4e904bebc..b449301ff 100644 --- a/addons/diagnostic/fnc_error.sqf +++ b/addons/diagnostic/fnc_error.sqf @@ -1,43 +1,59 @@ /* ---------------------------------------------------------------------------- -Function: CBA_fnc_error +Internal Function: CBA_fnc_error Description: Logs an error message to the RPT log. - Should not be used directly, but rather via macros (, - or the ). + Should not be used directly, but rather via macros ( + or the ). Parameters: - _file - Name of file [String] - _lineNum - Line of file (starting at 0) [Number] - _title - Title of the error [String] - _message - Error message [String, which may contain \n] + _prefix - Addon name (optional, defaut: "cba") + _component - Component name (optional, default: "diagnostic") + _title - Title of the error + _message - Error message (use "\n" for newline) + _file - Name of file + _lineNum - Line of file Returns: nil Author: - Spooner + Spooner, commy2 ---------------------------------------------------------------------------- */ - #include "script_component.hpp" - SCRIPT(error); -// ----------------------------------------------------------------------------- -params ["_file","_lineNum","_title","_message"]; - -private ["_time", "_lines"]; +params [ + ["_prefix", 'PREFIX', [""]], + ["_component", 'COMPONENT'], + ["_title", "", [""]], + ["_message", "", [""]], + ["_file", "", [""]], + ["_lineNum", -1, [0]] +]; -// TODO: popup window with error message in it. -_time = [diag_tickTime, "H:MM:SS.mmm"] call CBA_fnc_formatElapsedTime; +_prefix = toUpper _prefix; -diag_log text format ["%1 (%2) [%3:%4] -ERROR- %5", _time, time, _file, _lineNum + 1, _title]; +// RPT log +diag_log text format ["[%1] (%2) ERROR: %3 File: %4 Line: %5", _prefix, _component, _title, _file, _lineNum]; -_lines = [_message, "\n"] call CBA_fnc_split; +private _lines = [_message, "\n"] call CBA_fnc_split; { diag_log text format [" %1", _x]; } forEach _lines; -nil; +// error pop up +QGVAR(Error) cutRsc [QGVAR(Error), "PLAIN"]; +private _control = uiNamespace getVariable QGVAR(Error); + +private _compose = [lineBreak, parseText format ["[%1] (%2) %3<\t>", _prefix, _component, _title], lineBreak]; + +{ + _compose append [lineBreak, format [" %1", _x]]; +} forEach _lines; + +_control ctrlSetStructuredText composeText _compose; + +nil diff --git a/addons/diagnostic/fnc_log.sqf b/addons/diagnostic/fnc_log.sqf index aa30f5a11..7fb408e43 100644 --- a/addons/diagnostic/fnc_log.sqf +++ b/addons/diagnostic/fnc_log.sqf @@ -1,65 +1,45 @@ /* ---------------------------------------------------------------------------- -Function: CBA_fnc_log +Internal Function: CBA_fnc_log Description: Logs a message to the RPT log. Should not be used directly, but rather via macro (). - This function is unaffected by the debug level (). Parameters: - _file - File error occurred in [String] - _lineNum - Line number error occurred on (starting from 0) [Number] - _message - Message [String] + _message - Message Returns: nil Author: - Spooner and Rommel + Spooner, Rommel, commy2 -----------------------------------------------------------------------------*/ #define DEBUG_MODE_NORMAL #include "script_component.hpp" - SCRIPT(log); -// ---------------------------------------------------------------------------- +params [["_message", "", [""]]]; + +if (isNil QGVAR(logArray)) then { + GVAR(logArray) = []; + GVAR(logScript) = scriptNull; +}; -#ifndef DEBUG_SYNCHRONOUS - if (isNil "CBA_LOG_ARRAY") then { CBA_LOG_ARRAY = [] }; - private ["_msg"]; - _msg = [_this select 0, _this select 1, _this select 2, diag_frameNo, diag_tickTime, time]; // Save it here because we want to know when it was happening, not when it is outputted - CBA_LOG_ARRAY pushBack _msg; +GVAR(logArray) pushBack text _message; - if (isNil "CBA_LOG_VAR") then - { - CBA_LOG_VAR = true; - SLX_XEH_STR spawn - { - _fnc_log = - { - params ["_file","_lineNum","_message","_frameNo","_tickTime","_gameTime"]; - // TODO: Add log message to trace log - diag_log [_frameNo, - _tickTime, _gameTime, //[_tickTime, "H:MM:SS.mmm"] call CBA_fnc_formatElapsedTime, [_gameTime, "H:MM:SS.mmm"] call CBA_fnc_formatElapsedTime, - _file + ":"+str(_lineNum + 1), _message]; - }; +if (scriptDone GVAR(logScript)) then { + GVAR(logScript) = 0 spawn { + private "_selected"; - _selected = ""; - while {_selected = CBA_LOG_ARRAY deleteAt 0; !isNil "_selected"} do - { - _selected call _fnc_log; - }; - CBA_LOG_VAR = nil; + while { + _selected = GVAR(logArray) deleteAt 0; + !isNil "_selected" + } do { + diag_log _selected; }; }; -#else - params ["_file","_lineNum","_message"]; - // TODO: Add log message to trace log - diag_log [diag_frameNo, - diag_tickTime, time, // [diag_tickTime, "H:MM:SS.mmm"] call CBA_fnc_formatElapsedTime, [time, "H:MM:SS.mmm"] call CBA_fnc_formatElapsedTime - _file + ":"+str(_lineNum + 1), _message]; -#endif +}; -nil; +nil diff --git a/addons/diagnostic/gui.hpp b/addons/diagnostic/gui.hpp new file mode 100644 index 000000000..6301bdc27 --- /dev/null +++ b/addons/diagnostic/gui.hpp @@ -0,0 +1,26 @@ + +class RscStructuredText; + +class RscTitles { + class GVAR(Error) { + idd = -1; + duration = 5; + fadeIn = 0; + fadeOut = 0.5; + movingEnable = 0; + + class Controls { + class GVAR(Error): RscStructuredText { + onLoad = QUOTE(uiNamespace setVariable [ARR_2('GVAR(Error)',_this select 0)]); + idc = -1; + font = "RobotoCondensedBold"; + sizeEx = 0.55 * GUI_GRID_CENTER_H; + x = 0 * GUI_GRID_CENTER_W + GUI_GRID_CENTER_X; + y = 0 * GUI_GRID_CENTER_H + GUI_GRID_CENTER_Y; + w = 40 * GUI_GRID_CENTER_W; + h = 10 * GUI_GRID_CENTER_H; + colorBackground[] = {1,0.4,0,0.8}; + }; + }; + }; +}; diff --git a/addons/diagnostic/script_component.hpp b/addons/diagnostic/script_component.hpp index df0873197..b8c573417 100644 --- a/addons/diagnostic/script_component.hpp +++ b/addons/diagnostic/script_component.hpp @@ -12,3 +12,4 @@ #include "\x\cba\addons\main\script_macros.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" +#include "\a3\ui_f\hpp\defineCommonGrids.inc" diff --git a/addons/main/script_macros_common.hpp b/addons/main/script_macros_common.hpp index 69b69c681..2356bdaa3 100644 --- a/addons/main/script_macros_common.hpp +++ b/addons/main/script_macros_common.hpp @@ -134,20 +134,24 @@ Macros: DEBUG_MODE_x #define DEBUG_MODE_MINIMAL #endif -#ifdef THIS_FILE -#define THIS_FILE_ 'THIS_FILE' +#define LOG_SYS_FORMAT(LEVEL,MESSAGE) format ['[%1] (%2) %3: %4', toUpper 'PREFIX', 'COMPONENT', LEVEL, MESSAGE] + +#ifdef DEBUG_SYNCHRONOUS +#define LOG_SYS(LEVEL,MESSAGE) diag_log text LOG_SYS_FORMAT(LEVEL,MESSAGE) #else -#define THIS_FILE_ __FILE__ +#define LOG_SYS(LEVEL,MESSAGE) LOG_SYS_FORMAT(LEVEL,MESSAGE) call CBA_fnc_log #endif +#define LOG_SYS_FILELINENUMBERS(LEVEL,MESSAGE) LOG_SYS(LEVEL,format [ARR_4('%1 File: %2 Line: %3',MESSAGE,__FILE__,__LINE__ + 1)]) + /* ------------------------------------------- Macro: LOG() - Log a timestamped message into the RPT log. + Log a debug message into the RPT log. - Only run if or higher is defined. + Only run if is defined. Parameters: - MESSAGE - Message to record [String] + MESSAGE - Message to record Example: (begin example) @@ -158,19 +162,36 @@ Macro: LOG() Spooner ------------------------------------------- */ #ifdef DEBUG_MODE_FULL -#define LOG(MESSAGE) [THIS_FILE_, __LINE__, MESSAGE] call CBA_fnc_log +#define LOG(MESSAGE) LOG_SYS_FILELINENUMBERS('LOG',MESSAGE) #else #define LOG(MESSAGE) /* disabled */ #endif +/* ------------------------------------------- +Macro: INFO() + Record a message without file and line number in the RPT log. + +Parameters: + MESSAGE - Message to record + +Example: + (begin example) + INFO("Mod X is loaded, do Y"); + (end) + +Author: + commy2 +------------------------------------------- */ +#define INFO(MESSAGE) LOG_SYS('INFO',MESSAGE) + /* ------------------------------------------- Macro: WARNING() - Record a timestamped, non-critical error in the RPT log. + Record a non-critical error in the RPT log. Only run if or higher is defined. Parameters: - MESSAGE - Message to record [String] + MESSAGE - Message to record Example: (begin example) @@ -181,21 +202,17 @@ Macro: WARNING() Spooner ------------------------------------------- */ #ifdef DEBUG_MODE_NORMAL -#define WARNING(MESSAGE) [THIS_FILE_, __LINE__, ('WARNING: ' + MESSAGE)] call CBA_fnc_log +#define WARNING(MESSAGE) LOG_SYS_FILELINENUMBERS('WARNING',MESSAGE) #else #define WARNING(MESSAGE) /* disabled */ #endif /* ------------------------------------------- Macro: ERROR() - Record a timestamped, critical error in the RPT log. - - The heading is "ERROR" (use for a specific title). - - TODO: Popup an error dialog & throw an exception. + Record a critical error in the RPT log. Parameters: - MESSAGE - Message to record [String] + MESSAGE - Message to record Example: (begin example) @@ -205,12 +222,11 @@ Macro: ERROR() Author: Spooner ------------------------------------------- */ -#define ERROR(MESSAGE) \ - [THIS_FILE_, __LINE__, "ERROR", MESSAGE] call CBA_fnc_error; +#define ERROR(MESSAGE) LOG_SYS_FILELINENUMBERS('ERROR',MESSAGE) /* ------------------------------------------- Macro: ERROR_WITH_TITLE() - Record a timestamped, critical error in the RPT log. + Record a critical error in the RPT log. The title can be specified (in the heading is always just "ERROR") Newlines (\n) in the MESSAGE will be put on separate lines. @@ -218,8 +234,8 @@ Macro: ERROR_WITH_TITLE() TODO: Popup an error dialog & throw an exception. Parameters: - TITLE - Title of error message [String] - MESSAGE - Body of error message [String] + TITLE - Title of error message + MESSAGE - Body of error message Example: (begin example) @@ -229,16 +245,15 @@ Macro: ERROR_WITH_TITLE() Author: Spooner ------------------------------------------- */ -#define ERROR_WITH_TITLE(TITLE,MESSAGE) \ - [THIS_FILE_, __LINE__, TITLE, MESSAGE] call CBA_fnc_error; +#define ERROR_WITH_TITLE(TITLE,MESSAGE) ['PREFIX', 'COMPONENT', TITLE, MESSAGE, __FILE__, __LINE__ + 1] call CBA_fnc_error /* ------------------------------------------- Macro: MESSAGE_WITH_TITLE() - Record a single line, timestamped log entry in the RPT log. + Record a single line in the RPT log. Parameters: - TITLE - Title of log message [String] - MESSAGE - Body of message [String] + TITLE - Title of log message + MESSAGE - Body of message Example: (begin example) @@ -248,8 +263,7 @@ Macro: MESSAGE_WITH_TITLE() Author: Killswitch ------------------------------------------- */ -#define MESSAGE_WITH_TITLE(TITLE,MESSAGE) \ - [THIS_FILE_, __LINE__, TITLE + ': ' + (MESSAGE)] call CBA_fnc_log; +#define MESSAGE_WITH_TITLE(TITLE,MESSAGE) LOG_SYS_FILELINENUMBERS(TITLE,MESSAGE) /* ------------------------------------------- Macro: RETNIL() @@ -327,35 +341,16 @@ Macros: TRACE_n() #ifdef DEBUG_MODE_FULL -#define TRACE_1(MESSAGE,A) \ - [THIS_FILE_, __LINE__, PFORMAT_1(MESSAGE,A)] call CBA_fnc_log - -#define TRACE_2(MESSAGE,A,B) \ - [THIS_FILE_, __LINE__, PFORMAT_2(MESSAGE,A,B)] call CBA_fnc_log - -#define TRACE_3(MESSAGE,A,B,C) \ - [THIS_FILE_, __LINE__, PFORMAT_3(MESSAGE,A,B,C)] call CBA_fnc_log - -#define TRACE_4(MESSAGE,A,B,C,D) \ - [THIS_FILE_, __LINE__, PFORMAT_4(MESSAGE,A,B,C,D)] call CBA_fnc_log - -#define TRACE_5(MESSAGE,A,B,C,D,E) \ - [THIS_FILE_, __LINE__, PFORMAT_5(MESSAGE,A,B,C,D,E)] call CBA_fnc_log - -#define TRACE_6(MESSAGE,A,B,C,D,E,F) \ - [THIS_FILE_, __LINE__, PFORMAT_6(MESSAGE,A,B,C,D,E,F)] call CBA_fnc_log - -#define TRACE_7(MESSAGE,A,B,C,D,E,F,G) \ - [THIS_FILE_, __LINE__, PFORMAT_7(MESSAGE,A,B,C,D,E,F,G)] call CBA_fnc_log - -#define TRACE_8(MESSAGE,A,B,C,D,E,F,G,H) \ - [THIS_FILE_, __LINE__, PFORMAT_8(MESSAGE,A,B,C,D,E,F,G,H)] call CBA_fnc_log - -#define TRACE_9(MESSAGE,A,B,C,D,E,F,G,H,I) \ - [THIS_FILE_, __LINE__, PFORMAT_9(MESSAGE,A,B,C,D,E,F,G,H,I)] call CBA_fnc_log - +#define TRACE_1(MESSAGE,A) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_1(str diag_frameNo + ' ' + (MESSAGE),A)) +#define TRACE_2(MESSAGE,A,B) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_2(str diag_frameNo + ' ' + (MESSAGE),A,B)) +#define TRACE_3(MESSAGE,A,B,C) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_3(str diag_frameNo + ' ' + (MESSAGE),A,B,C)) +#define TRACE_4(MESSAGE,A,B,C,D) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_4(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D)) +#define TRACE_5(MESSAGE,A,B,C,D,E) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_5(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E)) +#define TRACE_6(MESSAGE,A,B,C,D,E,F) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_6(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F)) +#define TRACE_7(MESSAGE,A,B,C,D,E,F,G) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_7(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F,G)) +#define TRACE_8(MESSAGE,A,B,C,D,E,F,G,H) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_8(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F,G,H)) +#define TRACE_9(MESSAGE,A,B,C,D,E,F,G,H,I) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_9(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F,G,H,I)) #else - #define TRACE_1(MESSAGE,A) /* disabled */ #define TRACE_2(MESSAGE,A,B) /* disabled */ #define TRACE_3(MESSAGE,A,B,C) /* disabled */ @@ -365,7 +360,6 @@ Macros: TRACE_n() #define TRACE_7(MESSAGE,A,B,C,D,E,F,G) /* disabled */ #define TRACE_8(MESSAGE,A,B,C,D,E,F,G,H) /* disabled */ #define TRACE_9(MESSAGE,A,B,C,D,E,F,G,H,I) /* disabled */ - #endif /* ------------------------------------------- diff --git a/addons/settings/XEH_postInit.sqf b/addons/settings/XEH_postInit.sqf index d5475be79..607a53fb2 100644 --- a/addons/settings/XEH_postInit.sqf +++ b/addons/settings/XEH_postInit.sqf @@ -3,7 +3,7 @@ // --- refresh all settings after postInit to guarantee that events are added and settings are recieved from server { if (isNil QGVAR(serverSettings)) then { - diag_log text "[CBA] (settings): No server settings after postInit phase."; + ERROR("No server settings after postInit phase."); }; //Event to read modules @@ -14,7 +14,7 @@ [QGVAR(refreshSetting), _x] call CBA_fnc_localEvent; } forEach GVAR(allSettings); - diag_log text format ["[CBA] (settings): Settings Initialized"]; + LOG("Settings Initialized"); ["CBA_settingsInitialized", []] call CBA_fnc_localEvent; } call CBA_fnc_execNextFrame; diff --git a/addons/settings/XEH_preInit.sqf b/addons/settings/XEH_preInit.sqf index 5eaea7002..b0b68e5ae 100644 --- a/addons/settings/XEH_preInit.sqf +++ b/addons/settings/XEH_preInit.sqf @@ -49,9 +49,9 @@ addMissionEventHandler ["Loaded", { ["CBA_SettingChanged", { params ["_setting", "_value"]; - private _message = format ["[CBA] (settings): %1 = %2", _setting, _value]; + private _message = format ["%1 = %2", _setting, _value]; systemChat _message; - diag_log text _message; + LOG(_message); }] call CBA_fnc_addEventHandler; #endif @@ -68,10 +68,12 @@ if (isServer) then { params ["_setting", "_value", ["_forced", false, [false]]]; if ([_setting, "mission"] call FUNC(isForced)) exitWith { - diag_log text format ["[CBA] (settings): Setting %1 already forced, ignoring setSettingMission.", _setting]; + private _message = format ["Setting %1 already forced, ignoring setSettingMission.", str _setting]; + LOG(_message); }; if (!([_setting, _value] call FUNC(check))) exitWith { - diag_log text format ["[CBA] (settings): Value %1 is invalid for setting %2.", _value, _setting]; + private _message = format ["Value %1 is invalid for setting %2.", _value, str _setting]; + WARNING(_message); }; GVAR(missionSettings) setVariable [_setting, [_value, _forced]]; diff --git a/addons/settings/fnc_init.sqf b/addons/settings/fnc_init.sqf index fddb6bbf7..562c53cbf 100644 --- a/addons/settings/fnc_init.sqf +++ b/addons/settings/fnc_init.sqf @@ -130,7 +130,8 @@ if (!isNil "_settingInfo") then { if !([_setting, _value] call FUNC(check)) then { _value = [_setting, "default"] call FUNC(get); [_setting, _value, _forced, "client"] call FUNC(set); - diag_log text format ["[CBA] (settings): Invalid value for setting %1. Fall back to default value.", str _setting]; + private _message = format ["Invalid value for setting %1. Fall back to default value.", str _setting]; + WARNING(_message); }; GVAR(clientSettings) setVariable [_setting, [_value, _forced]]; diff --git a/addons/settings/fnc_parse.sqf b/addons/settings/fnc_parse.sqf index 1e046483d..e85e5dbf8 100644 --- a/addons/settings/fnc_parse.sqf +++ b/addons/settings/fnc_parse.sqf @@ -98,12 +98,14 @@ private _result = []; private _currentValue = [_setting, "default"] call FUNC(get); if (isNil "_currentValue") then { - diag_log text format ["[CBA] (settings): Error parsing settings file. Setting %1 does not exist.", str _setting]; + private _message = format ["Error parsing settings file. Setting %1 does not exist.", str _setting]; + ERROR(_message); } else { if ([_setting, _value] call FUNC(check)) then { _result pushBack [_setting, _value, _force]; } else { - diag_log text format ["[CBA] (settings): Error parsing settings file. Value %1 is invalid for setting %2.", _value, str _setting]; + private _message = format ["Error parsing settings file. Value %1 is invalid for setting %2.", _value, str _setting]; + ERROR(_message); }; }; }; diff --git a/addons/settings/fnc_set.sqf b/addons/settings/fnc_set.sqf index 32369aa83..aa10d61dc 100644 --- a/addons/settings/fnc_set.sqf +++ b/addons/settings/fnc_set.sqf @@ -33,7 +33,8 @@ Author: params [["_setting", "", [""]], "_value", ["_forced", nil, [false]], ["_source", "client", [""]]]; if (!isNil "_value" && {!([_setting, _value] call FUNC(check))}) exitWith { - diag_log text format ["[CBA] (settings): Value %1 is invalid for setting %2.", _value, str _setting]; + private _message = format ["Value %1 is invalid for setting %2.", _value, str _setting]; + WARNING(_message); 1 }; diff --git a/optionals/auto_load_settings_file/loadSettingsFile.sqf b/optionals/auto_load_settings_file/loadSettingsFile.sqf index 3ba92e022..4cacf4612 100644 --- a/optionals/auto_load_settings_file/loadSettingsFile.sqf +++ b/optionals/auto_load_settings_file/loadSettingsFile.sqf @@ -12,10 +12,10 @@ if (isFilePatchingEnabled) then { [_setting, _value, _force, _source] call EFUNC(settings,set); } forEach _info; - diag_log text "[CBA] (settings): Settings file loaded."; + LOG("Settings file loaded."); } else { - diag_log text "[CBA] (settings): Settings file not loaded. File empty or does not exist."; + WARNING("Settings file not loaded. File empty or does not exist."); }; } else { - diag_log text "[CBA] (settings): Cannot load settings file. File patching disabled. Use -filePatching flag."; + WARNING("Cannot load settings file. File patching disabled. Use -filePatching flag."); }; diff --git a/template/static_settings_addon/loadSettingsFile.sqf b/template/static_settings_addon/loadSettingsFile.sqf index 9de070ba0..0d67412d8 100644 --- a/template/static_settings_addon/loadSettingsFile.sqf +++ b/template/static_settings_addon/loadSettingsFile.sqf @@ -13,4 +13,4 @@ _info = _info call EFUNC(settings,parse); [_setting, _value, _force, _source] call EFUNC(settings,set); } forEach _info; -diag_log text "[CBA] (settings): Settings file loaded from PBO."; +LOG("Settings file loaded from PBO.");