Skip to content
ovY9jkhTEUpllGPJRrKU edited this page Jan 18, 2024 · 1 revision

Table of Contents

  1. Instructions
  2. Removing a Player's Voice (Example)
  3. Regex Patterns
  4. Formats in JSON to Recognize

Instructions

  • Downloading all the voice files of every player into a folder

    For the <folder name>, you do not have to create it. demboyz will automatically create a new folder for you: \

    demboyz.exe <demo file> <folder name>
    
  • Storing the demo file information into a json

    Make sure to end the <json file> with .json:\

    demboyz.exe <demo file> <json file>
    

Removing a Player's Voice (Example)

The way that I usually do this is by using regex and modifying the JSON file generated by demboyz. If someone has a better method or more preferable method, feel free to share what they did.

  • For clarification, I am using a demo pulled from the Counter-Strike: Source GFL Zombie Escape servers. The download link is located in https://demos.2qt.eu/css-ze/. The specific file I will modify will be auto-20230812-211600-ze_scp_v4.dem (download here).

.bz2 files can be extracted with 7-zip

1. Extract the .dem file into demboyz/bin

2. Create the .json file by running this command on powershell:

.\demboyz.exe auto-20230812-211600-ze_scp_v4.dem ze_scp_v4.json

Some .json files may take a very long time to build depending on the size of the .dem file

3. Create the audio folder by running this command on powershell:

.\demboyz.exe auto-20230812-211600-ze_scp_v4.dem ze_scp_v4

4. Open the .json with a Text Editor (I use Notepad++)

*When opening a big .json file with VSCode, it could crash or take awhile to load due to the amount of bytes written.

There are two ways to remove a player:

  1. Easy: Listen to the .wav files in the folder you created (ze_scp_v4), then based on the voice in client_{index_number}.wav, use index_number as the value you want to remove (a lot easier).
  2. Hard (Method described here): Parse the .json file for the user you want to remove, and determine their index_number (This starts from 0 to 255).

5. Search: "text": "# (Ctrl + F on Notepad++) and go to the first search

1. This part is usually complicated because the mapping between players and voice data changes (I believe?) due to it being broken up into sections. The ordering of the players is not the same in each section and they could have been listed the first time. If someone with a better understanding of the `.json` construction could help me understand this, that would be helpful. This is how I understand how the section is constructed when I looked through the code. 1. You can think of the mapping or sections like:
# Section 1
(User name -> index)
  |---> (User index -> Voice chat)
# Section 2
(User name -> index)
  |---> (User index -> Voice chat)
# Section 3
(User name -> index)
  |---> (User index -> Voice chat)

6. Scroll through until you find the user you want gone

7. Map out the username to the index number (starting from 0)

.json text snippet

{
    "text": "# 2        \"TorchTV\"                                BOT                      dead  human \n"
}{
    "netpacket": 7
}{
    "text": "# 5        \"Earthquake\"                             STEAM_0:1:161096309      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 6        \"male\"                                   STEAM_0:0:131412172      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 7        \"CaptainWalter\"                          STEAM_0:1:49666770       alive human \n"
}

Mapping:

-------------------------
| Username      | Index |
-------------------------
| TorchTV       | 0     |
| Earthquake    | 1     |
| male          | 2     |
| CaptainWalter | 3     |
-------------------------

8. Grab the pattern regex from here and make sure to replace REPLACE STRING.

Since I want to remove TorchTV, I will replace REPLACE_STRING with 0

  1. You can use this regex to change the output with whatever string replacing program you use. I believe Notepad++ is the most convenient way if you want to not write a program to automate the process for you.

9. Open Notepad++ > Ctrl + F > Replace > Click Regular expression under Search Mode > Paste the regex pattern in "Find what:" > Add "$1 0$3" (no double quotes) in "Replace with:" > Click "Replace All" > Save the file

This can take awhile if your file is 50+ MB. Just let it complete the process.

10. In Powershell, compile the newly saved .json to a .dem file:

Note: I saved as ze_scp_v4_new.json

.\demboyz.exe ze_scp_v4_new.json ze_scp_v4_new.dem

11. In Powershell, extract all the audio files:

.\demboyz.exe ze_scp_v4_new.dem ze_scp_v4_new

You can also load the demo you modified and the user's voice should not be there

Checking the folder is faster since you won't have to reload a demo, but only check that the audio is 0 seconds long

Regex Patterns (Rust style)

Get all voice commands from a specific user

Replace REPLACE_STRING with the index number

(\s+"fromClientIndex": REPLACE_STRING,\n.+\s+"dataLengthInBits":)( \d+)(,\n.+)

Explanation:

Group 1: The user index and proximity (key + value) and dataLengthInBits (key)
Group 2: dataLengthInBits (value)
Group 3: data (key + value)

How to group for regex replacing pattern

$1 0$3

Explanation:

We want to print out (group 1) 0(group 3) since our goal is to replace dataLengthInBits value with 0.

Formats in JSON to Recognize:

