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

Common - Improve PBO checking #9266

Merged
merged 39 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0b34a13
Update PBO checking
johnb432 Jul 15, 2023
8386a3c
Added kicking of clients without ACE loaded
johnb432 Aug 1, 2023
fcc8e1d
Update fnc_errorMessage.sqf
johnb432 Sep 14, 2023
42fa32b
Merge remote-tracking branch 'upstream/master' into pbo-check-update
johnb432 Sep 14, 2023
f5c0fd4
Update fnc_checkVersionNumber.sqf
johnb432 Sep 14, 2023
c41f623
Merge remote-tracking branch 'upstream/master' into pbo-check-update
johnb432 Oct 23, 2023
942a72d
Compatibility with #9568
johnb432 Oct 23, 2023
0d7669f
Merge branch 'master' into pbo-check-update
johnb432 Oct 23, 2023
152995e
More compatibility for #9568
johnb432 Oct 23, 2023
29d1f69
Merge branch 'pbo-check-update' of https://github.com/johnb432/ACE3 i…
johnb432 Oct 23, 2023
b5af267
Cleanup
johnb432 Oct 25, 2023
4b560d2
Minor cleanup + added server source
johnb432 Oct 29, 2023
329c9bb
Merge master
johnb432 Dec 20, 2023
968d643
Merge branch 'master' into pr/9266
johnb432 Jan 7, 2024
0de1b26
update outdated/not present error message
LinkIsGrim Jan 8, 2024
cf50c78
check version number fixes
LinkIsGrim Jan 8, 2024
9168207
Update fnc_errorMessage.sqf
johnb432 Jan 8, 2024
1d08693
Changed error names
johnb432 Jan 9, 2024
c84a7fb
Improved ACE detection method
johnb432 Jan 10, 2024
dd84f2f
Tweaks and fixes
johnb432 Jan 10, 2024
5514373
Try another approach
johnb432 Jan 10, 2024
a9fa625
Update events-framework.md
johnb432 Jan 10, 2024
c0f1c61
Merge branch 'master' into pr/9266
johnb432 Jan 28, 2024
c45344a
Update XEH_postInit.sqf
johnb432 Jan 28, 2024
cf711dc
Merge branch 'master' into pr/9266
johnb432 Mar 24, 2024
6b2e036
Update fnc_checkVersionNumber.sqf
johnb432 Mar 24, 2024
c21c5ca
Removed check for non-ACE clients
johnb432 Mar 24, 2024
a45c37a
Update XEH_postInit.sqf
johnb432 Mar 24, 2024
59f189b
Cleanup
johnb432 Apr 1, 2024
c66aa37
Merge branch 'master' into pr/9266
johnb432 Apr 3, 2024
87eac77
Remove rogue change
johnb432 Apr 4, 2024
effcfd1
Improved message display in systemChat
johnb432 Apr 4, 2024
7d84ea9
Update fnc_checkPBOs.sqf
johnb432 Apr 10, 2024
03d26ed
Merge branch 'master' into pr/9266
johnb432 Apr 19, 2024
6ddcfb1
Removed loop variable initialisers
johnb432 Jun 6, 2024
0d32f55
Merge branch 'master' into pr/9266
johnb432 Jun 6, 2024
5c47e88
Merge branch 'master' into pr/9266
johnb432 Jun 14, 2024
fbea26c
Fixed header
johnb432 Jun 14, 2024
27b3fba
Updated headers
johnb432 Jun 22, 2024
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
1 change: 1 addition & 0 deletions addons/common/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ PREP(changeProjectileDirection);
PREP(checkFiles);
PREP(checkFiles_diagnoseACE);
PREP(checkPBOs);
PREP(checkVersionNumber);
PREP(claim);
PREP(claimSafeServer);
PREP(codeToString);
Expand Down
115 changes: 72 additions & 43 deletions addons/common/functions/fnc_checkFiles.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -15,79 +15,94 @@
* Public: No
*/

// Don't execute in scheduled environment
if (canSuspend) exitWith {
[FUNC(checkFiles), nil] call CBA_fnc_directCall;
};

///////////////
// check addons
// Check addons
///////////////
private _mainCfg = configFile >> "CfgPatches" >> "ace_main";
private _mainVersion = getText (_mainCfg >> "versionStr");
private _mainSource = configSourceMod _mainCfg;
private _cfgPatches = configFile >> "CfgPatches";
private _mainVersion = getText (_cfgPatches >> "ace_main" >> "versionStr");
private _mainSource = configSourceMod (_cfgPatches >> "ace_main");

//CBA Versioning check - close main display if using incompatible version
private _cbaVersionAr = getArray (configFile >> "CfgPatches" >> "cba_main" >> "versionAr");
// CBA Versioning check - close main display if using incompatible version
private _cbaVersionAr = getArray (_cfgPatches >> "cba_main" >> "versionAr");
private _cbaRequiredAr = getArray (configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> "ACE" >> "dependencies" >> "CBA") select 1;

private _cbaVersionStr = _cbaVersionAr joinString ".";
private _cbaRequiredStr = _cbaRequiredAr joinString ".";

