========================================= CyberPunk 2077 (PC) CR2W String Utils ========================================= Feb 5 , 2021 Version 1.01 Written by: Dheu Email: Dheuster@gmail.com Use subject: cr2wStringUtil 1.01 QUICK SUMMARY ------------------------------------------------------------------------------- An app/script that allows you to view/edit the string tables of CR2W files (The wrapper format used by CyberPunk 2077 for most game resources). ------------------------------------------------------------------------------- I. > > > > Introduction ------------------------------------------------------------------------------- I was playing around with the CP77 tools and was rather frustrated by the fact that it would spit out all this beautiful detailed JSON, but if you edited the JSON, it offered no way to go back to the original file format. So I made this script/tool to convert both to and from json. It can also make some common changes directly to save time. My converter isn't as advanced as CP77. I don't have logic inline that understands all the object types to expose their insides. However my goal was to simply edit the string tables. To that end, this script is sufficient. This can be used (for example) to change the default texture of a multi-layered mesh. ------------------------------------------------------------------------------- II. > > > > Installation ------------------------------------------------------------------------------- A) This script: 1) If you do not already have it, get 7-zip : www.7-zip.org 2) Once 7-zip is installed, open the .7z file Typically you need only double click the file: cr2wStringUtil_v1_01.7z 3) The 7-zip window will show 4 files: /cr2wStringUtil_src cr2wStringUtil.exe cSU_DragNDrop.cmd cr2wStringUtil_readme.txt 4) Extract to any folder you wish. B) Paranoid Users Some users may not be comfortable running some app they got off the internet. For that matter, your OS may try to protect you by not letting you run that random EXE you got from someone you don't know off a game website. I'm personally a paranoid user, that is why I include source code with all my apps. I've become a fan of python for quick and dirty mod utils because you can include the script (source code) but also compile the script into a stand-alone exe for users who don't want to install python. This distro includes a compiled version of the app, but also includes the apps original python version. So if you don't want to run the the exe delete it and use the python script version under cw2rStringUtil_src instead. This will however require that you install python. I used Python 3.8.2 during development: https://www.python.org/downloads/release/python-382/ I have back-port code that should allow this to work with Python 2.7, but that is untested. (It may not run, but you are welcome to try). C) CP77 For now and the foreseeable future, you need CP77 to extract the game files (and package them back together). As this script is more or less useless without game files, I thought I would include the steps for extracting them. 1) Install .Net 5.0.2 SDK (Not ASP.NET): https://dotnet.microsoft.com/download/dotnet/5.0) 2) Install CP77 Tools. These instructions were made with version 1.1.0.2 https://github.com/WolvenKit/CP77Tools/releases To make these instructions more simple, I will assume you install it under: C:\CP77Tools 3) Create a sym link: This will make everything easier. Run "cmd". Then type: C:\Users\SoemGuy>cd \ C:\>mklink /J "C:\CP77" "PATH_TO_CYBERPUNK" Where PATH_TO_CYBERPUNK is the full path to cyberpunk, wherever you have it install. For example, Steam users might use the command: mklink /J "C:\CP77" "C:\Program Files (x86)\Steam\steamapps\common\Cyberpunk 2077" 4)Copy oo2ext_7_win64.dll to CP77 Tools Either use file explorer to drag-n-drop the file or you can do it from the command prompt: C:\>copy "C:\CP77\bin\x64\oo2ext_7_win64.dll" "C:\CP77Tools\" 5) Run C:\CP77Tools\CP77Tools.exe Double click the file from Explorer, or from command prompt: C:\>cd C:\CP77Tools C:\CP77Tools>CP77Tools.exe This will start up a console app. 6) Extract the Archives Extract the game archives to a common directory. This is recommended if you want to be able to search for things. It does require about 180 GB of space. So make sure you have room before doing this. Also, if you have an SSD, that is best for file searches. With CP77Tools.exe running, type (copy paste) the following commands. Some will take a long time to finish (as in... make a cup of coffee long). To copy/paste... highlight a row below, hit CTRL+C. Then in the console window, hit CTRL+V. unbundle -p "C:\CP77\archive\pc\content\audio_1_general.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\audio_2_soundbanks.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_1_engine.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_2_mainmenu.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_3_nightcity.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_3_nightcity_gi.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_3_nightcity_terrain.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_4_animation.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_4_appearance.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_4_gamedata.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\basegame_5_video.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\lang_en_text.archive" -o "C:\CP77Dev" unbundle -p "C:\CP77\archive\pc\content\lang_en_voice.archive" -o "C:\CP77Dev" 7) [optional] Uncook the appearances Uncooking the archives will provide the .buffer files needed by some scripts. My script doesn't care, but there are some modeling import/export plugins out there that do. You will see some error messages as the command will try to uncook everything... even things that don't have anything to uncook. You can ignore the errors. uncook --uext png -p "C:\CP77\archive\pc\content\basegame_1_engine.archive" -o "C:\CP77Dev" uncook --uext png -p "C:\CP77\archive\pc\content\basegame_2_mainmenu.archive" -o "C:\CP77Dev" uncook --uext png -p "C:\CP77\archive\pc\content\basegame_3_nightcity.archive" -o "C:\CP77Dev" uncook --uext png -p "C:\CP77\archive\pc\content\basegame_4_animation.archive" -o "C:\CP77Dev" uncook --uext png -p "C:\CP77\archive\pc\content\basegame_4_appearance.archive" -o "C:\CP77Dev" uncook --uext png -p "C:\CP77\archive\pc\content\basegame_4_gamedata.archive" -o "C:\CP77Dev" ------------------------------------------------------------------------------- III. > > > > Usage ------------------------------------------------------------------------------- A. From command line: cr2wStringUtil [options] [infile] [infile] ... Options: -ei : Enum Info -si : String Info -es VAL1 VAL2 : Swap two Enums values -ec VAL1 VAL2 : Copy one Enum over another -ss VAL1 VAL2 : Swap two String values -sc VAL1 VAL2 : Copy one String over another -r VAL1 VAL2 : Replace String/Enum value -d : Show Debug Output -t : Show Trace Output -h : detailed help (you are viewing quick help) When ran with no options, it converts cr2w to json by default (or vice-versa if it is ran against a json file). Examples: 1) Cr2w to json cr2wStringUtil example.mesh Output: cr2wStringUtil example.mesh.json 2) Json to Cr2w (Only understands JSON made by this script) cr2wStringUtil example.mesh.json Output: cr2wStringUtil example.mesh.cr2w 3) Swap default textures of arms from pale to dark: cr2wStringUtil -es 01_ca_pale 06_bl_dark a0_000_pma_base_hq__l.mesh Details: -------- Most commands will take a string name OR an index. When you run copy, swap or replace, the current enum table and indexes are shown. When processing files in batch, you must use the string name (enum offsets can vary from file to file, so only names are reliable across files). For even more detail on CR2W format, etc... see Python source code. Understanding Enum versus String: --------------------------------- CR2W files start off with a header containing raw string data. The string data is then followed by 2 enum tables. A Name Enums table for smaller strings and a Path Enums table for larger strings such as file paths to resources in the game. Enums point to offsets in the string data. Meanwhile, the rest of the protocol makes use of the enum index to describe objects in a compact manner. IE: Objects never point directly to string data. They point to enums (order is important) which then redirects to the string data: [Object] ====> [Enums] =====> [String Data] So if you want to change the texture some model is using for skin, you can change what strign an enum points at if the change is to a string that is already in the file. You could also change the raw string data that the enum points at. Even replace a string with a value that is not in the current file. The main thing users need to know is that changing enums is safer than changing strings. When you mess change strings, the entire header has to be re-written because the offsets change (All enums must be updated with the new offsets). When you alter what an enum points to, you only change a single pointer. But when you change a string, you basically create the need to update all pointers and rewrite the string data. Fewer changes means less chance of human error. So in general, focus and making your changes by redirecting enums and only mess with strings when you have no choice. Order of Edits: --------------- If you want to change Enums AND String values, make you updates to the string values first and then make your updates to the enums. This will result in more stable files than if you do it the other way around. B. Drag-n-Drop The distro includes a file called cSU_DragNDrop.cmd. As the name implies, you can drag and drop a file or directory onto the file and the batch script will prompt you for what you want to do. FILES: ----- If you Drag non-json files onto the redirect script, you will see the following: What would you like to do? 1 - Convert to JSON 2 - Swap two ENUMS 3 - Copy an Enum 4 - Swap two STRINGS 5 - Copy a STRING 6 - Replace STRING (ENUM) 7 - Export ENUM info to FILENAME.enums.txt 8 - View raw String Table 9 - Exit > If you convert to json, it will append ".json" to the files and save the json versions. Conversly if you Drag-n-Drop json files onto the redirect script, it will immediatly try to convert them to CR2W. Note I said "files". You can drag multiple files on at once. However if you choose anything other than JSON conversion, only the first file will be processed. While the scripts primary function is converting to/from JSON, if you happen to want to do the other things in this list, it will backup the original file (Add .bak) and update the original file in place, bypassing the JSON conversion. If an error is detected, for example the string you provided wasn't found, it will abort. Directories: ------------ If you Drag a directory onto the redirect script, you will see the following: What would you like to do? 1 - Export Folder Contents to JSON 2 - Import Folder Contents from JSON 3 - Swap two ENUMS across entire folder 4 - Copy an ENUM across entire folder 5 - Swap two STRINGs across entire folder 6 - Copy a STRING over another across entire folder 7 - Replace a STRING/ENUM across entire folder 8 - Export Value Infos to FILENAME.info.txt 9 - Exit > All options will follow up with a prompt of whether you want to traverse sub-directories or not. When batch processing, the .cmd file has a file filter in place such that it only (automatically) converts the following extensions: *.acousticdata *.anims *.app *.cfoliage *.cminimap *.cookedapp *.effect *.ent *.facialcustom *.facialsetup *.fnt *.geometry_cache *.mesh *.mi *.morphtarget *.navmesh *.particle *.physicalscene *.physmatlib *.psrep *.quest *.questphase *.reps *.scenerid *.streamingsector *.streamingsector_inplace *.w2mesh *.xcube Other potential extensions include the following (These are currently ignored by batch processing): *.archetypes *.areas *.audio_metadata *.audiovehcurveset *.behavior *.bikecurveset *.bk2 *.bnk *.camcurveset *.charcustpreset *.community *.conversations *.cooked_mlsetup *.cookedanims *.credits *.csv *.cubemap *.curveset *.devices *.dtex *.envparam *.envprobe *.es *.fb2tl *.folbrush *.foldest *.fp *.game *.gamedef *.garmentlayerparams *.genericanimdb *.gidata *.gradient *.hp *.ies *.inkanim *.inkatlas *.inkcharcustomization *.inkfontfamily *.inkfullscreencomposition *.inkgamesettings *.inkhud *.inklayers *.inkmenu *.inkshapecollection *.inkstyle *.inktypography *.inkwidget *.interaction *.journal *.journaldesc *.lane_connections *.lane_polygons *.lane_spots *.lights *.lipmap *.location *.locopaths *.loot *.mappins *.matlib *.mlmask *.mlsetup *.mltemplate *.mt *.null_areas *.opusinfo *.opuspak *.phys *.png *.poimappins *.ragdoll.json *.remt *.reslist *.rig *.scene *.scenesversions *.smartobject *.smartobjects *.sp *.spatial_representation *.streamingquerydata *.streamingworld *.terrainsetup *.texarray *.traffic_collisions *.traffic_persistent *.vehcommoncurveset *.vehcurveset *.voicetags *.w2mi *.wem *.workspot *.xbm If you wish to include some of these other extensions, you will need to update the .cmd file (Look for the for ( ) loops ) and add the extensions to the file filter. Of coarse, single file drag-n-drop has no filters. ------------------------------------------------------------------------------- IV. > > > > Credits ------------------------------------------------------------------------------- - anygoodname (NexusMods) - Discovered Space-In-Path Bug - Looping Menu System idea ----------------------------------------------------------------------- V. > > > > Version History ------------------------------------------------------------------------------- 1.0 - Initial Version (No changes) 1.01 - Added Looping Added Copy From-To support Added multi-file drag-n-drop JSON conversion support Minor bug fixes with paths that have spaces