User list (no indices)

}{
    "text": "# 2        \"TorchTV\"                                BOT                      dead  human \n"
}{
    "netpacket": 7
}{
    "text": "# 5        \"Earthquake\"                             STEAM_0:1:161096309      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 6        \"male\"                                   STEAM_0:0:131412172      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 7        \"CaptainWalter\"                          STEAM_0:1:49666770       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 8        \"Cow\"                                    STEAM_0:0:65459749       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 9        \"WarpedCakez\"                            STEAM_0:1:79341741       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 58       \"mini\"                                   STEAM_0:1:429610828      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 66       \"cee anide\"                              STEAM_0:1:180503667      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 12       \"machu\"                                  STEAM_0:1:94908621       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 13       \"Trap Babe\"                              STEAM_0:1:23822794       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 69       \"Pudding!!!\"                             STEAM_0:0:202214768      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 70       \"NoLifer\"                                STEAM_0:1:193150773      alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 71       \"Star\"                                   STEAM_0:1:14748941       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 25       \"cron\"                                   STEAM_0:1:54109628       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 72       \"j0ueurnul\"                              STEAM_0:0:45008978       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 28       \"iHaz Ol'timers\"                         STEAM_0:0:16486044       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 29       \"Lev\"                                    STEAM_0:0:23670843       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 73       \"iszaar\"                                 STEAM_0:0:88083057       dead  human \n"
}{
    "netpacket": 7
}{
    "text": "# 74       \"Soviet_Tornado\"                         STEAM_0:1:79703037       alive human \n"
}{
    "netpacket": 7
}{
    "text": "# 33       \"Kultakalle2\"                            STEAM_0:0:42114365       alive human \n"
}{
    "netpacket": -1
}{

Voice Chat with Indices

}{
    "netpacket": 15
}{
    "fromClientIndex": 10,
    "proximity": false,
    "dataLengthInBits": 1024,
    "data": "GDar97pPF1n3yb3klp248YzeW2Ke5zOrQmkMRTWVtKol9yXNgnydRR+0YG0/xxD/8vF9Eu9w5L8S5+lfkAIxxhhVgZdUeXLVE9xHLovjsFJLAUiX7JZg6SjPgqpg3UnS0VfW8s/C1wPggskn+hTfK0ty/qeOqgZYwm+yOf8/PRY="
}{
    "netpacket": 15
}{
    "fromClientIndex": 17,
    "proximity": false,
    "dataLengthInBits": 1024,
    "data": "GJrpCEM2i8YKrlVyhFsMQqfA70I99NNVuYSxZx1WGIEsfwGi8jahjhKQSNmTyAG0w2oCC8Xpqi8WSRIhlhQzpxib2FIqsk/W5vN3kVjCsn1e7nygvIDaVgPOQckwkEkPYQN3EmO+nj8q6I0aomC1fqAcqWYuLB+WovjT+PwiB4Y="
}{
    "netpacket": 15
}{
    "fromClientIndex": 30,
    "proximity": false,
    "dataLengthInBits": 1024,
    "data": "GJwGkS6wrFsSm3zUTDyrW7WoiIu8uv8HkAkUZNjLEmtZeLOmuAdai0B8kMC/ESL7Wx/vDGS/eo0AsFqvVYZKWRhe17GrrC/DSgIA9V3jL86jTePeGJ5Z0dMpXMG06ZOR7IA9T/MXgXjoo66O5dRMtDz0dSu6Oocy21AGCRPIHoM="
}{
    "netpacket": 15
}{
    "fromClientIndex": 9,
    "proximity": false,
    "dataLengthInBits": 512,
    "data": "GLCvuGcgWujoYf0vy0pEYYUVLO6/OaACirgyoWo3+9N8CwoKrMPQpUDsV9NWYLsaGJrRG9XGWQwipsNLPJD9HA=="
}{
    "netpacket": 15
}{
    "fromClientIndex": 20,
    "proximity": false,
    "dataLengthInBits": 512,
    "data": "GIeFd3T2QvBgpib4dDAOtMNiL9eySo2oMGmUIEX9S+x9POZi3+hvitt5y1LyncijvH5i3gOPrINdT60/4RwJtw=="
}{
    "netpacket": 15
}{
    "fromClientIndex": 32,
    "proximity": false,
    "dataLengthInBits": 512,
    "data": "GPDKGq6oJd7YPWLhLAW3QPp8o9y6g0iS5FzFwYRNCSzdF1ICNsMjh1nDyEiY9/STs5QMcpgdDOdF+bFFDomHMQ=="
}{
    "netpacket": 15
}{
    "fromClientIndex": 10,
    "proximity": false,
    "dataLengthInBits": 512,
    "data": "GFcrP+tsWGfahUPWbRK50QCCb8ZarHj79a7fQ/RmJFekcvT/6Y6LObzxMq1KQzQ6dv6pLicAPO9pqz7uNy1ixQ=="
}{
    "netpacket": 15
}{
    "fromClientIndex": 2,
    "proximity": false,
    "dataLengthInBits": 512,
    "data": "GDTyG2224vrDesP8KakAFl/nnKIAa5nwHiS7IqiIjWLAO00ndiHdXZcMso9pcQVTrvFuAfDkkGUZ4+anjEN34w=="
}{
    "netpacket": 15
}{
    "fromClientIndex": 30,
    "proximity": false,
    "dataLengthInBits": 512,
    "data": "GFDPOuLRTAmrOp7eQf3tct7DqpZ/4iZ2Ms0XHuef+j1daDN9kWv35/MuVWRtcw+8SJh4lG7ZK1Qt4u8eSqAjSA=="
}{
    "netpacket": 15
}{
    "fromClientIndex": 0,
    "proximity": false,
    "dataLengthInBits": 512,
    "data": "GAoe7oLddOwVw6akrKVR89VrPumlOm9uy7aY6dA5gmU6MvTM6nfLgtd8oeSmz089kI4omjU9mPGKMjXUV35dAA=="
}{
    "netpacket": 15
}{