diff --git a/arma/server/addons/store/README.md b/arma/server/addons/store/README.md index 10787a9..03fe25f 100644 --- a/arma/server/addons/store/README.md +++ b/arma/server/addons/store/README.md @@ -42,6 +42,7 @@ class CfgStore { patches[] = {"rhs_main", "rhsusf_main"}; addons[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; prefixes[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; + contains[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; dlcs[] = {}; }; @@ -49,6 +50,7 @@ class CfgStore { patches[] = {"ace_main"}; addons[] = {"ace_"}; prefixes[] = {"ace_"}; + contains[] = {"ace_"}; dlcs[] = {}; }; }; @@ -79,9 +81,10 @@ filtering. `allowlist` only keeps generated entries that match one of the configured `mods[]`; `denylist` removes matching entries. Each `ModSources` child can define `patches[]` to detect whether the mod is loaded, `addons[]` for exact config source addon/source mod names, `prefixes[]` for classname, -source addon, or source mod prefixes, and `dlcs[]` for DLC/source/author labels -used by Creator DLC content. If a mod source defines no patches, it is treated -as available and only the source/prefix/DLC checks are used. +source addon, or source mod prefixes, `contains[]` for classname/source +metadata tokens that can appear anywhere, and `dlcs[]` for DLC/source/author +labels used by Creator DLC content. If a mod source defines no patches, it is +treated as available and only the source/prefix/contains/DLC checks are used. `units[]` follows the same `dynamic`, `allowlist`, and `denylist` behavior as item and vehicle categories. Unit purchases are immediate spawn grants, not diff --git a/arma/server/addons/store/functions/fnc_initCatalogService.sqf b/arma/server/addons/store/functions/fnc_initCatalogService.sqf index 0865b0f..2ae7085 100644 --- a/arma/server/addons/store/functions/fnc_initCatalogService.sqf +++ b/arma/server/addons/store/functions/fnc_initCatalogService.sqf @@ -95,16 +95,18 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [ private _patches = _self call ["getMissionStoreModSourceValues", [_modID, "patches"]]; private _addons = _self call ["getMissionStoreModSourceValues", [_modID, "addons"]]; private _prefixes = _self call ["getMissionStoreModSourceValues", [_modID, "prefixes"]]; + private _contains = _self call ["getMissionStoreModSourceValues", [_modID, "contains"]]; private _dlcs = _self call ["getMissionStoreModSourceValues", [_modID, "dlcs"]]; private _loaded = _self call ["isMissionStoreModLoaded", [_modID]]; format [ - "%1 loaded=%2 patches=%3 addons=%4 prefixes=%5 dlcs=%6", + "%1 loaded=%2 patches=%3 addons=%4 prefixes=%5 contains=%6 dlcs=%7", _modID, _loaded, _patches, _addons, _prefixes, + _contains, _dlcs ] } @@ -122,6 +124,19 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [ _matches }], + ["doesValueContainAnyToken", compileFinal { + params [["_value", "", [""]], ["_tokens", [], [[]]]]; + + private _normalizedValue = toLowerANSI _value; + private _matches = false; + { + private _token = toLowerANSI _x; + if (_token isEqualTo "") then { continue; }; + if ((_normalizedValue find _token) >= 0) exitWith { _matches = true; }; + } forEach _tokens; + + _matches + }], ["doesItemMatchMissionStoreMod", compileFinal { params [["_item", createHashMap, [createHashMap]], ["_modID", "", [""]]]; @@ -135,6 +150,7 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [ private _sourceAuthor = _item getOrDefault ["sourceAuthor", ""]; private _addons = (_self call ["getMissionStoreModSourceValues", [_modID, "addons"]]) apply { toLowerANSI _x }; private _prefixes = (_self call ["getMissionStoreModSourceValues", [_modID, "prefixes"]]) apply { toLowerANSI _x }; + private _contains = (_self call ["getMissionStoreModSourceValues", [_modID, "contains"]]) apply { toLowerANSI _x }; private _dlcs = (_self call ["getMissionStoreModSourceValues", [_modID, "dlcs"]]) apply { toLowerANSI _x }; private _matchPrefixes = _addons + _prefixes; private _sourceModLower = toLowerANSI _sourceMod; @@ -148,12 +164,17 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [ { if (_x in _addons) exitWith { _sourceAddonMatched = true; }; if (_self call ["doesValueMatchAnyPrefix", [_x, _matchPrefixes]]) exitWith { _sourceAddonMatched = true; }; + if (_self call ["doesValueContainAnyToken", [_x, _contains]]) exitWith { _sourceAddonMatched = true; }; } forEach _sourceAddons; if (_sourceAddonMatched) exitWith { true }; if (_self call ["doesValueMatchAnyPrefix", [_className, _matchPrefixes]]) exitWith { true }; + if (_self call ["doesValueContainAnyToken", [_className, _contains]]) exitWith { true }; if (_self call ["doesValueMatchAnyPrefix", [_sourceMod, _matchPrefixes]]) exitWith { true }; + if (_self call ["doesValueContainAnyToken", [_sourceMod, _contains]]) exitWith { true }; if (_self call ["doesValueMatchAnyPrefix", [_sourceDLC, _dlcs]]) exitWith { true }; + if (_self call ["doesValueContainAnyToken", [_sourceDLC, _contains]]) exitWith { true }; if (_self call ["doesValueMatchAnyPrefix", [_sourceAuthor, _dlcs]]) exitWith { true }; + if (_self call ["doesValueContainAnyToken", [_sourceAuthor, _contains]]) exitWith { true }; false }], diff --git a/docs/STORE_USAGE_GUIDE.md b/docs/STORE_USAGE_GUIDE.md index 338a1a5..a309a2c 100644 --- a/docs/STORE_USAGE_GUIDE.md +++ b/docs/STORE_USAGE_GUIDE.md @@ -42,6 +42,7 @@ class CfgStore { patches[] = {"rhs_main", "rhsusf_main"}; addons[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; prefixes[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; + contains[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; dlcs[] = {}; }; @@ -49,6 +50,7 @@ class CfgStore { patches[] = {"ace_main"}; addons[] = {"ace_"}; prefixes[] = {"ace_"}; + contains[] = {"ace_"}; dlcs[] = {}; }; }; @@ -79,9 +81,10 @@ filtering. `allowlist` only keeps generated entries that match one of the configured `mods[]`; `denylist` removes matching entries. Each `ModSources` child can define `patches[]` to detect whether the mod is loaded, `addons[]` for exact config source addon/source mod names, `prefixes[]` for classname, -source addon, or source mod prefixes, and `dlcs[]` for DLC/source/author labels -used by Creator DLC content. If a mod source defines no patches, it is treated -as available and only the source/prefix/DLC checks are used. +source addon, or source mod prefixes, `contains[]` for classname/source +metadata tokens that can appear anywhere, and `dlcs[]` for DLC/source/author +labels used by Creator DLC content. If a mod source defines no patches, it is +treated as available and only the source/prefix/contains/DLC checks are used. For example, to show only RHS-sourced generated inventory: @@ -101,6 +104,7 @@ class rf { patches[] = {}; addons[] = {"lxrf_", "rf_"}; prefixes[] = {"lxrf_", "rf_"}; + contains[] = {"lxrf", "_rf_", "_rf", "rf_"}; dlcs[] = {"rf", "reactionforces", "reaction forces"}; }; ```