This is a system for generating data dumps from Borderlands 2, The Pre-Sequel, and the standalone Assault on Dragon Keep, for the purposes of generating Object Explorer data for use in OpenBLCMM and FT Explorer. It was also used as the basis for data in the original BLCMM, starting with v1.2.0, though the extracts here required extra processing to be fully compatible with the original BLCMM.
The main data collection component of this project is a
PythonSDK mod which allows the
user to cycle through the various steps in the process in an interactive
way. It also uses a few external Python scripts
to massage the resulting Launch.log
files into more useful formats and
finish up the data collection.
- Caveats/Warnings
- Overview
- A Note About Missing Objects
- Getting The Game Ready For Dumps
- Getting Characters/Vehicles Ready For Dumps
- The Process
- Filtering/Scrubbing Sensitive Data
- What's Happening Behind-The-Scenes
- FT/BLCMM Explorer Integration
- Other Scripts
- License
-
The PythonSDK mod component of this project relies on using the
say
command to give feedback to the user as you interact with it. Ever since BL2/TPS was updated with crossplatform multiplayer, thesay
command will crash the game if you're playing in offline mode. So, dumping data using this method currently relies on having the game online. -
This whole process assumes at least a working knowledge of dealing with Python from the commandline (shell if on Linux,
cmd.exe
or Powershell if on Windows), and installing/running (and potentially tweaking) PythonSDK mods. The process necessarily requires quite a bit of handholding, and some scripts will require at least minor edits to work properly in your environment. You're likely to end up needing to debug errors if they pop up, etc. If you're interested in getting a "release-quality" set of dumps generated, you'll also need to be motivated enough to dig into data comparisons and debug issues when some objects don't get dumped, etc. -
This process has, to my knowledge, only ever been tested/run on Linux. There's one step in particular which, in its current state, might only work on Linux, due to some open-filehandle limits on Windows. If you're running this on Windows,
categorize_data.py
might need to be adapted for use on your OS, and other scripts may end up needing some tweaking too. PRs are welcome, for cross-platform support!
There are various challenges inherent with dumping data from Borderlands games. There are a bunch of "transient" objects which might exist in every level but have wildly differing content. There's a lot of dynamically-named objects whose numerical suffixes can change from level to level, or between game sessions. There's various data that's only available when specific characters are loaded, or specific vehicles. Ideally, you want to know what objects are specific to an individual level, because you don't want to have to dump all objects for every level, lest you end up having to sift through hundreds of gigs of spurious dumps, when you're done.
This mod, and its associated scripts, aims to try and iron out as much of that as possible. The mod has various modes which you'll cycle through and kick off at various points, depending on where you are in the process. The app will output the currently-available keybinds via in-game chat whenever you interact with it, and will pop up the initial message as soon as you activate the mod via the "Mods" menu.
Interacting with the mod is done via some keybinds, though note that the keys are only available when you're actually in the game, not from the main menu. So be sure to "continue" with the chosen character before trying to play with it. The keybinds were chosen based on what keys Apocalyptech had unused at the time. At the moment, to change them, you'll have to update the mod sourcecode:
Function | Keybind |
---|---|
Next Mode | N |
Previous Mode | P |
Activate/Run Mode | B |
Cancel Current Run | O |
The general procedure, glossing over every detail imaginable, is:
- Do one pass of
getall
s in all levels, with all chars + vehicles, to figure out what objects exist. - Do another pass of
getall
s, loading everything in a different order, to try to filter out dynamically-named objects which can't be relied on for modding. - Then with the filtered list of objects, loop through all
levels/chars/vehicles again with
obj dump
, to get the dumps. - Run the final processing scripts to get the data packaged for OpenBLCMM.
There are a set of modes for the getall
steps, and then a separate set
of modes for the obj dump
steps. As mentioned above, you can cycle
through them with N
and P
. Just pay attention to the names of the
modes, so you know whether you've got a Getall
or Dump
mode active!
Inbetween each step there's one or more Python scripts to be run from the commandline to massage the data and do sanity checks, etc. Once you've got the dumps in hand, there's some more commands to work the data into an export format for OpenBLCMM, and to compare the extracted dataset against previous extractions, etc.
Throughout the course of working with this app, I have yet to discover a method which ends up dumping a "100% complete" set of data on its own. Each method I've tried seems to omit at least an object or two. The methods currently active in the mod tend to give the results that I'm happiest with, but there seems to be no getting around having to do some manual cleanup after the fact. The objects which are missing seem to change as time goes on, in fact -- after having gone through several iterations of data dumping, I seem to have a different set each time.
So, to help figure out what might be missing, there are a couple of utilities which can be used to investigate the discrepancies. Those are listed as part of the procedure, below.
It's possibly worth noting that even in the worst cases, the vast majority of objects do get dumped. There's generally only a handful of objects which need manual handling, out of a total of over a million (for BL2).
Apart from simply having PythonSDK installed and working,
the only other thing you'll probably want to do is apply the "array limit"
hexedit. Ordinarily, when the game does an obj dump
on an object with
a top-level array attribute, only the first 100 elements will be printed,
with a message afterwards saying ... N more elements
. That's obviously
not ideal for an object database which aims to be complete, so you'll want
to fix that up.
OpenBLCMM (and BLCMM) has a hex-edit available right in the app to update this for both BL2 and TPS. c0dycode's Hex Multitool should be able to handle it as well. Eventually, PythonSDK will probably take care of doing this transparently, but for now, hexedits are all we've got for it.
Note that we do not currently have a hexedit available for the standalone Assault on Dragon Keep, so dumps for that game will just be limited to 100 elements on top-level arrays.
There are some methods available in PythonSDK to automatically load in character and vehicle data, but it tends to result in different datasets than what's actually seen in-game, so unfortunately the best results are achieved when you manually head to the main menu to switch up chars, and then spawn vehicles in-game via a Catch-A-Ride.
The "modes" in the DataDumper mod are set up with some specific character and vehicle mappings. For instance, you'll use Axton to spawn in Skiffs (from DLC1), and Maya to spawn in Fan Boats (from DLC3), etc. You're free to deviate from the pre-assigned scheme if you want, of course, but the labels of the modes in DataDumper won't match what you're doing unless you also tweak the mod code.
In general, I recommend using max-level characters but loading them in Normal mode. That way if any combat ends up getting triggered while the dumping is happening, there's zero risk in just sitting there and taking it. In practice, that never really happens so long as you don't move around before dumping, but there's a few levels where enemies spawn quite close.
- Sal/Gunzerker will do the bulk of the automated dumping. Starting map location is irrelevant. Make sure he's gone through the entire game content, including DLC5 (Commander Lilith), so no cutscenes are triggered when hopping around.
- Axton/Commando, stationed in Wurmwater or Oasis (so long as Catch-a-Ride is active in that DLC). He will be the one to spawn two sets of Skiffs during the process. (First Rocket + Harpoon, and then Sawblade.)
- Maya/Siren, stationed in Scylla's Grove. She will be the one to spawn two sets of Fan Boats. (First Corrosive + Flamethrower, then then Shock.)
- Gaige/Mechromancer, stationed in the Dust (or anywhere else near a Catch-A-Ride where enemies are unlikely to spawn). She will be the one to spawn first a pair of Bandit Technicals, and then a pair of Runners.
- Zer0/Assassin, stationed anywhere
- Krieg/Psycho, stationed anywhere
The character order is the same as in Borderlands 2, though since AoDK doesn't have any vehicles, those can be ignored. I actually did all these dumps with Level 1 characters who had done none of the game (since I wasn't actually interested in playing the standalone version). I never had any problems with enemies attacking during the process.
- Sal/Gunzerker will do the bulk of the automated dumping.
- Axton/Commando
- Maya/Siren
- Gaige/Mechromancer
- Zer0/Assassin
- Krieg/Psycho
I'm honestly not sure why I'd had Claptrap spawn both Moon Buggies but split up the stingrays between Wilhelm and Jack. At this point it's ever so slightly more work to change it in the mode settings than it is to leave it, though, so there it is.
- Nisha/Lawbringer will do the bulk of the automated dumping. Starting map location is irrelevant. She should have gone through the entire game content, including Claptastic Voyage, so no cutscenes are triggered when hopping around.
- Claptrap/Fragtrap, stationed somewhere with a handy Moon Zoomy station (Triton Flats or Serenity's Waste is best). He will be the one to spawn a pair of Moon Buggies.
- Wilhelm/Enforcer, stationed somewhere with a handy Moon Zoomy station (Triton Flats or Serenity's Waste is best). He will be the one to spawn the Flak Stingray.
- Jack/Doppelganger, stationed somewhere with a handy Moon Zoomy station (Triton Flats or Serenity's Waste is best). He will be the one to spawn the Cryo Stingray.
- Athena/Gladiator, stationed anywhere
- Aurelia/Baroness, stationed anywhere
The DataDumper
mod from this repo should be copied into PythonSDK's Mods
dir. Then copy the scripts from the scripts
dir into your WillowGames
folder (where your Logs
and SaveData
dirs are). Make sure you can
activate "Data Dumper" mod from PythonSDK's "Mods" menu, and prep the
characters listed above -- make sure they're stationed at the correct maps
to be able to spawn vehicles, etc.
If you've run the data dumper in the past, you may want to head into the game's
Binaries
dir to see if there are control files left inside the datadumper
directory there. If so, you may want to delete all those just so nothing has
an opportunity to get in the way.
At the moment, there's at least a couple of things you'll have to tweak in the scripts, even if you're running on Linux.
- In
check_undumped.py
andgenerate_obj_dump_lists.py
, update theoutput_dirs
var to point to your actual game install locations. Keep thedatadumper
path at the end, afterBinaries
. - In
compare_blcmm_data.py
, update thestock_files_dir
to point at the location of your original BLCMM data jars, so it knows where to find the data to compare to. - You may want to read the notes about open filehandles in
categorize_data.py
and make sure you understand what to do about that. As I've mentioned elsewhere, it's possible that this utility, as written, is only usable by folks on Linux. If a Windows user ever does want to go through this process, I'd welcome a PR with a Windows-friendly version.
- Start the game, activate Data Dumper, and head into game as Sal or Nisha.
You're already in
Maps Getall Forward
mode, but you can hitN
andP
to cycle through the modes to verify. HitB
to run it. Once the dumping is done, and you're back on the main menu, load each of the other chars above, in order, hitN
to cycle to the appropriate mode (for instance,Axton + Rocket/Harpoon Skiff Getall
for the first Axton dump), spawn any vehicles requested by the mode (for instance, Axton should spawn the rocket and harpoon skiffs), and thenB
to run the mode. Repeat for all character/vehicle modes. HitP
to cycle backwards if you accidentally miss a mode.- Once done and you've exited the game, copy
Launch.log
up alongside the scripts you copied, with the filenameLaunch.log-all_object_names_fwd
- Once done and you've exited the game, copy
- Start the game again, activate Data Dumper, and you'll be going through the same
process as the previous step but in reverse order. I like to do the
char+vehicle steps first (starting with Kreig or Aurelia), before arriving
at the
Maps Getall Reverse
mode for use with Sal or Nisha. UseN
andP
to cycle through the modes to find the ones you want. Keep in mind that there are a set ofDump
modes after theGetall
modes, and we still want to dogetall
here.- Once you've exited again, copy
Launch.log
up alongside the scripts you copied, with the filenameLaunch.log-all_object_names_rev
- Once you've exited again, copy
- From the commandline, run
generate_obj_dump_lists.py
. This creates a bunch of control files insideBinaries/datadumper
which the mod will use in the next step. - Start the game again, activate Data Dumper, head into game as Sal or Nisha,
and hit
N
a bunch until you cycle toMaps Dump
mode. HitB
to start. When you're back at the main menu and the automated dumps have finished, hop into your individual characters again, usingN
to cycle into the associated char/vehicle mode (withDump
in the title, notGetall
!). Spawn whatever vehicles are necessary, and useB
to run the mode.- Once you've exited, copy
Launch.log
up alongside the scripts, with the filenameLaunch.log-data_dumps
- Once you've exited, copy
- If you want, run
check_undumped.py
to compare the list of attempted object dumps versus the dumps that we actually got. If any are missing (and there probably will be), they'll be saved out in new "control" files in your gameBinaries
dir, underdatadumper/makeup
.- Note first off that objects whose name have a
Willow
prefix, or with big-looking numeric suffixes, are likely to be dynamic objects which just didn't get caught by the initial round ofgetall
filtering. Many of the results in here can be pretty safely ignored.MatineeActor
objects are likely to be not worth bothering with, too. - If you want to try re-dumping from these "makeup" files, move the original control
files in the
datadumper
dir out of the way, and replace with themakeup
files. Then head back into the game and switch to theMakeup Dumps
mode (which is near the end of the mode list), and run that. (That mode is practically identical to the usual map-dumping mode, but will not dump the "Default" objects beforehand.) Thecheck_undumped.py
script will also have let you know if you need to head into any of the char/vehicle-specific modes and re-run from there. - Note that in my experience, this rarely actually succeeds in getting new dumps,
without manually tweaking the makeup control files. Many cases seem to be
objects which have been categorized into the wrong level. So the first map
(
Ash_P
) may have a bunch of objects which are clearly intended for other maps. So you may want to move things around so they make sense, creating your own control files likeCaverns_P.1
and shuffling objects around. You may need to head into an existing BLCMM Object Explorer install to run some references to find out where some objects are intended to be. - Alternatively, if there's not much, you could always just dump the missing
objects manually in-game, of course, instead of loading up the
Makeup Dumps
mode and running that. - If you did get some fresh object dumps, concatenate the new
Launch.log
onto the end of yourLaunch.log-data_dumps
file.
- Note first off that objects whose name have a
- Create a
scrub.txt
file alongside your scripts (and the collectedLaunch.log-*
files). This file will contain patterns to scrub out of the data, used to hide things like usernames and Steam IDs when prepping datasets for public release. If you don't care about sanitizing data, just create it as an empty file. Keep in mind that if any string you put in here is too generic, you may end up replacing strings in more data than you intend. Strings to consider adding:- Steam Username
- 17-digit Steam ID
- Steam Support Token
- Epic Games equivalents of the above, if running off EGS.
- Local box hostname (in all uppercase)
- Run
categorize_data.py
- This step may currently only work on Linux, and even on Linux will probably require temporarily tweaking your user's allowed open filehandle count.
- This step will also use the contents of
scrub.txt
to automatically scrub data from the dumps. See below for some known locations of information you might want to remove, or where to find some of the info if you're not sure what it is (like your Steam ID or Shift support token, etc). - This utility will also recommend manually clearing the
Scrollback
attribute from an object which holds console scrollback info. Do so manually, if you want.
- If you want, run
compare_blcmm_data.py
to compare the categorized dataset against the dumps provided by the original vanilla BLCMM data. This will generate acomparisons_blcmm
directory which you can browse through, and see if anything in there merits manual dumping. Note that there are various CLI args to this util which can filter out various objects which are likely to be "noise" in the results. You'll probably want to run it with-c
/--clean
to turn on all of these.- If you do have objects you want to manually dump, hop into the game and do so.
You can make use of the
Makeup Dumps
mode, if you want to use control files such as describe above in thecheck_undumped.py
section. - Once you've exited the game, concatenate the new
Launch.log
to the end of yourLaunch.log-data_dumps
file, and re-runcategorize_data.py
- If you do have objects you want to manually dump, hop into the game and do so.
You can make use of the
- If you want, run
compare_openblcmm_data.py
to compare the categorized dataset against previous dumps prepared for OpenBLCMM. Data for OpenBLCMM has basically always been generated with these tools, so the results should hopefully be pretty similar. This utility supports the same options to decrease noise, and you probably want to be using the-c
/--clean
option to get the cleanest comparison possible.- As before, if you do have objects you want to manually dump, hop into the game
and do so. You can make use of the
Makeup Dumps
mode, if you want to use control files such as describe above in thecheck_undumped.py
section. - Once you've exited the game, concatenate the new
Launch.log
to the end of yourLaunch.log-data_dumps
file, and re-runcategorize_data.py
- As before, if you do have objects you want to manually dump, hop into the game
and do so. You can make use of the
- Copy
resources/enums.dat
into the same directory as the scripts you've been running, and then rungenerate_blcmm_data.py
- this will generate OE-compatible files inside the directorygenerated_blcmm_data
. Note that the current version of this script generates data for OpenBLCMM, the newer 2023 version, not the BLCMM version that's been in-use for awhile now.
The categorize_data.py
script will attempt to scrub sensitive data for you,
as it's looping through the dumps, based on the contents of a scrub.txt
file
which you can provide yourself. As mentioned above, you probably want to be
scrubbing your steam username/userid, Shift support-token, and possibly your box's
local hostname. For users on Epic/EGS, there's probably some similar things
to filter out.
Also as mentioned above, if your Steam username (or other info) happens to be
a string which might appear somewhere in the Borderlands data, you may end up
wanting to scrub that info manually instead of using scrub.txt
. The scrubbing
process is pretty stupid, and could match strings inside dialog subtitles, or
even inside object or attribute names. Make sure to watch the output of
categorize_data.py
to make sure that the list of objects with scrubs ends up
looking mostly like the list below. The process will replace the given strings
with <hidden>
, so you can search the resulting dump files for that string
to see what might've been replaced.
The other thing to look out for, which categorize_data.py
takes care of as well,
is that there are various instances in the data which output a ShiftId
attribute,
which encodes your (and possibly your friends') Shift ID, as an array of sixteen
bytes. You can search the dumps for ShiftId
to take a look at that if you want. The
categorize_data.py
script automatically replaces the data in every instance of this
with zeroes, so no Shift IDs should be leaked in the data.
Here are the locations of sensitive information that I've found thus far, across all of BL2/TPS/AoDK. Some may only exist for one or two of the three games. Also, some of these don't seem to exist at all, anymore -- there have been various changes to how the game handles its interaction with storefronts since this list was first compiled. There could very well be other objects with other information in existence that haven't been found by myself, too.
- Your hostname (just the local component, and in all uppercase) might be found in:
WorldInfo'Loader.TheWorld:PersistentLevel.WorldInfo_1'
WorldInfo'menumap.TheWorld:PersistentLevel.WorldInfo_0'
- Your Steam username might be found in:
-
OnlineSubsystemSteamworks'Transient.OnlineSubsystemSteamworks_0'
-
WillowGameEngine'Transient.WillowGameEngine_0'
-
WillowGameViewportClient'Transient.WillowGameEngine_0:WillowGameViewportClient_0'
-
WillowOnlineGameSettings'Transient.WillowOnlineGameSettings_0'
-
WillowPlayerReplicationInfo'Loader.TheWorld:PersistentLevel.WillowPlayerReplicationInfo_44'
-
UIDataStore_OnlinePlayerData'Transient.DataStoreClient_0:UIDataStore_OnlinePlayerData_42'
-
- Your 17-digit Steam user ID might be found in:
-
OnlineSubsystemSteamworks'Transient.OnlineSubsystemSteamworks_0'
-
GearboxAccountData'Transient.GearboxAccountData_1'
-
WillowSaveGameManager'Transient.WillowSaveGameManager_0'
-
- Your Shift/Gearbox support token might be found in:
GearboxAccountData'Transient.GearboxAccountData_1'
- Your console history (which may contain any of the above) might be found in:
WillowConsole'Transient.WillowGameEngine_0:WillowGameViewportClient_0.WillowConsole_0'
ShiftId
byte-array representations might be found in:OnlineRecentPlayersList'Transient.OnlineRecentPlayersList_0'
OnlineSubsystemSteamworks'Transient.OnlineSubsystemSteamworks_0'
WillowOnlineGameSettings'Transient.WillowOnlineGameSettings_0'
The general method for data collection goes like this:
- Open each level and do a
getall <ClassName> Name
for each Class in the game, to get a list of all objects in each level.- Note that a
getall Object Name
would theoretically return all the objects as well, but without extra hacking, Borderlands 2 will crash beacuse of too much output, so we're doing it by class, instead. Likewise,getall Field Name
would crash as well, so skip that one too. - Prior to each level dump, generate an easily-recognizable line in
the logfile by doing an
obj dump switch.to.LevelName_P
- Note that a
- Load in all character and vehicle packages, then do the same
getall
loop to get those object names- Prior to this section, generate an easily-recognizable line in the
logfile by doing an
obj dump switch.to.charvehicle
- Prior to this section, generate an easily-recognizable line in the
logfile by doing an
- Finally, return to the main menu to do a further set of
getall
.- Getting dumps from the main menu is very unlikely to be helpful for anything, but it's included for completeness' sake.
- We do the main menu last, because we want object data after hotfixes and other engine changes have been applied.
- Prior to this section, generate an easily-recognizable line in the
logfile by doing an
obj dump switch.to.mainmenu
- Quit the game and save
Launch.log
where it can be found later. The file should be little under 6GB (as of mid-June, 2019), and on my PC took a little under two hours to complete.
- Many objects are dynamically named and can't actually be used in traditional mods, since the object names will change each time a map is loaded.
- Knowing which objects are like that is a bit tricky - in the engine
itself, it's attributes labelled with
transient
which get the dynamic names, but attempting to use that information leads to a lot of processing that we'd have to do.- We could also just build up a list of places in the object tree manually, and exclude from that, but likewise, it's a lot of work.
- So, what we do is just repeat our previous data-collection loop, but just to be sure, we loop through levels in a different order, and load vehicle/character data in a different order as well.
- Quit the game, and save this
Launch.log
file alongside the original one.
- It's possible at this point that some of the transient data might by pure chance end up with the same name while in the same level, but it's supremely unlikely.
- So, loop through each
Launch.log
, using theNo objects found using command 'obj dump switch.to.foo'
markers to differentiate what stage of the dump you're in, and generate a list of objects per map/whatever which only contains objects found in both dumps. - Make sure to do your checking in a case-insensitive manner. The object
names returned by
getall
can vary sometimes, for some reason. For instance, you're likely to see an object withCaraVan
versusCaravan
at some point in your dumps.
- Using the combined object list above, generate a "condensed" list of objects to dump, while looping through levels in-game again. There are a lot of objects which will be active on every single level, so there's no point dumping the stock item pools for each level, for instance.
- This should be easily-generatable using the condensed list: simply remember which objects you've seen before, and only set up dump commands when you've gotten to a new object.
- There are some class types which generate extremely long
obj dump
outputs, which can lead to crashing the game similar togetall Object Name
from above. Rather than try to work around this, we're going to just exclude these classes from the dumps. These have not historically been part of the BLCMM OE dataset anyway, so shouldn't be missed:AnimSequence
GBXNavMesh
GFxRawData
SwfMovie
Terrain
- Remember that there's a step to load characters/vehicles, and heading out to the main menu, as well!
- Also be sure to dump some special object names called
Default__<Classname>
(that's with two underscores inbetween). There'll be one for each class in the game, and some modders find those objects useful.- Do not attempt to dump
Default__Class
- the engine freaks out and crashes.
- Do not attempt to dump
- Restrict the number of
obj dump
commands sent by eachexec
statement, to avoid engine crashing problems. Since some object types will generate longer dumps than others, this could theoretically be fairly intelligently dealt-with, to condense the number ofexec
s that have to be done, but what I've done is restrict it to 600obj dump
statements at once, which seems to be sufficient to dump the whole game. - This should generate a dump file that's a little over 6GB (as of mid June, 2019), and on my PC took a little under 90 minutes to complete.
- A few objects can contain information like your local system username and the like. See above for some sanitization tips.
- This step is simple in that it can be done by executing a single script, but it's actually a pretty involved process. Check the script for more details! The core of the script is generating a big ol' SQLite database which things can query, and then reorganizing the data dumps for ease of access.
This is really only of interest to Apocalyptech, but in case you were interested
too: importing this data into FT/BLCMM Explorer is pretty simple. The main
thing is, after running generate_blcmm_data.py
, to compress the .dump
files using
lzma
(on Linux this can be done with the xz
utilitiy). You'll end up with files
named ClassName.dump.xz
. Copy those into the relevant FT Explorer resource
directory, and then run FT Explorer's generate_indexes.py
(at the top level of
that project). That's it!
Apoc may or may not eventually convert FT/BLCMM Explorer to use the new OpenBLCMM data format instead, which is better in just about every way except for diskspace requirements.
There have historically been a scripts in the scripts
directory which aren't
part of the main dumping process, but I wanted to get committed into source
control. They probably won't be of interest to most folks, but I'll briefly
describe them here:
verify_encoding.py
: Just used to verify the text encoding on the generated dump files, to confirm that they really were latin1/iso-8859-1. Note that this utility is expected to generate some errors as it runs.- A collection of utilities to modify/work with the
Launch.log
files which are generated by various parts of this process. All of these write to a new file rather than overwriting anything, so you'll need to shuffle files around once you've made changes.extract_section.py
: Used to extract a section (map name or char/vehicle mode) from a logfile. For instance, you could specifyCove_P
to extract that section, oraxton2
for Axton's second Skiff run.replace_section.py
: In the event that you want to completely replace a section inside the file (such as if you totally screwed upaxton2
and want to replace it with a fresh version), this is the util which can help with that. Note that the utility replaces the specified section with an entire file -- if you've got a larger file with multiple sections, you may want to extract the new section withextract_section.py
first.strip_duplicate_section.py
: In case you accidentally end up with the same section repeated more than once, you can use this script to strip out the second instance of that section. For instance, if you accidentally run the second set of Axton skiff dumps while still on theaxton1
mode, you can specifyaxton1
for the section to skip the second category.
This code is licensed under the GPLv3 or later. See COPYING.txt for the full text of the license.