diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp
index 24ffbce3b7..25899db1ae 100644
--- a/addons/common/XEH_PREP.hpp
+++ b/addons/common/XEH_PREP.hpp
@@ -27,6 +27,7 @@ PREP(canGetInPosition);
PREP(canInteractWith);
PREP(changeProjectileDirection);
PREP(checkFiles);
+PREP(checkFiles_diagnoseACE);
PREP(checkPBOs);
PREP(claim);
PREP(claimSafeServer);
diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf
index 622855da02..9af2bcff09 100644
--- a/addons/common/functions/fnc_checkFiles.sqf
+++ b/addons/common/functions/fnc_checkFiles.sqf
@@ -18,7 +18,7 @@
///////////////
// check addons
///////////////
-private _version = getText (configFile >> "CfgPatches" >> "ace_main" >> "versionStr");
+private _mainVersion = getText (configFile >> "CfgPatches" >> "ace_main" >> "versionStr");
//CBA Versioning check - close main display if using incompatible version
private _cbaVersionAr = getArray (configFile >> "CfgPatches" >> "cba_main" >> "versionAr");
@@ -27,7 +27,7 @@ private _cbaRequiredAr = getArray (configFile >> "CfgSettings" >> "CBA" >> "Vers
private _cbaVersionStr = _cbaVersionAr joinString ".";
private _cbaRequiredStr = _cbaRequiredAr joinString ".";
-INFO_3("ACE is version %1 - CBA is version %2 (min required %3)",_version,_cbaVersionStr,_cbaRequiredStr);
+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 {
private _errorMsg = format ["CBA version %1 is outdated (required %2)", _cbaVersionStr, _cbaRequiredStr];
@@ -39,29 +39,47 @@ if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) the
//private _addons = activatedAddons; // broken with High-Command module, see #2134
private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLower _x};
-
+private _oldAddons = [];
+private _oldSources = [];
private _oldCompats = [];
{
- if (getText (configFile >> "CfgPatches" >> _x >> "versionStr") != _version) then {
- private _errorMsg = format ["File %1.pbo is outdated.", _x];
-
- ERROR(_errorMsg);
+ private _addonCfg = configFile >> "CfgPatches" >> _x;
+ private _addonVersion = getText (_addonCfg >> "versionStr");
+ if (_addonVersion != _mainVersion) then {
+ private _addonSource = configSourceMod _addonCfg;
+ _oldSources pushBackUnique _addonSource;
+ call FUNC(checkFiles_diagnoseACE);
if ((_x select [0, 10]) != "ace_compat") then {
if (hasInterface) then {
- ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
+ _oldAddons pushBack _x;
};
} else {
- _oldCompats pushBack _x; // Don't block game if it's just an old compat pbo
+ _oldCompats pushBack [_x, _addonVersion]; // Don't block game if it's just an old compat pbo
};
};
- false
-} count _addons;
+} forEach _addons;
+
+if (_oldAddons isNotEqualTo []) then {
+ _oldAddons = _oldAddons apply {"%1.pbo", _x};
+ private _errorMsg = "";
+ if (count _oldAddons > 3) then {
+ _errorMsg = format ["The following files are outdated: %1, and %2 more.
ACE Main version is %3.
Loaded mods with outdated ACE files: %4", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) -3, _mainVersion, (_oldSources joinString ", ")];
+ } else {
+ _errorMsg = format ["The following files are outdated: %1.
ACE Main version is %2.
Loaded mods with outdated ACE files: %3", (_oldAddons) joinString ", ", _mainVersion, (_oldSources) joinString ", "];
+ };
+ if (hasInterface) then {
+ ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
+ };
+ ERROR(_errorMsg);
+};
+
if (_oldCompats isNotEqualTo []) then {
+ _oldCompats = _oldCompats apply {format ["%1 (%2, source: %3)", _x select 0, _x select 1]};
[{
// Lasts for ~10 seconds
- ERROR_WITH_TITLE_1("The following ACE compatiblity PBOs are outdated", "%1", _this);
- }, _oldCompats, 1] call CBA_fnc_waitAndExecute;
+ ERROR_WITH_TITLE_2("The following ACE compatiblity PBOs are outdated", "%1. ACE Main version is %2",_this select 0,_this select 1);
+ }, [_oldCompats, _mainVersion], 1] call CBA_fnc_waitAndExecute;
};
///////////////
@@ -116,7 +134,7 @@ if (isMultiplayer) then {
if (isServer) then {
// send servers version of ACE to all clients
- GVAR(ServerVersion) = _version;
+ GVAR(ServerVersion) = _mainVersion;
GVAR(ServerAddons) = _addons;
publicVariable QGVAR(ServerVersion);
publicVariable QGVAR(ServerAddons);
@@ -125,11 +143,12 @@ if (isMultiplayer) then {
[{
if (isNil QGVAR(ServerVersion) || isNil QGVAR(ServerAddons)) exitWith {};
- (_this select 0) params ["_version", "_addons"];
+ (_this select 0) params ["_mainVersion", "_addons"];
- if (_version != GVAR(ServerVersion)) then {
- private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _version];
+ if (_mainVersion != GVAR(ServerVersion)) then {
+ private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _mainVersion];
+ call FUNC(checkFiles_diagnoseACE);
ERROR(_errorMsg);
if (hasInterface) then {
@@ -141,6 +160,7 @@ if (isMultiplayer) then {
if (_addons isNotEqualTo []) then {
private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons];
+ call FUNC(checkFiles_diagnoseACE);
ERROR(_errorMsg);
if (hasInterface) then {
@@ -149,6 +169,6 @@ if (isMultiplayer) then {
};
[_this select 1] call CBA_fnc_removePerFrameHandler;
- }, 1, [_version,_addons]] call CBA_fnc_addPerFrameHandler;
+ }, 1, [_mainVersion,_addons]] call CBA_fnc_addPerFrameHandler;
};
};
diff --git a/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf
new file mode 100644
index 0000000000..5b7f80198b
--- /dev/null
+++ b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf
@@ -0,0 +1,58 @@
+#include "..\script_component.hpp"
+/*
+ * Author: PabstMirror
+ * Diagnose ACE install problems, this will only be called if there is a known problem
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call ace_common_fnc_checkFiles_diagnoseACE
+ *
+ * Public: No
+ */
+
+// Only run once
+if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith {};
+GVAR(checkFiles_diagnoseACE) = true;
+
+private _addons = cba_common_addons select {(_x select [0,4]) == "ace_"};
+private _cfgPatches = configFile >> "CfgPatches";
+private _allMods = createHashMap;
+
+// Check ACE_ADDONs are in expected mod DIR
+{
+ private _cfg = (_cfgPatches >> _x);
+ private _actualModDir = configSourceMod _cfg;
+ private _expectedModDir = getText (_cfg >> "ACE_expectedModDir");
+ if (_expectedModDir == "") then { _expectedModDir = "@ace" };
+ private _expectedSteamID = getText (_cfg >> "ACE_expectedSteamID");
+ 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];
+ systemChat _errorMsg;
+ WARNING_1("%1",_errorMsg);
+ };
+} forEach _addons;
+
+// Check 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 (_actualID != _expectedSteamID) then {
+ private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]",_modDir,_modName,_actualID];
+ systemChat _errorMsg;
+ WARNING_1("%1",_errorMsg);
+ };
+} forEach _allMods;
+
+_allMods
diff --git a/optionals/noactionmenu/config.cpp b/optionals/noactionmenu/config.cpp
index bb0e964482..9ddc737c1b 100644
--- a/optionals/noactionmenu/config.cpp
+++ b/optionals/noactionmenu/config.cpp
@@ -12,6 +12,8 @@ class CfgPatches {
authors[] = {"commy2"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE No Action Menu";
+ ACE_expectedSteamID = "2202412030";
};
};
diff --git a/optionals/nocrosshair/config.cpp b/optionals/nocrosshair/config.cpp
index 1e5f0f3bc5..2c2433380e 100644
--- a/optionals/nocrosshair/config.cpp
+++ b/optionals/nocrosshair/config.cpp
@@ -12,6 +12,8 @@ class CfgPatches {
authors[] = {"commy2"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE No Cross Hair";
+ ACE_expectedSteamID = "2202412481";
};
};
diff --git a/optionals/nomedical/config.cpp b/optionals/nomedical/config.cpp
index e392061445..8a34203ea2 100644
--- a/optionals/nomedical/config.cpp
+++ b/optionals/nomedical/config.cpp
@@ -11,5 +11,7 @@ class CfgPatches {
authors[] = {"Dystopian"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE No Medical";
+ ACE_expectedSteamID = "3053169823";
};
};
diff --git a/optionals/norealisticnames/config.cpp b/optionals/norealisticnames/config.cpp
index e392061445..c682a9e714 100644
--- a/optionals/norealisticnames/config.cpp
+++ b/optionals/norealisticnames/config.cpp
@@ -11,5 +11,7 @@ class CfgPatches {
authors[] = {"Dystopian"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE No Realistic Names";
+ ACE_expectedSteamID = "3053177117";
};
};
diff --git a/optionals/nouniformrestrictions/config.cpp b/optionals/nouniformrestrictions/config.cpp
index 2b658fdb85..d226679a5c 100644
--- a/optionals/nouniformrestrictions/config.cpp
+++ b/optionals/nouniformrestrictions/config.cpp
@@ -11,6 +11,8 @@ class CfgPatches {
authors[] = {"654wak654", "jonpas"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE No Uniform Restrictions";
+ ACE_expectedSteamID = "2202413047";
};
};
diff --git a/optionals/particles/config.cpp b/optionals/particles/config.cpp
index ad1747529c..e62e1ed0e8 100644
--- a/optionals/particles/config.cpp
+++ b/optionals/particles/config.cpp
@@ -10,6 +10,8 @@ class CfgPatches {
authors[] = {"BaerMitUmlaut"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE Particles";
+ ACE_expectedSteamID = "2202413537";
};
};
diff --git a/optionals/realisticdispersion/config.cpp b/optionals/realisticdispersion/config.cpp
index f8274ceba3..30a887550b 100644
--- a/optionals/realisticdispersion/config.cpp
+++ b/optionals/realisticdispersion/config.cpp
@@ -11,6 +11,8 @@ class CfgPatches {
authors[] = {"Ruthberg"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE Realistic Dispersion";
+ ACE_expectedSteamID = "2202414018";
};
};
diff --git a/optionals/tracers/config.cpp b/optionals/tracers/config.cpp
index 79e7f3364d..bace23c390 100644
--- a/optionals/tracers/config.cpp
+++ b/optionals/tracers/config.cpp
@@ -11,6 +11,8 @@ class CfgPatches {
authors[] = {"ACE2 Team"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
+ ACE_expectedModDir = "@ACE Tracers";
+ ACE_expectedSteamID = "2202414450";
};
};