Add store mod source contains matching

This commit is contained in:
Jacob Schmidt 2026-06-03 23:23:03 -05:00
parent 69acbaef4c
commit 6282080cb4
3 changed files with 35 additions and 7 deletions

View File

@ -42,6 +42,7 @@ class CfgStore {
patches[] = {"rhs_main", "rhsusf_main"}; patches[] = {"rhs_main", "rhsusf_main"};
addons[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; addons[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"};
prefixes[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; prefixes[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"};
contains[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"};
dlcs[] = {}; dlcs[] = {};
}; };
@ -49,6 +50,7 @@ class CfgStore {
patches[] = {"ace_main"}; patches[] = {"ace_main"};
addons[] = {"ace_"}; addons[] = {"ace_"};
prefixes[] = {"ace_"}; prefixes[] = {"ace_"};
contains[] = {"ace_"};
dlcs[] = {}; dlcs[] = {};
}; };
}; };
@ -79,9 +81,10 @@ filtering. `allowlist` only keeps generated entries that match one of the
configured `mods[]`; `denylist` removes matching entries. Each `ModSources` configured `mods[]`; `denylist` removes matching entries. Each `ModSources`
child can define `patches[]` to detect whether the mod is loaded, `addons[]` child can define `patches[]` to detect whether the mod is loaded, `addons[]`
for exact config source addon/source mod names, `prefixes[]` for classname, for exact config source addon/source mod names, `prefixes[]` for classname,
source addon, or source mod prefixes, and `dlcs[]` for DLC/source/author labels source addon, or source mod prefixes, `contains[]` for classname/source
used by Creator DLC content. If a mod source defines no patches, it is treated metadata tokens that can appear anywhere, and `dlcs[]` for DLC/source/author
as available and only the source/prefix/DLC checks are used. 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 `units[]` follows the same `dynamic`, `allowlist`, and `denylist` behavior as
item and vehicle categories. Unit purchases are immediate spawn grants, not item and vehicle categories. Unit purchases are immediate spawn grants, not

View File

@ -95,16 +95,18 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [
private _patches = _self call ["getMissionStoreModSourceValues", [_modID, "patches"]]; private _patches = _self call ["getMissionStoreModSourceValues", [_modID, "patches"]];
private _addons = _self call ["getMissionStoreModSourceValues", [_modID, "addons"]]; private _addons = _self call ["getMissionStoreModSourceValues", [_modID, "addons"]];
private _prefixes = _self call ["getMissionStoreModSourceValues", [_modID, "prefixes"]]; private _prefixes = _self call ["getMissionStoreModSourceValues", [_modID, "prefixes"]];
private _contains = _self call ["getMissionStoreModSourceValues", [_modID, "contains"]];
private _dlcs = _self call ["getMissionStoreModSourceValues", [_modID, "dlcs"]]; private _dlcs = _self call ["getMissionStoreModSourceValues", [_modID, "dlcs"]];
private _loaded = _self call ["isMissionStoreModLoaded", [_modID]]; private _loaded = _self call ["isMissionStoreModLoaded", [_modID]];
format [ 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, _modID,
_loaded, _loaded,
_patches, _patches,
_addons, _addons,
_prefixes, _prefixes,
_contains,
_dlcs _dlcs
] ]
} }
@ -122,6 +124,19 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [
_matches _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 { ["doesItemMatchMissionStoreMod", compileFinal {
params [["_item", createHashMap, [createHashMap]], ["_modID", "", [""]]]; params [["_item", createHashMap, [createHashMap]], ["_modID", "", [""]]];
@ -135,6 +150,7 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [
private _sourceAuthor = _item getOrDefault ["sourceAuthor", ""]; private _sourceAuthor = _item getOrDefault ["sourceAuthor", ""];
private _addons = (_self call ["getMissionStoreModSourceValues", [_modID, "addons"]]) apply { toLowerANSI _x }; private _addons = (_self call ["getMissionStoreModSourceValues", [_modID, "addons"]]) apply { toLowerANSI _x };
private _prefixes = (_self call ["getMissionStoreModSourceValues", [_modID, "prefixes"]]) 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 _dlcs = (_self call ["getMissionStoreModSourceValues", [_modID, "dlcs"]]) apply { toLowerANSI _x };
private _matchPrefixes = _addons + _prefixes; private _matchPrefixes = _addons + _prefixes;
private _sourceModLower = toLowerANSI _sourceMod; private _sourceModLower = toLowerANSI _sourceMod;
@ -148,12 +164,17 @@ GVAR(StoreCatalogServiceBaseClass) = compileFinal createHashMapFromArray [
{ {
if (_x in _addons) exitWith { _sourceAddonMatched = true; }; if (_x in _addons) exitWith { _sourceAddonMatched = true; };
if (_self call ["doesValueMatchAnyPrefix", [_x, _matchPrefixes]]) exitWith { _sourceAddonMatched = true; }; if (_self call ["doesValueMatchAnyPrefix", [_x, _matchPrefixes]]) exitWith { _sourceAddonMatched = true; };
if (_self call ["doesValueContainAnyToken", [_x, _contains]]) exitWith { _sourceAddonMatched = true; };
} forEach _sourceAddons; } forEach _sourceAddons;
if (_sourceAddonMatched) exitWith { true }; if (_sourceAddonMatched) exitWith { true };
if (_self call ["doesValueMatchAnyPrefix", [_className, _matchPrefixes]]) 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 ["doesValueMatchAnyPrefix", [_sourceMod, _matchPrefixes]]) exitWith { true };
if (_self call ["doesValueContainAnyToken", [_sourceMod, _contains]]) exitWith { true };
if (_self call ["doesValueMatchAnyPrefix", [_sourceDLC, _dlcs]]) 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 ["doesValueMatchAnyPrefix", [_sourceAuthor, _dlcs]]) exitWith { true };
if (_self call ["doesValueContainAnyToken", [_sourceAuthor, _contains]]) exitWith { true };
false false
}], }],