INFO_3("ACE is version %1 - CBA is version %2 (min required %3)",_mainVersion,_cbaVersionStr,_cbaRequiredStr);

if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) then {
if ([_cbaRequiredAr, _cbaVersionAr] call CBA_versioning_fnc_version_compare) then {
private _errorMsg = format ["CBA version %1 is outdated (required %2)", _cbaVersionStr, _cbaRequiredStr];
ERROR(_errorMsg);

if (hasInterface) then {
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
};
};

//private _addons = activatedAddons; // broken with High-Command module, see #2134
private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLowerANSI _x};
//private _addons = activatedAddons; // Broken with High-Command module, see #2134
private _addons = (CBA_common_addons select {(_x select [0, 4]) == "ace_"}) apply {toLowerANSI _x};

private _oldAddons = [];
private _oldSources = [];
private _oldCompats = [];

{
private _addonCfg = configFile >> "CfgPatches" >> _x;
private _addonVersion = getText (_addonCfg >> "versionStr");

if (_addonVersion != _mainVersion) then {
private _addonSource = configSourceMod _addonCfg;

_oldSources pushBackUnique _addonSource;

// Check ACE install
call FUNC(checkFiles_diagnoseACE);

// Don't block game if it's just an old compat pbo
if ((_x select [0, 10]) != "ace_compat") then {
if (hasInterface) then {
_oldAddons pushBack _x;
};
_oldAddons pushBack _x;
} else {
_oldCompats pushBack [_x, _addonVersion]; // Don't block game if it's just an old compat pbo
_oldCompats pushBack [_x, _addonVersion];
};
};
} forEach _addons;

