From 1d37b5eea67bf068d9fdfbd2b306a074dca44162 Mon Sep 17 00:00:00 2001 From: commy2 Date: Fri, 21 May 2021 15:37:57 +0200 Subject: [PATCH 1/4] Ordered Dicts Macros --- addons/hashes/orderedDicts.hpp | 25 +++++ addons/hashes/script_component.hpp | 2 + addons/hashes/test.sqf | 2 +- addons/hashes/test_orderedDicts.sqf | 137 ++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 addons/hashes/orderedDicts.hpp create mode 100644 addons/hashes/test_orderedDicts.sqf diff --git a/addons/hashes/orderedDicts.hpp b/addons/hashes/orderedDicts.hpp new file mode 100644 index 0000000000..4b540fff4c --- /dev/null +++ b/addons/hashes/orderedDicts.hpp @@ -0,0 +1,25 @@ +#define DICT_CREATE [createHashMap, []] +#define _DICT_MAP(D) ((D) select 0) +#define _DICT_LIST(D) ((D) select 1) + +#define DICT_SET(D,k,v) (call {\ + _DICT_MAP(D) set [k, v];\ + _DICT_LIST(D) pushBackUnique (k) != -1\ +}) + +#define DICT_GET(D,k) (_DICT_MAP(D) get (k)) +#define DICT_GET_DEFAULT(D,k,d) (_DICT_MAP(D) getOrDefault [k, d]) +#define DICT_POP(D,k) (_DICT_MAP(D) deleteAt (_DICT_LIST(D) deleteAt (_DICT_LIST(D) find (k)))) +#define DICT_CONTAINS(D,k) ((k) in _DICT_MAP(D)) + +#define DICT_KEYS(D) (+ _DICT_LIST(D)) +#define DICT_VALUES(D) (_DICT_LIST(D) apply {_DICT_MAP(D) get _x}) +#define DICT_COUNT(D) (count _DICT_LIST(D)) + +// note, overwrites "_this" variable +#define DICT_FOR_EACH(D) call {\ + {\ + private _y = DICT_GET(D, _x);\ + call _this;\ + } forEach DICT_KEYS(D);\ +} diff --git a/addons/hashes/script_component.hpp b/addons/hashes/script_component.hpp index 6aa5dec14a..23585ed84f 100644 --- a/addons/hashes/script_component.hpp +++ b/addons/hashes/script_component.hpp @@ -10,3 +10,5 @@ #endif #include "\x\cba\addons\main\script_macros.hpp" + +#include "orderedDicts.hpp" diff --git a/addons/hashes/test.sqf b/addons/hashes/test.sqf index 1755af0e20..38315232ef 100644 --- a/addons/hashes/test.sqf +++ b/addons/hashes/test.sqf @@ -5,7 +5,7 @@ #define DEBUG_MODE_FULL #include "script_component.hpp" -#define TESTS ["hashEachPair", "hashes", "parseJSON", "parseYaml", "hashFilter"] +#define TESTS ["hashEachPair", "hashes", "parseJSON", "parseYaml", "hashFilter", "orderedDicts"] SCRIPT(test-hashes); diff --git a/addons/hashes/test_orderedDicts.sqf b/addons/hashes/test_orderedDicts.sqf new file mode 100644 index 0000000000..3b28cfa11d --- /dev/null +++ b/addons/hashes/test_orderedDicts.sqf @@ -0,0 +1,137 @@ +// ---------------------------------------------------------------------------- + +#include "script_component.hpp" + +SCRIPT(test_orderedDicts); + +// ---------------------------------------------------------------------------- +#define DEBUG_MODE_FULL + +LOG("Testing Ordered Dicts"); + +// happy basic operations +private _dict = DICT_CREATE; +DICT_SET(_dict, "A", []); +DICT_SET(_dict, "B", "x"); +DICT_SET(_dict, "C", 1); + +private _result = DICT_GET(_dict, "A"); +TEST_OP(_result,isEqualTo,[],"DICT_GET()/A"); + +_result = DICT_GET(_dict, "B"); +TEST_OP(_result,==,"x","DICT_GET()/B"); + +_result = DICT_GET(_dict, "C"); +TEST_OP(_result,==,1,"DICT_GET()/C"); + +_result = DICT_GET(_dict, "D"); +TEST_TRUE(isNil "_result","DICT_GET()/missing"); + +DICT_SET(_dict, "A", objNull); +_result = DICT_GET(_dict, "A"); +TEST_TRUE(isNull _result,"DICT_GET()/overwrite"); + +_result = DICT_GET_DEFAULT(_dict, "B", ""); +TEST_OP(_result,==,"x","DICT_GET_DEFAULT()/defined"); + +_result = DICT_GET_DEFAULT(_dict, "E", -2); +TEST_OP(_result,==,-2,"DICT_GET_DEFAULT()/missing"); + +DICT_POP(_dict, "A"); +_result = DICT_GET_DEFAULT(_dict, "A", west); +TEST_OP(_result,isEqualType,sideEmpty,"DICT_GET_DEFAULT()/removed"); + +_result = DICT_POP(_dict, "B"); +TEST_OP(_result,==,"x","DICT_POP()/return value"); + +_result = DICT_POP(_dict, "D"); +TEST_TRUE(isNil "_result","DICT_POP()/missing"); + +_result = DICT_GET(_dict, "B"); +TEST_TRUE(isNil "_result","DICT_GET()/already removed before"); + +DICT_SET(_dict, "B", 2); +_result = DICT_GET_DEFAULT(_dict, "B", "x"); +TEST_OP(_result,==,2,"DICT_GET_DEFAULT()/re-added"); + +_result = DICT_CONTAINS(_dict, "E"); +TEST_FALSE(_result,"DICT_CONTAINS()/missing"); + +_result = DICT_CONTAINS(_dict, "A"); +TEST_FALSE(_result,"DICT_CONTAINS()/removed"); + +DICT_SET(_dict, "A", 3); +_result = DICT_GET_DEFAULT(_dict, "A", west); +TEST_OP(_result,==,3,"DICT_GET_DEFAULT()/re-added"); + +_result = DICT_CONTAINS(_dict, "A"); +TEST_TRUE(_result,"DICT_CONTAINS()/found"); + +_result = DICT_KEYS(_dict); +#define EXPECTED ["C","B","A"] +TEST_OP(_result,isEqualTo,EXPECTED,"DICT_KEYS()"); + +_result = DICT_VALUES(_dict); +#define EXPECTED [1,2,3] +TEST_OP(_result,isEqualTo,EXPECTED,"DICT_VALUES()"); + +_result = DICT_COUNT(_dict); +TEST_OP(_result,==,3,"DICT_COUNT()"); + +_result = ""; +{ + _result = _result + format ["%1=%2;", _x, _y]; +} DICT_FOR_EACH(_dict); +TEST_OP(_result,==,"C=1;B=2;A=3;","DICT_FOR_EACH()"); + + +// nasty evil edge-cases +_dict = DICT_CREATE; +DICT_SET(_dict, [], "value"); +(DICT_KEYS(_dict) select 0) pushBack 1; +_result = [1] in DICT_KEYS(_dict); // uses list +TEST_FALSE(_result,"DICT array keys-list"); + +_result = DICT_CONTAINS(_dict, [1]); +TEST_FALSE(_result,"DICT array keys-map"); + +DICT_SET(_dict, "key", []); +DICT_GET(_dict, "key") pushBack 2; +_result = DICT_GET(_dict, "key"); +TEST_OP(_result,isEqualTo,[2],"DICT array values"); + +private _resultLeft = DICT_KEYS(_dict) select 0; +_resultLeft pushBack 3; // [1,3] +_result = DICT_KEYS(_dict) select 0; // [1] +TEST_OP(_resultLeft,isNotEqualTo,_result,"DICT array keys modified"); + +_resultLeft = DICT_GET(_dict, "key"); +_resultLeft pushBack 4; // [2,4] +_result = DICT_GET(_dict, "key"); // [2,4] +TEST_OP(_resultLeft,isEqualTo,_result,"DICT array values modified"); + +_dict = DICT_CREATE; +DICT_SET(_dict, "key", nil); // key works, value set to nil w/o error +DICT_SET(_dict, nil, "value"); // key fails silently, no additional value +_result = str DICT_KEYS(_dict); +TEST_OP(_result,==,"[""key""]","DICT nil keys"); + +_result = str DICT_VALUES(_dict); +TEST_OP(_result,==,"[any]","DICT nil values"); + +_result = DICT_GET(_dict, nil); +TEST_TRUE(isNil "_result","DICT nil values\DICT_GET"); + +_result = DICT_GET_DEFAULT(_dict, nil, 127); +TEST_OP(_result,==,127,"DICT nil values\DICT_GET_DEFAULT"); + +_dict = DICT_CREATE; +DICT_SET(_dict, "Key", true); +_result = DICT_GET_DEFAULT(_dict, "keY", false); +TEST_FALSE(_result,"DICT key case-sensitivity"); + +_result = "keY" in DICT_KEYS(_dict); +TEST_FALSE(_result,"DICT key case-sensitivity-list"); + +_result = DICT_CONTAINS(_dict, "keY"); +TEST_FALSE(_result,"DICT key case-sensitivity-map"); From 4bc018ff2786903a6fd7c5164b86dfa99f2a1a1c Mon Sep 17 00:00:00 2001 From: commy2 Date: Fri, 21 May 2021 16:29:18 +0200 Subject: [PATCH 2/4] Replace CBA Hash in CBA_fnc_addPlayerAction --- addons/common/XEH_preClientInit.sqf | 2 +- addons/common/fnc_addPlayerAction.sqf | 12 ++++++------ addons/common/fnc_removePlayerAction.sqf | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/addons/common/XEH_preClientInit.sqf b/addons/common/XEH_preClientInit.sqf index d78ed7c3a4..00d15dc934 100644 --- a/addons/common/XEH_preClientInit.sqf +++ b/addons/common/XEH_preClientInit.sqf @@ -4,7 +4,7 @@ LOG(MSG_INIT); if (hasInterface) then { // ArmA - actionmonitor.sqf v1.0 Original by BN880, converted by Sickboy (sb_at_dev-heaven.net), 6th Sense - Share the Spirit - GVAR(actionList) = [] call CBA_fnc_hashCreate; + GVAR(actionList) = createHashMap; GVAR(actionListUpdated) = false; // Set true to force recreation of actions. GVAR(nextActionIndex) = 0; // Next index that will be given out. GVAR(actionListPFEH) = false; diff --git a/addons/common/fnc_addPlayerAction.sqf b/addons/common/fnc_addPlayerAction.sqf index 45465de09b..bd0e1b8e0d 100644 --- a/addons/common/fnc_addPlayerAction.sqf +++ b/addons/common/fnc_addPlayerAction.sqf @@ -49,12 +49,12 @@ private _return = if (isDedicated) then { GVAR(actionIndexes) = []; }; GVAR(actionListUpdated) = false; - [GVAR(actionList), { - TRACE_3("Inside the code for the hashPair",(vehicle player),GVAR(actionIndexes), _value); - if ((!isNil "_value") && {_value isEqualType []}) then { - GVAR(actionIndexes) pushBack (_curVic addAction _value); + { + TRACE_3("Inside the code for the hashPair",(vehicle player),GVAR(actionIndexes), _y); + if ((!isNil "_y") && {_y isEqualType []}) then { + GVAR(actionIndexes) pushBack (_curVic addAction _y); }; - }] call CBA_fnc_hashEachPair; + } forEach GVAR(actionList); }; _params set [0, (vehicle player)]; }; @@ -62,7 +62,7 @@ private _return = if (isDedicated) then { }; private _index = GVAR(nextActionIndex); - [GVAR(actionList), _index, _actionArray] call CBA_fnc_hashSet; + GVAR(actionList) set [_index, _actionArray]; GVAR(actionListUpdated) = true; INC(GVAR(nextActionIndex)); _index; diff --git a/addons/common/fnc_removePlayerAction.sqf b/addons/common/fnc_removePlayerAction.sqf index 94a7fcaef7..b34f543cb1 100644 --- a/addons/common/fnc_removePlayerAction.sqf +++ b/addons/common/fnc_removePlayerAction.sqf @@ -33,8 +33,8 @@ private _return = if (isDedicated) then { WARNING("Function ran on a dedicated server. Function only usable on a client. Index was: " + str _actionIndex); false; } else { - if ([GVAR(actionList), _actionIndex] call CBA_fnc_hashHasKey) then { - [GVAR(actionlist),_actionIndex, nil] call CBA_fnc_hashSet; + if (_actionIndex in GVAR(actionList)) then { + GVAR(actionlist) deleteAt _actionIndex; GVAR(actionListUpdated) = true; true; } else { From 4cb711e22293778cbbf831187abf39f56b83b8e6 Mon Sep 17 00:00:00 2001 From: commy2 Date: Fri, 21 May 2021 17:43:40 +0200 Subject: [PATCH 3/4] Replace CBA Hash in Versioning, Refactor Versioning --- addons/versioning/XEH_postInit.sqf | 14 +++- addons/versioning/XEH_postInitClient.sqf | 8 +- addons/versioning/XEH_postInitServer.sqf | 95 +++++++++++++++++------- addons/versioning/XEH_preInit.sqf | 11 +-- addons/versioning/fnc_version_check.sqf | 4 +- addons/versioning/script_component.hpp | 3 + 6 files changed, 94 insertions(+), 41 deletions(-) diff --git a/addons/versioning/XEH_postInit.sqf b/addons/versioning/XEH_postInit.sqf index 517ddabab7..57c97c54d3 100644 --- a/addons/versioning/XEH_postInit.sqf +++ b/addons/versioning/XEH_postInit.sqf @@ -8,15 +8,21 @@ SCRIPT(XEH_postInit); if (!SLX_XEH_DisableLogging) then { private _logMsgs = []; private _filter = {if (_x isEqualType 1) then {[_x] call CBA_fnc_formatNumber} else {_x}}; - [GVAR(versions), { _logMsgs pushBack format["%1=%2", _key, ([_value select 0, _filter] call CBA_fnc_filter) joinString "."]}] call CBA_fnc_hashEachPair; + + { + _logMsgs pushBack format["%1=%2", _x, ([_y select 0, _filter] call CBA_fnc_filter) joinString "."]; + } forEach GVAR(versions); + private _logMsg = _logMsgs joinString ", "; INFO_2("%1 VERSIONING:%2", [ARR_3(diag_frameNo, diag_tickTime, time)], _logMsg); }; // Dependency check and warn -[GVAR(dependencies), { - private _f = { +{ + private _key = _x; + private _value = _y; + private _f = { diag_log text _this; sleep 1; CBA_logic globalChat _this; @@ -45,4 +51,4 @@ if (!SLX_XEH_DisableLogging) then { }; }; } forEach _value; -}] call CBA_fnc_hashEachPair; +} forEach GVAR(dependencies); diff --git a/addons/versioning/XEH_postInitClient.sqf b/addons/versioning/XEH_postInitClient.sqf index 1b521466cc..a4f078eae4 100644 --- a/addons/versioning/XEH_postInitClient.sqf +++ b/addons/versioning/XEH_postInitClient.sqf @@ -6,10 +6,14 @@ SLX_XEH_STR spawn { waitUntil {!(isNil QGVAR(versions_serv))}; if (!SLX_XEH_DisableLogging) then { private _logMsgs = []; - [GVAR(versions_serv), { _logMsgs pushBack format["%1=%2", _key, (_value select 0) joinString "."]}] call CBA_fnc_hashEachPair; + { + _logMsgs pushBack format ["%1=%2", _x, (_y select 0) joinString "."]; + } forEach GVAR(versions_serv); private _logMsg = _logMsgs joinString ", "; INFO_2("%1 VERSIONING_SERVER:%2", [ARR_3(diag_frameNo, diag_tickTime, time)], _logMsg); }; - [GVAR(versions_serv), {call FUNC(version_check)}] call CBA_fnc_hashEachPair; + { + [_x, _y] call FUNC(version_check); + } forEach GVAR(versions_serv); }; diff --git a/addons/versioning/XEH_postInitServer.sqf b/addons/versioning/XEH_postInitServer.sqf index 8b0d372064..b6238d0f49 100644 --- a/addons/versioning/XEH_postInitServer.sqf +++ b/addons/versioning/XEH_postInitServer.sqf @@ -1,43 +1,86 @@ #include "script_component.hpp" -if (SLX_XEH_MACHINE select 1) exitWith { LOG("WARNING: YOUR MACHINE WAS DETECTED AS SERVER INSTEAD OF CLIENT!") }; +if (SLX_XEH_MACHINE select 1) exitWith { + LOG("WARNING: YOUR MACHINE WAS DETECTED AS SERVER INSTEAD OF CLIENT!"); +}; -GVAR(versions_serv) = + GVAR(versions); // For latest versions -GVAR(versions_server) = + GVAR(versions); // For legacy versions +GVAR(versions_serv) = + GVAR(versions); // For latest versions +GVAR(versions_server) = + GVAR(versions); // For legacy versions publicVariable QGVAR(versions_serv); publicVariable QGVAR(versions_server); // TODO: Deprecate? // Paranoid; yet pretty annoying gamebreaking issue :-) -FUNC(paranoid) = { - diag_log [diag_frameNo, diag_tickTime, time, _this, "WARNING: Some client seems to have overriden the versions array; please report to CBA devs!"]; - diag_log [GVAR(versions), GVAR(versions_serv)]; - if (isMultiplayer) then { - GVAR(versions_serv) = + GVAR(versions); - publicVariable QGVAR(versions_serv); +QGVAR(versions_serv) addPublicVariableEventHandler { + (_this select 1) call { + diag_log [ + diag_frameNo, diag_tickTime, time, _this, + "WARNING: Some client seems to have overriden the versions array; please report to CBA devs!" + ]; + + diag_log [GVAR(versions), GVAR(versions_serv)]; + + if (isMultiplayer) then { + GVAR(versions_serv) = + GVAR(versions); + publicVariable QGVAR(versions_serv); + }; }; }; -QGVAR(versions_serv) addPublicVariableEventHandler { (_this select 1) call FUNC(paranoid) }; - // Skip missing mod check if it is disabled. if (getNumber (configFile >> "CBA_disableMissingModCheck") == 1) exitWith {}; // Missing Modfolder check -FUNC(handleMismatch) = { - params ["_machine","_mod"]; - [format["%1 - Not running! (Machine: %2)", _mod, _machine], QUOTE(COMPONENT), [CBA_display_ingame_warnings, true, true]] call CBA_fnc_debug; +QGVAR(mismatch) addPublicVariableEventHandler { + (_this select 1) call { + params ["_machine", "_component"]; + + private _msg = format ["%1 - Not running! (Machine: %2)", _component, _machine]; + [_msg, QUOTE(COMPONENT), [CBA_display_ingame_warnings, true, true]] call CBA_fnc_debug; + }; }; -QGVAR(mismatch) addPublicVariableEventHandler { (_this select 1) call FUNC(handleMismatch) }; - -private "_str"; -_str = 'if(isServer)exitWith{};if (isNil "CBA_display_ingame_warnings") then { CBA_display_ingame_warnings = true; };LOG("cba_versioning_check");0 = objNull spawn { sleep 1; sleep 1; _func={GVAR(mismatch)=[format["%2 (%1)",name player, player],_this];publicVariable QGVAR(mismatch);_this spawn{_t=format["You are missing the following mod: %1",_this];diag_log text _t;sleep 2;if (CBA_display_ingame_warnings) then {player globalChat _t}}};'; -[GVAR(versions_serv), { - _cfg = (configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> _key); - _addon = if (isClass _cfg) then { if (isText (_cfg >> "main_addon")) then { getText (_cfg >> "main_addon") } else { _key + "_main" }; } else { _key + "_main" }; - // TODO: Make sensitive to level, if -2, do not check for mod - _str = _str + format['if !(isClass(configFile >> "CfgPatches" >> "%1"))exitWith{"%1" call _func};', _addon]; -}] call CBA_fnc_hashEachPair; -ADD(_str,"};"); -(compile _str) remoteExecCall ["BIS_fnc_call", -2]; +private _components = []; + +{ + private _config = configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> _x; + + if (isClass _config && {isText (_config >> "main_addon")}) then { + _components pushBack getText (_config >> "main_addon"); + } else { + _components pushBack (_x + "_main"); + }; +} forEach GVAR(versions_serv); + +[[_components], { + if (!hasInterface) exitWith {}; + params ["_components"]; + + LOG("cba_versioning_check"); + + if (isNil "CBA_display_ingame_warnings") then { + CBA_display_ingame_warnings = true; + }; + + private _showError = { + params ["_component"]; + + sleep 2; + GVAR(mismatch) = [format ["%2 (%1)", name player, player], _component]; + publicVariable QGVAR(mismatch); + + private _msg = format ["You are missing the following mod: %1", _component]; + diag_log text _msg; + + if (CBA_display_ingame_warnings) then { + sleep 2; + player globalChat _msg; + }; + }; + + { + if (!isClass (configFile >> "CfgPatches" >> _x)) exitWith { + _x spawn _showError; + }; + } forEach _components; +}] remoteExecCall ["BIS_fnc_call"]; diff --git a/addons/versioning/XEH_preInit.sqf b/addons/versioning/XEH_preInit.sqf index b2a8502cd8..398d7d0307 100644 --- a/addons/versioning/XEH_preInit.sqf +++ b/addons/versioning/XEH_preInit.sqf @@ -1,6 +1,3 @@ -// Any registered functions used in the PreINIT phase must use the uiNamespace copies of the variable. -// So uiNamespace getVariable "CBA_fnc_hashCreate" instead of just CBA_fnc_hashCreate -VM - #include "script_component.hpp" SCRIPT(XEH_preInit); /* @@ -14,8 +11,8 @@ if (isNil "CBA_display_ingame_warnings") then { CBA_display_ingame_warnings = tr if (isNil QGVAR(mismatch)) then { GVAR(mismatch) = [] }; // Build versions hashes -GVAR(versions) = [[], [[0, 0, 0], 0]] call (uiNamespace getVariable "CBA_fnc_hashCreate"); -GVAR(dependencies) = [[], ["", [0, 0, 0], "true"]] call (uiNamespace getVariable "CBA_fnc_hashCreate"); +GVAR(versions) = createHashMap; +GVAR(dependencies) = createHashMap; #define DATA configName _entry,(getArray(_entry)) for "_i" from 0 to (count (CFGSETTINGS) - 1) do @@ -27,7 +24,7 @@ for "_i" from 0 to (count (CFGSETTINGS) - 1) do private _verCfg = (configFile >> "CfgPatches" >> _cfgPatches >> "versionAr"); private _level = if (isNumber(_prefix >> "level")) then { getNumber(_prefix >> "level") } else { -1 }; private _version = if (isArray(_verCfg)) then { [getArray(_verCfg), _level] } else { [[0, 0, 0], 0] }; - [GVAR(versions), toLower(configName _prefix), _version] call (uiNamespace getVariable "CBA_fnc_hashSet"); + GVAR(versions) set [toLower configName _prefix, _version]; private _deps = (_prefix >> "dependencies"); if (isClass(_deps)) then { private _dependencies = []; @@ -37,7 +34,7 @@ for "_i" from 0 to (count (CFGSETTINGS) - 1) do _dependencies pushBack [DATA]; }; }; - [GVAR(dependencies), toLower(configName _prefix), _dependencies] call (uiNamespace getVariable "CBA_fnc_hashSet"); + GVAR(dependencies) set [toLower configName _prefix, _dependencies]; }; }; }; diff --git a/addons/versioning/fnc_version_check.sqf b/addons/versioning/fnc_version_check.sqf index c07b514594..d4a16cf321 100644 --- a/addons/versioning/fnc_version_check.sqf +++ b/addons/versioning/fnc_version_check.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" -// _key, _value are injected by the CBA_fnc_hashEachPair +params ["_key", "_value"]; -private _localValue = [GVAR(versions), _key] call CBA_fnc_hashGet; +private _localValue = GVAR(versions) getOrDefault [_key, VERSION_DEFAULT]; TRACE_3("Version Check",_key,_value,_localValue); private _failed = false; diff --git a/addons/versioning/script_component.hpp b/addons/versioning/script_component.hpp index b04c0ffea5..1347bbb255 100644 --- a/addons/versioning/script_component.hpp +++ b/addons/versioning/script_component.hpp @@ -11,3 +11,6 @@ #define DEBUG_SYNCHRONOUS #include "\x\cba\addons\main\script_macros.hpp" + +#define VERSION_DEFAULT [[0, 0, 0], 0] +#define DEPENDENCY_DEFAULT ["", [0, 0, 0], "true"] From a0ac805cf087a3911661973ed2652898a00e2c9c Mon Sep 17 00:00:00 2001 From: commy2 Date: Sat, 22 May 2021 15:41:56 +0200 Subject: [PATCH 4/4] Optimize --- addons/versioning/XEH_postInitServer.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/versioning/XEH_postInitServer.sqf b/addons/versioning/XEH_postInitServer.sqf index b6238d0f49..5e756e5a20 100644 --- a/addons/versioning/XEH_postInitServer.sqf +++ b/addons/versioning/XEH_postInitServer.sqf @@ -40,10 +40,11 @@ QGVAR(mismatch) addPublicVariableEventHandler { }; }; +private _cfgVersioning = configFile >> "CfgSettings" >> "CBA" >> "Versioning"; private _components = []; { - private _config = configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> _x; + private _config = _cfgVersioning >> _x; if (isClass _config && {isText (_config >> "main_addon")}) then { _components pushBack getText (_config >> "main_addon");