kazesim 2 Posted December 18, 2013 Extracts a whole config class to the Windows clipboard. It includes every entry in that class plus every subclass (and sub-sub-etc-class) all the way back to the root. The entries are left in the same order that they are in the config, with ones from parent classes added later, so that the most derived entries are at the top. The output is formatted as standard ArmA cpp (instead of bin or sqf), so you should hopefully be able to just paste it in a config file without problems. This is for people like me who hate using unPBO/unBin/Eliteness just to get a few config values. Instead you can just run this from in-game, paste the whole thing into Notepad++ or whatever and take out what you don't need. Due to it's complexity, it typically takes a few seconds to run, just wait until it says it's done. Don't use it on the huge Cfg- base classes as it will never finish. I recommend making a "Scripts" folder in your ArmA root (same folder as the game's main exe) and putting it there. Then it can be called from anywhere in the game with "Scripts\NAME.sqf". /*-------------------------------------------------------------------------------------------- Extracts a whole config class to the Windows clipboard It includes every entry in that class plus every subclass (and sub-sub-etc-class) all the way back to the root The entries are left in the same order that they are in the config, with ones from parent classes added later, so that the most derived entries are at the top The output is formatted as standard ArmA cpp (instead of bin or sqf), so you should hopefully be able to just paste it in a config file without problems Don't use this script on huge root classes like CfgVehicles / CfgWeapons, it will never finish The parameter can be either the config class to extract, or an array: 0: Config (Class to extract) 1: Bool (Add comments indicating which parent class the entries came from, default false) 2: Bool (Include parent class names in the class definitions, default true) Examples: (configFile/'CfgWeapons'/'M16A2') execVM "Scripts\cfgGet.sqf"; [configFile/'CfgVehicles'/'HMMWV', true] execVM "Scripts\cfgGet.sqf"; [configFile/'CfgVehicles'/'HMMWV', true, false] execVM "Scripts\cfgGet.sqf"; This should work on any ArmA, tested on 2 and 3 v1.0 By Kazesim --------------------------------------------------------------------------------------------*/ #define DQUOTE 34 #define INC(X) X = X + 1 #define ADD(X,Y) _list set [count _list, [X, Y]] _addClassLabels = false; _addParentClassDefs = true; if ((typeName _this) == "ARRAY") then { _count = count _this; if (_count > 1) then {_addClassLabels = _this select 1}; if (_count > 2) then {_addParentClassDefs = _this select 2}; _this = _this select 0; }; if not (isClass _this) exitWith {hint "Invalid class"; copyToClipboard "Invalid class"}; _offset = 0; _tab = ""; _CRLF = toString [0x0D, 0x0A]; __TAB = toString [0x09]; _getTab = { //Update the string containing the current number of tabs private ["_c", "_t"]; _offset = _offset + _this; _t = ""; for "_c" from 1 to _offset do { _t = _t + __TAB; }; _tab = _t; }; _insert = { //Format: [array, item to insert, index] private ["_array", "_index", "_count", "_save", "_last", "_c"]; _array = _this select 0; _index = _this select 2; _count = count _array; _save = ""; _last = _this select 1; for "_c" from _index to (_count - 1) do { _save = _array select _c; _array set [_c, _last]; _last = _save; }; _array set [_count, _last]; }; _formatString = { //Re-double-quotes any quotes inside a string private ["_c", "_x", "_count"]; _this = toArray _this; _count = count _this; for [{_c = 0}, {_c < _count}, {INC(_c)}] do { _x = _this select _c; if (_x == DQUOTE) then { [_this, DQUOTE, _c+1] call _insert; INC(_c); INC(_count); }; }; str toString _this; }; _formatArray = { //Switch all the brackets to braces, and add spaces after commas private ["_str", "_last"]; _last = (count _this) - 1; _str = "{"; { _str = _str + (switch (typeName _x) do { case "ARRAY": {_x call _formatArray}; case "TEXT": {_x call _formatString}; case default {str _x}; }); if (_forEachIndex != _last) then {_str = _str + ", "}; } forEach _this; _str + "}"; }; _scanEntries = { private ["_cfg", "_c", "_entry", "_name", "_added", "_str", "_list"]; _cfg = _this select 0; _list = _this select 1; _addLabel = _this select 2; for "_c" from 0 to ((count _cfg) - 1) do { _entry = _cfg select _c; _name = configName _entry; _added = false; {if ((_x select 0) == _name) exitWith {_added = true}} forEach _list; if (!_added) then { //Add the class label comment, if enabled if (_addClassLabels and _addLabel) then { _str = format ["%1// %2%3", _tab, configName _cfg, _CRLF]; ADD("", _str); _addLabel = false; }; //Add the entry _str = ""; if (isClass _entry) then { _str = _entry call _scanCfg; } else { _str = format ["%1%2%3 = %4;%5", _tab, _name, if (isArray _entry) then {"[]"} else {""}, switch (true) do { case (isNumber _entry): {getNumber _entry}; case (isText _entry): {(getText _entry) call _formatString}; case (isArray _entry): {(getArray _entry) call _formatArray}; }, _CRLF ]; }; ADD(_name, _str); }; }; }; _scanCfg = { private ["_list", "_tab", "_cfg", "_name", "_count", "_inherit", "_str", "_empty"]; _list = []; 0 call _getTab; //Add the class name, parent class name, and starting brace _cfg = _this; _name = configName _cfg; _count = count _cfg; _inherit = configName inheritsFrom _cfg; _empty = _count == 0 and _inherit == ""; _str = format ["%1class %2%3 {%4", _tab, _name, if (_inherit == "" or !_addParentClassDefs) then { ""; } else { ": " + _inherit; }, if (_empty) then {""} else {_CRLF} ]; ADD(_name, _str); 1 call _getTab; //Get all the entries from this class and every parent class if (_count > 0) then {[_cfg, _list, false] call _scanEntries}; while {true} do { _inherit = inheritsFrom _cfg; _inheritName = configName _inherit; if (_inheritName == "") exitWith {}; //Last class _cfg = _inherit; [_cfg, _list, _name != _inheritName] call _scanEntries; }; //Add the ending brace -1 call _getTab; _str = format ["%1};%2", if (_empty) then {""} else {_tab}, _CRLF]; ADD("", _str); //Concat the string and return it _str = ""; {_str = _str + (_x select 1)} forEach _list; _str; }; hint "Running..."; copyToClipboard (_this call _scanCfg); hint "Done"; 2 Share this post Link to post Share on other sites
UNN 0 Posted February 9, 2014 (edited) Thanks Kazesim, Some very useful functionality there. I wondered if you would consider an addition? I wrote a similar script to extract the entire Arma1 config as one file for general browsing, searching and tracing the inheritance. As you did a better job of formatting and exporting the config, I wondered if you would be willing to add that feature to your script? For what I want it for my script works fine, but I'm sure it would be helpful for others. I've attached the output from my version below. I format mine in a slightly different way from you, but this isn't an issue as it's easy to modify your script to suit each persons preference. allConfig.txt If you can't no worries, it's still worth posting the file here, for anyone else who might find it useful. Edit: I'm not sure how that stupid emoticon ended up in the title, please ignore it. Edited February 9, 2014 by UNN Share this post Link to post Share on other sites
kazesim 2 Posted March 10, 2014 Sorry I always forget to check for replies. I wasn't able to download that file, I'm pretty sure that site is worse than FilePlanet, which I didn't think was possible. If you can put it on Dropbox or something, or just paste it here I'll look at it. And do you mean extracting the whole entire game config? You could theoretically do that with this script by just extracting the Cfg- classes. I'm afraid to actually try that though because it would take forever and probably either run out of memory or reach some kind of recursion limit. I haven't actually tested it on ArmA 1 since my copy of that game is broken thanks to FADE thinking that I have a pirate copy, but I'd assume it would work. For just perusing the config I think it's easiest to just use the in-game browser. But yeah if you have managed to find a way to extract the whole thing then I'd like to see. Share this post Link to post Share on other sites