if (_oldAddons isNotEqualTo []) then {
_oldAddons = _oldAddons apply { format ["%1.pbo", _x] };
private _errorMsg = "";
if (count _oldAddons > 3) then {
_errorMsg = format ["The following files are outdated: %1, and %2 more.<br/>ACE Main version is %3 from %4.<br/>Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) -3, _mainVersion, _mainSource, (_oldSources joinString ", ")];
_oldAddons = _oldAddons apply {format ["%1.pbo", _x]};

private _errorMsg = if (count _oldAddons > 3) then {
format ["The following files are outdated: %1, and %2 more.<br/>ACE Main version is %3 from %4.<br/>Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) - 3, _mainVersion, _mainSource, _oldSources joinString ", "];
} else {
_errorMsg = format ["The following files are outdated: %1.<br/>ACE Main version is %2 from %3.<br/>Loaded mods with outdated ACE files: %4", (_oldAddons) joinString ", ", _mainVersion, _mainSource, (_oldSources) joinString ", "];
format ["The following files are outdated: %1.<br/>ACE Main version is %2 from %3.<br/>Loaded mods with outdated ACE files: %4", _oldAddons joinString ", ", _mainVersion, _mainSource, _oldSources joinString ", "];
};

if (hasInterface) then {
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
};

ERROR(_errorMsg);
};

if (_oldCompats isNotEqualTo []) then {
_oldCompats = _oldCompats apply {format ["%1 (%2)", _x select 0, _x select 1]};

[{
// Lasts for ~10 seconds
ERROR_WITH_TITLE_3("The following ACE compatiblity PBOs are outdated","%1. ACE Main version is %2 from %3.",_this select 0,_this select 1,_this select 2);
}, [_oldCompats, _mainVersion, _mainSource], 1] call CBA_fnc_waitAndExecute;
};

///////////////
// check extensions
// Check extensions
///////////////
private _platform = toLowerANSI (productVersion select 6);

if (!isServer && {_platform in ["linux", "osx"]}) then {
// Linux and OSX client ports do not support extensions at all
INFO("Operating system does not support extensions");
Expand All @@ -101,8 +116,10 @@ if (!isServer && {_platform in ["linux", "osx"]}) then {

if ((_isWindows || _isLinux) && {_isClient || _isServer}) then {
private _versionEx = _extension callExtension "version";

if (_versionEx == "") then {
private _extensionFile = _extension;

if (productVersion select 7 == "x64") then {
_extensionFile = format ["%1_x64", _extensionFile];
};
Expand All @@ -114,7 +131,7 @@ if (!isServer && {_platform in ["linux", "osx"]}) then {
ERROR(_errorMsg);

if (hasInterface) then {
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
};
} else {
// Print the current extension version
Expand All @@ -123,54 +140,66 @@ if (!isServer && {_platform in ["linux", "osx"]}) then {
};
} forEach ("true" configClasses (configFile >> "ACE_Extensions"));
};

if (isArray (configFile >> "ACE_Extensions" >> "extensions")) then {
WARNING("extensions[] array no longer supported");
};

///////////////
// check server version/addons
// Check server version/addons
///////////////
if (isMultiplayer) then {
// don't check optional addons
_addons = _addons select {getNumber (configFile >> "CfgPatches" >> _x >> "ACE_isOptional") != 1};
// Don't check optional addons
_addons = _addons select {getNumber (_cfgPatches >> _x >> "ACE_isOptional") != 1};

if (isServer) then {
// send servers version of ACE to all clients
GVAR(ServerVersion) = _mainVersion;
GVAR(ServerAddons) = _addons;
publicVariable QGVAR(ServerVersion);
publicVariable QGVAR(ServerAddons);
// Send server's version of ACE to all clients
GVAR(serverVersion) = _mainVersion;
GVAR(serverAddons) = _addons;
GVAR(serverSource) = _mainSource;

publicVariable QGVAR(serverVersion);
publicVariable QGVAR(serverAddons);
publicVariable QGVAR(serverSource);
} else {
// clients have to wait for the variables
[{
if (isNil QGVAR(ServerVersion) || isNil QGVAR(ServerAddons)) exitWith {};

(_this select 0) params ["_mainVersion", "_addons"];
GVAR(clientVersion) = _version;
GVAR(clientAddons) = _addons;

if (_mainVersion != GVAR(ServerVersion)) then {
private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _mainVersion];
private _fnc_check = {
if (GVAR(clientVersion) != GVAR(serverVersion)) then {
private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2. Server modDir: %3", GVAR(serverVersion), GVAR(clientVersion), GVAR(serverSource)];

// Check ACE install
call FUNC(checkFiles_diagnoseACE);

ERROR(_errorMsg);

if (hasInterface) then {
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
};
};

_addons = _addons - GVAR(ServerAddons);
private _addons = GVAR(clientAddons) - GVAR(serverAddons);

if (_addons isNotEqualTo []) then {
private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons];
private _errorMsg = format ["Client/Server Addon Mismatch. Client has additional addons: %1. Server modDir: %2", _addons, GVAR(serverSource)];

// Check ACE install
call FUNC(checkFiles_diagnoseACE);

ERROR(_errorMsg);

if (hasInterface) then {
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
};
};
};

[_this select 1] call CBA_fnc_removePerFrameHandler;
}, 1, [_mainVersion,_addons]] call CBA_fnc_addPerFrameHandler;
// Clients have to wait for the variables
if (isNil QGVAR(serverVersion) || isNil QGVAR(serverAddons)) then {
GVAR(serverVersion) addPublicVariableEventHandler _fnc_check;
} else {
call _fnc_check;
};
};
};
48 changes: 32 additions & 16 deletions addons/common/functions/fnc_checkFiles_diagnoseACE.sqf
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Diagnose ACE install problems, this will only be called if there is a known problem
* Diagnoses ACE install problems, this will only be called if there is a known problem.
*
* Arguments:
* None
*
* Return Value:
* None
* ACE addons' WS IDs <HASHMAP>
*
* Example:
* [] call ace_common_fnc_checkFiles_diagnoseACE
Expand All @@ -16,43 +16,59 @@
*/

// Only run once
if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith {};
if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith {
createHashMap // return
};

GVAR(checkFiles_diagnoseACE) = true;

private _addons = cba_common_addons select {(_x select [0,4]) == "ace_"};
private _addons = CBA_common_addons select {(_x select [0, 4]) == "ace_"};
private _cfgPatches = configFile >> "CfgPatches";
private _allMods = createHashMap;
private _getLoadedModsInfo = getLoadedModsInfo;

// Check ACE_ADDONs are in expected mod DIR
// Check if ACE_ADDONs are in expected mod DIR
{
private _cfg = (_cfgPatches >> _x);
private _cfg = _cfgPatches >> _x;
private _actualModDir = configSourceMod _cfg;
private _expectedModDir = getText (_cfg >> "ACE_expectedModDir");
if (_expectedModDir == "") then { _expectedModDir = "@ace" };

if (_expectedModDir == "") then {
_expectedModDir = "@ace";
};

private _expectedSteamID = getText (_cfg >> "ACE_expectedSteamID");
if (_expectedSteamID == "") then { _expectedSteamID = "463939057" };

if (_expectedSteamID == "") then {
_expectedSteamID = "463939057"
};

(_allMods getOrDefault [_actualModDir, [], true]) pushBackUnique _expectedSteamID;

if (_actualModDir != _expectedModDir) then {
private _errorMsg = format ["%1 loading from unexpected modDir [%2]",_x,_actualModDir];
private _errorMsg = format ["%1 loading from unexpected modDir [%2]", _x, _actualModDir];
systemChat _errorMsg;
WARNING_1("%1",_errorMsg);
};
} forEach _addons;

// Check all ACE ModDirs have expected steam WS ID
// Check if all ACE ModDirs have expected steam WS ID
{
private _modDir = _x;
if ((count _y) != 1) then { ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y) };
private _expectedSteamID = _y # 0;
private _index = getLoadedModsInfo findIf {_x#1 == _modDir};
(getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]];

if (count _y != 1) then {
ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y);
};

private _expectedSteamID = _y select 0;
private _index = _getLoadedModsInfo findIf {_x select 1 == _modDir};
(_getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]];

if (_actualID != _expectedSteamID) then {
private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]",_modDir,_modName,_actualID];
private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]", _modDir, _modName, _actualID];
systemChat _errorMsg;
WARNING_1("%1",_errorMsg);
};
} forEach _allMods;

_allMods
_allMods // return
Loading
Loading