Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove cba hash #1458

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/common/XEH_preClientInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 6 additions & 6 deletions addons/common/fnc_addPlayerAction.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,20 @@ 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)];
};
[_fnc, 1, [vehicle player]] call CBA_fnc_addPerFrameHandler;
};

private _index = GVAR(nextActionIndex);
[GVAR(actionList), _index, _actionArray] call CBA_fnc_hashSet;
GVAR(actionList) set [_index, _actionArray];
GVAR(actionListUpdated) = true;
INC(GVAR(nextActionIndex));
_index;
Expand Down
4 changes: 2 additions & 2 deletions addons/common/fnc_removePlayerAction.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
25 changes: 25 additions & 0 deletions addons/hashes/orderedDicts.hpp
Original file line number Diff line number Diff line change
@@ -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);\
}
2 changes: 2 additions & 0 deletions addons/hashes/script_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@
#endif

#include "\x\cba\addons\main\script_macros.hpp"

#include "orderedDicts.hpp"
2 changes: 1 addition & 1 deletion addons/hashes/test.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
137 changes: 137 additions & 0 deletions addons/hashes/test_orderedDicts.sqf
Original file line number Diff line number Diff line change
@@ -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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semi-colon ... according to the test. The test is broken.

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");
14 changes: 10 additions & 4 deletions addons/versioning/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -45,4 +51,4 @@ if (!SLX_XEH_DisableLogging) then {
};
};
} forEach _value;
}] call CBA_fnc_hashEachPair;
} forEach GVAR(dependencies);
8 changes: 6 additions & 2 deletions addons/versioning/XEH_postInitClient.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
96 changes: 70 additions & 26 deletions addons/versioning/XEH_postInitServer.sqf
Original file line number Diff line number Diff line change
@@ -1,43 +1,87 @@
#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 _cfgVersioning = configFile >> "CfgSettings" >> "CBA" >> "Versioning";
private _components = [];

{
private _config = _cfgVersioning >> _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"];
Loading