Jump to content
Defunkt

EDEN All-In-One Config Dumps

Recommended Posts

I generated some all-in-one dumps of the config tree for the new Eden update.

 

NeoArmageddon, who provided a workaround for a recent breakage in the script to generate these via his MapBuilder FileIO extension (Thanks!), suggested I should post them up;

 

http://ionwerks.net/arma/arma3-eden-allinoneconfigs.7z

 

There are four dumps;

 

Vanilla Only: arma3-156.134627.aio.cpp

w. CUP Terrains: arma3-156.134627_cup-1.0.1.aio.cpp

w. RHS Escalation: arma3-156.134627_rhs-0.4.0.1.aio.cpp

w. CUP & RHS: arma3-156.134627_cup-1.0.1_rhs-0.4.0.1.aio.cpp

  • Like 3

Share this post


Link to post
Share on other sites

Very nice. Can finally update my outdated allInOne config. Espwcially the CUP TP dump will come in handy when fixing bugs.

Share this post


Link to post
Share on other sites

This is fantastic!!  Please keep them coming (with both CUP and RHS).

Share this post


Link to post
Share on other sites

What are these for?  What can you do with them?

These are an essential and helpful tool for addon and mod makers making addons using content derived from these sources.

Share this post


Link to post
Share on other sites

any chance you can post the updated script?

Actually it turns out (after chatting to kju) that the breakage I encountered was a bug in the initial EDEN release which has subsequently been fixed so there's no need for the amendment (though I haven't actually confirmed this for myself yet).

 

