ACE3/addons/common/functions/fnc_checkVersionNumber.sqf
johnb432 7ea2aab2c9
Common - Improve PBO checking (#9266)
* Update PBO checking

* Added kicking of clients without ACE loaded

* Update fnc_errorMessage.sqf

* Update fnc_checkVersionNumber.sqf

* More compatibility for #9568

* Cleanup

* Minor cleanup + added server source

* update outdated/not present error message

* check version number fixes

* Update fnc_errorMessage.sqf

* Changed error names

Server is always right, client has either older or newer versions, or missing or additional addons

* Improved ACE detection method

* Tweaks and fixes

* Try another approach

* Update events-framework.md

* Update XEH_postInit.sqf

* Update fnc_checkVersionNumber.sqf

* Removed check for non-ACE clients

* Update XEH_postInit.sqf

* Cleanup

* Remove rogue change

* Improved message display in systemChat

* Update fnc_checkPBOs.sqf

* Removed loop variable initialisers

* Fixed header

* Updated headers

---------

Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com>
Co-authored-by: LinkIsGrim <salluci.lovi@gmail.com>
2024-06-22 15:52:59 +02:00

162 lines
5.5 KiB
Plaintext

#include "..\script_component.hpp"
/*
* Author: commy2, johnb43
* Compares version numbers from loaded addons.
*
* Arguments:
* 0: Lowercase addon whitelist <ARRAY> (default: missionNamespace getVariable ["ACE_Version_Whitelist", []])
*
* Return Value:
* None
*
* Example:
* call ace_common_fnc_checkVersionNumber
*
* Public: No
*/
// Don't execute in scheduled environment
if (canSuspend) exitWith {
[FUNC(checkVersionNumber), _this] call CBA_fnc_directCall;
};
params [["_whitelist", missionNamespace getVariable ["ACE_Version_Whitelist", []]]];
private _files = CBA_common_addons select {
(_x select [0, 3] != "a3_") &&
{_x select [0, 4] != "ace_"} &&
{!((toLowerANSI _x) in _whitelist)}
};
private _cfgPatches = configFile >> "CfgPatches";
private _versions = [];
{
(getText (_cfgPatches >> _x >> "version") splitString ".") params [["_major", "0"], ["_minor", "0"]];
private _version = parseNumber _major + parseNumber _minor / 100;
_versions pushBack _version;
} forEach _files;
if (isServer) exitWith {
ACE_Version_ServerVersions = [_files, _versions];
publicVariable "ACE_Version_ServerVersions";
// Raise event when done
["ace_versioning_serverCheckDone", [+ACE_Version_ServerVersions]] call CBA_fnc_localEvent;
};
// Begin client version check
ACE_Version_ClientVersions = [_files, _versions];
private _fnc_check = {
ACE_Version_ClientVersions params [["_files", []], ["_versions", []]];
ACE_Version_ServerVersions params [["_serverFiles", []], ["_serverVersions", []]];
// Compare client and server files and versions
private _client = profileName;
private _missingAddonsClient = [];
private _olderVersionsClient = [];
private _newerVersionsClient = [];
{
private _serverVersion = _serverVersions select _forEachIndex;
private _index = _files find _x;
if (_index == -1) then {
if (_x != "ace_server") then {
_missingAddonsClient pushBack _x;
};
} else {
private _clientVersion = _versions select _index;
if (_clientVersion < _serverVersion) then {
_olderVersionsClient pushBack [_x, _clientVersion, _serverVersion];
};
if (_clientVersion > _serverVersion) then {
_newerVersionsClient pushBack [_x, _clientVersion, _serverVersion];
};
};
} forEach _serverFiles;
// Find client files which the server doesn't have
private _additionalAddonsClient = _files select {!(_x in _serverFiles)};
// Check for client missing addons, server missing addons, client outdated addons and server outdated addons
private _clientErrors = [];
#define DISPLAY_NUMBER_ADDONS (10 + 1) // +1 to account for header
{
_x params ["_items", "_string"];
// Check if something is either missing or outdated
private _isMissingItems = _items isNotEqualTo [];
if (_isMissingItems) then {
// Generate error message
private _errorLog = +_items;
private _header = format ["[ACE] %1: ERROR %2 addon(s): ", _client, _string];
// Don't display all missing items, as they are logged
private _errorMsg = _header + ((_errorLog select [0, DISPLAY_NUMBER_ADDONS]) joinString ", ");
_errorLog = _header + (_errorLog joinString ", ");
private _count = count _items;
if (_count > DISPLAY_NUMBER_ADDONS) then {
_errorMsg = _errorMsg + format [", and %1 more.", _count - DISPLAY_NUMBER_ADDONS];
};
// Wait until in briefing screen
[{
getClientStateNumber >= 9 // "BRIEFING SHOWN"
}, {
params ["_errorLog", "_errorMsg"];
// Log and display error messages
diag_log text _errorLog;
[QGVAR(serverLog), _errorLog] call CBA_fnc_serverEvent;
[QGVAR(systemChatGlobal), _errorMsg] call CBA_fnc_globalEvent;
// Wait until after map screen
[{
!isNull (call BIS_fnc_displayMission)
}, {
params ["_errorMsg", "_timeOut"];
// If the briefing screen was shown for less than 5 seconds, display the error message again, but locally
if (_timeOut < CBA_missionTime) exitWith {};
// Make sure systemChat is ready by waiting a bit
[{
systemChat _this;
}, _errorMsg, 1] call CBA_fnc_waitAndExecute;
}, [_errorMsg, CBA_missionTime + 5]] call CBA_fnc_waitUntilAndExecute;
}, [_errorLog, _errorMsg]] call CBA_fnc_waitUntilAndExecute;
};
_clientErrors pushBack _isMissingItems;
} forEach [
[_missingAddonsClient, "client missing"],
[_additionalAddonsClient, "client additional"],
[_olderVersionsClient, "older client"],
[_newerVersionsClient, "newer client"]
];
TRACE_4("",_missingAddonsClient,_additionalAddonsClient,_olderVersionsClient,_newerVersionsClient);
ACE_Version_ClientErrors = _clientErrors;
// Raise event when done
["ace_versioning_clientCheckDone", [+ACE_Version_ClientErrors]] call CBA_fnc_localEvent;
};
// Wait for server to send the servers files and version numbers
if (isNil "ACE_Version_ServerVersions") then {
ACE_Version_ServerVersions addPublicVariableEventHandler _fnc_check;
} else {
call _fnc_check;
};