View File

@ -42,6 +42,7 @@ class CfgStore {
patches[] = {"rhs_main", "rhsusf_main"}; patches[] = {"rhs_main", "rhsusf_main"};
addons[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; addons[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"};
prefixes[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"}; prefixes[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"};
contains[] = {"rhs_", "rhsusf_", "rhsgref_", "rhsafrf_"};
dlcs[] = {}; dlcs[] = {};
}; };
@ -49,6 +50,7 @@ class CfgStore {
patches[] = {"ace_main"}; patches[] = {"ace_main"};
addons[] = {"ace_"}; addons[] = {"ace_"};
prefixes[] = {"ace_"}; prefixes[] = {"ace_"};
contains[] = {"ace_"};
dlcs[] = {}; dlcs[] = {};
}; };
}; };
@ -79,9 +81,10 @@ filtering. `allowlist` only keeps generated entries that match one of the
configured `mods[]`; `denylist` removes matching entries. Each `ModSources` configured `mods[]`; `denylist` removes matching entries. Each `ModSources`
child can define `patches[]` to detect whether the mod is loaded, `addons[]` child can define `patches[]` to detect whether the mod is loaded, `addons[]`
for exact config source addon/source mod names, `prefixes[]` for classname, for exact config source addon/source mod names, `prefixes[]` for classname,
source addon, or source mod prefixes, and `dlcs[]` for DLC/source/author labels source addon, or source mod prefixes, `contains[]` for classname/source
used by Creator DLC content. If a mod source defines no patches, it is treated metadata tokens that can appear anywhere, and `dlcs[]` for DLC/source/author
as available and only the source/prefix/DLC checks are used. 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: For example, to show only RHS-sourced generated inventory:
@ -101,6 +104,7 @@ class rf {
patches[] = {}; patches[] = {};
addons[] = {"lxrf_", "rf_"}; addons[] = {"lxrf_", "rf_"};
prefixes[] = {"lxrf_", "rf_"}; prefixes[] = {"lxrf_", "rf_"};
contains[] = {"lxrf", "_rf_", "_rf", "rf_"};
dlcs[] = {"rf", "reactionforces", "reaction forces"}; dlcs[] = {"rf", "reactionforces", "reaction forces"};
}; };
``` ```