Original script by Denis Usenko (found on OFPEC IIRC) below (sorry I can't seem to find a spoiler tag);

//
// dumpConfig.sqf
// Copyright (c) 2010 Denis Usenko, DenVdmj@gmail.com
// MIT-style license
//

/*
======================================================================================

Dump config to the clipboard:

    [config HNDL, bool IncludeInheritedPropertiesFlag] call compile preprocessFileLineNumbers "dumpConfig.sqf"

This example put section CfgVehicles on the clipboard:

    [configFile >> "CfgVehicles"] call compile preprocessFileLineNumbers "dumpConfig.sqf"

This example will put on the clipboard class "RscDisplayArcadeUnit", all classes will contain all heritable properties, so you get a full and self-sufficient class, independent from the other classes.

    [configFile >> "RscDisplayArcadeUnit", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

More examples:

    [configFile >> "RscTitle", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"
    [configFile >> "RscEdit", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"
    [configFile >> "RscToolbox", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

Warning: don't attempt to get a large classes with switched on parameter "IncludeInheritedPropertiesFlag", eg don't do so:

    [configFile, true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

Dump the entire config, it can take over ten seconds:

    [configFile] call compile preprocessFileLineNumbers "dumpConfig.sqf"
	
======================================================================================
*/

//
// #include "\rls\common";
//

#define arg(x)          (_this select (x))
#define argIf(x)        if(count _this > (x))
#define argIfType(x,t)  if(argIf(x)then{typeName arg(x) == (t)}else{false})
#define argSafe(x)      argIf(x)then{arg(x)}
#define argSafeType(x,t)  argIfType(x,t)then{arg(x)}
#define argOr(x,v)      (argSafe(x)else{v})
#define push(a,v)       (a)set[count(a),(v)]
#define pushTo(a)       call{(a)set[count(a),_this]}
#define log2(number)    ((log number)/.3010299956639812)

private [
    "_joinString",
    "_escapeString",
    "_collectInheritedProperties",
    "_dumpConfigTree"
];

_joinString = {
    //
    // Fast string concatenation,
    //
    private ["_list", "_char", "_size", "_subsize", "_oversize", "_j"];

    _list = arg(0);
    _char = arg(1);

    if( count _list < 1 ) exitwith {""};

    // while { count _list > 1 } do {
    for "" from 1 to ceil(log2(count _list)) do {
        _size = count _list / 2;
        _subsize = floor _size;
        _oversize = ceil _size;
        _j = 0;
        for "_i" from 0 to _subsize - 1 do {
            _list set [_i, (_list select _j) + _char + (_list select (_j+1))];
            _j = _j + 2;
        };
        if( _subsize != _oversize ) then { // to add a tail
            _list set [_j/2, _list select _j];
        };
        _list resize _oversize;
    };

    _list select 0;
};

_escapeString = {
    private ["_source", "_target", "_start", "_charCode"];
    _source = toArray _this;
    _start = _source find 34;
    if(_start > 0) then {
        _target = +_source;
        _target resize _start;
        for "_i" from _start to count _source - 1 do {
            _charCode = _source select _i;
            push(_target, _charCode);
            if(_charCode == 34) then {
                push(_target, _charCode);
            };
        };
        str toString _target;
    } else {
        str _this;
    };
};

_collectInheritedProperties = {
    private [
        "_config",
        "_className",
        "_propertyNameList",
        "_propertyNameLCList",
        "_propertyName",
        "_propertyNameLC"
    ];
    _config = _this;
    _propertyNameList = [];
    _propertyNameLCList = [];
    while {
        _className = configName _config;
        for "_i" from 0 to count _config - 1 do {
            _propertyName = _config select _i;
            _propertyNameLC = toLower configName _propertyName;
            if!(_propertyNameLC in _propertyNameLCList) then {
                push(_propertyNameList, _propertyName);
                push(_propertyNameLCList, _propertyNameLC);
            };
        };
        _className != "";
    } do {
        _config = inheritsFrom _config;
    };
    _propertyNameList;
};

_dumpConfigTree = {
    private [
        "_includeInheritedProperties", "_specifyParentClass",
        "_result", "_indents", "_depth",
        "_pushLine", "_traverse", "_traverseArray"
    ];
    _includeInheritedProperties = argOr(1, false);
    _specifyParentClass = argOr(2, !_includeInheritedProperties);

    _result = [];
    _indents = [""];
    _depth = 0;
    _pushLine = {
        if(_depth >= count _indents) then {
            _indents set [_depth, (_indents select _depth-1) + "    "];
        };
        push(_result, (_indents select _depth) + _this);
    };

    _traverse = {
        private "_confName";
        _confName = configName _this;
        if( isText _this ) exitwith {
            _confName + " = " + (getText _this call _escapeString) + ";" call _pushLine;
        };
        if( isNumber _this ) exitwith {
            _confName + " = " + str getNumber _this + ";" call _pushLine;
        };
        if( isArray _this ) exitwith {
            _confName + "[] = " + (getArray _this call _traverseArray) + ";" call _pushLine;
        };
        if( isClass _this ) exitwith {
            "class " + _confName + (
                configName inheritsFrom _this call {
                    if( _this == "" || !_specifyParentClass ) then { "" } else { " : " + _this }
                }
            ) + " {" call _pushLine;
            if( _includeInheritedProperties ) then {
                _this = _this call _collectInheritedProperties;
            };
            _depth = _depth + 1;
            for "_i" from 0 to count _this - 1 do {
                _this select _i call _traverse
            };
            _depth = _depth - 1;
            "};" call _pushLine;
        };
    };

    _traverseArray = {
        if(typeName _this == "array") exitwith {
            private "_array";
            _array = [];
            for "_i" from 0 to count _this - 1 do {
                push(_array, _this select _i call _traverseArray);
            };
            "{" + ([_array, ", "] call _joinString) + "}";
        };
        if(typeName _this == "string") exitwith {
            _this call _escapeString;
        };
        str _this;
    };

    arg(0) call _traverse;

    [_result, toString [0x0D,0x0A]] call _joinString;
};

private ["_res", "_startTime", "_endTime"];
_startTime = diag_tickTime;
_res = _this call _dumpConfigTree;
_endTime = diag_tickTime;
copyToClipboard _res;
hint format["Ready\nNow get config from clipboard\ntime: %1", _endTime - _startTime];
_res;

Share this post


Link to post
Share on other sites

one issue i'm getting with that script is the max array size can be reached in larger modsets when doing a full config dump

Share this post


Link to post
Share on other sites

Oh right, well try the amendment, rather than copying it all to the clipboard it writes to file as it goes via Neo's mapbuilder File IO extension;

//
// dumpConfig.sqf
// Copyright (c) 2010 Denis Usenko, DenVdmj@gmail.com
// MIT-style license
//

// Modified to write using MapBuilder MBFile_IO extension.

/*
======================================================================================

Dump config to the clipboard:

    [config HNDL, bool IncludeInheritedPropertiesFlag] call compile preprocessFileLineNumbers "dumpConfig.sqf"

This example put section CfgVehicles on the clipboard:

    [configFile >> "CfgVehicles"] call compile preprocessFileLineNumbers "dumpConfig.sqf"

This example will put on the clipboard class "RscDisplayArcadeUnit", all classes will contain all heritable properties, so you get a full and self-sufficient class, independent from the other classes.

    [configFile >> "RscDisplayArcadeUnit", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

More examples:

    [configFile >> "RscTitle", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"
    [configFile >> "RscEdit", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"
    [configFile >> "RscToolbox", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

Warning: don't attempt to get a large classes with switched on parameter "IncludeInheritedPropertiesFlag", eg don't do so:

    [configFile, true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

Dump the entire config, it can take over ten seconds:

    [configFile] call compile preprocessFileLineNumbers "dumpConfig.sqf"
	
======================================================================================
*/

#define arg(x)          (_this select (x))
#define argIf(x)        if(count _this > (x))
#define argIfType(x,t)  if(argIf(x)then{typeName arg(x) == (t)}else{false})
#define argSafe(x)      argIf(x)then{arg(x)}
#define argSafeType(x,t)  argIfType(x,t)then{arg(x)}
#define argOr(x,v)      (argSafe(x)else{v})
#define push(a,v)       (a)set[count(a),(v)]
#define pushTo(a)       call{(a)set[count(a),_this]}
#define log2(number)    ((log number)/.3010299956639812)

private ["_joinString", "_escapeString", "_collectInheritedProperties", "_dumpConfigTree"];

_joinString = { // Fast string concatenation.

    private ["_list", "_char", "_size", "_subsize", "_oversize", "_j"];

    _list = arg(0);
    _char = arg(1);

    if( count _list < 1 ) exitwith {""};

    for "" from 1 to ceil(log2(count _list)) do {
        _size = count _list / 2;
        _subsize = floor _size;
        _oversize = ceil _size;
        _j = 0;
        for "_i" from 0 to _subsize - 1 do {
            _list set [_i, (_list select _j) + _char + (_list select (_j+1))];
            _j = _j + 2;
        };
        if( _subsize != _oversize ) then { // Add a tail.
            _list set [_j/2, _list select _j];
        };
        _list resize _oversize;
    };

    _list select 0;
	
};

_escapeString = {

    private ["_source", "_target", "_start", "_charCode"];
	
    _source = toArray _this;
    _start = _source find 34;
	
    if(_start > 0) then {
        _target = +_source;
        _target resize _start;
        for "_i" from _start to count _source - 1 do {
            _charCode = _source select _i;
            push(_target, _charCode);
            if(_charCode == 34) then {
                push(_target, _charCode);
            };
        };
        str toString _target;
    } else {
        str _this;
    };
	
};

_collectInheritedProperties = {

    private ["_config", "_className", "_propertyNameList", "_propertyNameLCList", "_propertyName", "_propertyNameLC"];
	
    _config = _this;
    _propertyNameList = [];
    _propertyNameLCList = [];
	
    while {
        _className = configName _config;
        for "_i" from 0 to count _config - 1 do {
            _propertyName = _config select _i;
            _propertyNameLC = toLower configName _propertyName;
            if!(_propertyNameLC in _propertyNameLCList) then {
                push(_propertyNameList, _propertyName);
                push(_propertyNameLCList, _propertyNameLC);
            };
        };
        _className != "";
    } do {
        _config = inheritsFrom _config;
    };
	
    _propertyNameList;
	
};

_dumpConfigTree = {

    private ["_includeInheritedProperties", "_specifyParentClass", "_result", "_indents", "_depth", "_pushLine", "_traverse", "_traverseArray"];
	
	"mb_fileio" CallExtension "open_w|config_dump.txt";

    _includeInheritedProperties = argOr(1, false);
    _specifyParentClass = argOr(2, !_includeInheritedProperties);
    _result = [];
    _indents = [""];
    _depth = -1;
	
    _pushLine = {
		if (_depth < 0) then {
			"mb_fileio" CallExtension Format["write|/* %1 %2.%3 */", ProductVersion select 0, ProductVersion select 2, ProductVersion select 3];
		} else {
			if(_depth >= count _indents) then {
				_indents set [_depth, (_indents select _depth-1) + "    "];
			};
			"mb_fileio" CallExtension Format["write|%1%2", _indents select _depth, _this];
		};
    };

    _traverse = {
        private "_confName";
        _confName = configName _this;
        if( isText _this ) exitwith {
            _confName + " = " + (getText _this call _escapeString) + ";" call _pushLine;
        };
        if( isNumber _this ) exitwith {
            _confName + " = " + str getNumber _this + ";" call _pushLine;
        };
        if( isArray _this ) exitwith {
            _confName + "[] = " + (getArray _this call _traverseArray) + ";" call _pushLine;
        };
        if( isClass _this ) exitwith {
            "class " + _confName + (
                configName inheritsFrom _this call {
                    if( _this == "" || !_specifyParentClass ) then { "" } else { " : " + _this }
                }
            ) + " {" call _pushLine;
            if( _includeInheritedProperties ) then {
                _this = _this call _collectInheritedProperties;
            };
            _depth = _depth + 1;
            for "_i" from 0 to count _this - 1 do {
                _this select _i call _traverse
            };
            _depth = _depth - 1;
            "};" call _pushLine;
        };
    };

    _traverseArray = {
        if(typeName _this == "array") exitwith {
            private "_array";
            _array = [];
            for "_i" from 0 to count _this - 1 do {
                push(_array, _this select _i call _traverseArray);
            };
            "{" + ([_array, ", "] call _joinString) + "}";
        };
        if(typeName _this == "string") exitwith {
            _this call _escapeString;
        };
        str _this;
    };

    arg(0) call _traverse;

	"mb_fileio" CallExtension "close";
	
};

_this call _dumpConfigTree;

Share this post


Link to post
Share on other sites

These are an essential and helpful tool for addon and mod makers making addons using content derived from these sources.

I have no idea what you mean here.  I'm making a mod and have no clue what they are, so they cannot be essential.  "Vanilla Only" is the one that interests me.  Can using it improve my mod somehow; what is it?

Share this post


Link to post
Share on other sites

I have no idea what you mean here.  I'm making a mod and have no clue what they are, so they cannot be essential.  "Vanilla Only" is the one that interests me.  Can using it improve my mod somehow; what is it?

 

When you want to know how something works in ArmA3, you open the AllInOne config with your favorite texteditor, hit CTRL+F and search for the class you want to examine.

That basically saves you from hours and hours of trial and error and/or unpacking all ArmA3 pbos and checking every config.cpp one by one.

Share this post


Link to post
Share on other sites

When you want to know how something works in ArmA3, you open the AllInOne config with your favorite texteditor, hit CTRL+F and search for the class you want to examine.

That basically saves you from hours and hours of trial and error and/or unpacking all ArmA3 pbos and checking every config.cpp one by one.

Thank you.  I can see how that will save a lot of effort.

Share this post


Link to post
Share on other sites

Thank you.  I can see how that will save a lot of effort.

 

The configs are class definitions that define the information that the game engine needs to know in order to handle instantiating each object in the game world.  They define which 3D model(s) and sound file(s) an object uses, what speeds vehicles can travel at, how quickly they consume fuel, the max weight a helicopter can slingload, what weapons they carry, what magazines a given weapon accepts, etc., etc. 

 

By examining these class properties you can mine information out of the game.  I have zero idea how to make a mod, but I use configs extensively as a type of database to fill in the giant lack of documentation that exists about most game objects.  Bohemia has this page (https://community.bistudio.com/wiki/Arma_3_CfgVehicles_WEST) to tell you a few things about BLUFOR units (like class name, side, faction, and the weapons, magazines, and items that it contains), but if you wanted to know more about the basic Rifleman (B_Soldier_F), you could find it in the config viewer (or in a website dump, like here: https://configs.arma3.ru/155.133137/configfile/CfgVehicles/B_Soldier_F.html), or in the files above, to find out things like "attendant = 0; engineer = 0; uavHacker = 0;" to know that Rifleman can't fully heal other units, repair vehicles, or control UAVs.  So for instance, you can use config data to generate a database that tells you how many seats each vehicles in the game has (how many total, how many crew spots, how many passenger spots, and of the passenger spots, how many support firing from vehicles).  To learn how that's done, see my post here: https://forums.bistudio.com/topic/189522-how-to-find-vehicle-cargopassengerffv-seat-capacity/?p=3002357

 

Arma has a built in Config Viewer (more about that here: http://arma3scriptingtutorials.blogspot.com/2014/02/config-viewer-what-is-it-and-how-to-use.html and here: https://youtu.be/lM7IHPun3eE), but it's not searchable and isn't the greatest tool.  So what these config dumps here are are text files containing the same information, but since it's a text file you can open it in something like Notepad++ and search it far, far more easily to get at the data you want.

  • Like 3

Share this post


Link to post
Share on other sites

Good stuff. I needed this badly. 

 

Can we get Armaholic or similar sites to mirror these under tools or misc? Thanks.

 

PS: Thanks for the script too.

 

PPS: +1 to sticky this

 

Edit: Looks like someone updated these on DH its available there in the repo.

Share this post


Link to post
Share on other sites

Would you mind posting an updated dump with the new CUP versions?  They released a fairly large update recently.

Share this post


Link to post
Share on other sites

The only CUP package that was in the configs I posted was Terrains which hasn't been updated AFAIK. I don't actually have the others. Everything you need to create your own config dumps is here.

 

I'm told the first version of the script (above) should work now but it still doesn't for me. If you want to try yourself, save it to your Arma root as dumpConfig.sqf and launch with -filePatching then in the console enter;

[configFile] call compile preprocessFileLineNumbers "dumpConfig.sqf"

...after a few seconds your clipboard should contain the dump. Since EDEN I always get an error message about array size being exceeded.

 

Second version relies on the FileIO extension contained in MapBuilder (see Neo's sig) to write the output to file. Launch with -filePatching and MapBuilder loaded (or a mod folder containing just the mb_fileio.dll) and execute the same way. The dump should appear in a file called config_dump.txt - either in the Arma root or the DLL mod folder (sorry, I don't recall which).

Share this post


Link to post
Share on other sites

Okay, thanks.  Yeah, I think I misread CUP Terrains as being CUP in general.  I'll give it a try and if I can get it to work I'll post a link here.

Share this post


Link to post
Share on other sites

Anyone interested 1.58 dump here.

 

Used Map Builder dll only in A3 root and the rest as per instructions. Works OK.

 

PS: Someone verify if its complete?

Share this post


Link to post
Share on other sites

Did the same with the following mods (game version 1.58.135656):

  • RHS USF (v 0.4.0.1)
  • RHS AFRF (v 0.4.0.1)
  • CBA_A3 (v 2.3.1)
  • CUP Units (v 1.3.1)
  • CUP Weapons (v 1.6)
  • CUP Vehicles (v 1.3)
  • CUP Terrains Core (v 1.0.1)
  • CUP Terrains Maps (v 1.0.1)

Link to file here (52 MB).

  • Like 1

Share this post


Link to post
Share on other sites

I've noticed that the script has been broken by a recent update.

 

Line 72 -

         for "" from 1 to ceil(log2(count _list)) do {
        _size = count _list / 2;
        _subsize = floor _size;
        _oversize = ceil _size;

 

The error is - reserved variable in expression. Anyone know what the problem is?

Share this post


Link to post
Share on other sites

See the linked post below for instructions on using a fixed/currently working version of this script:

 

 

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×