Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #13 from szmarczak/000s
Browse files Browse the repository at this point in the history
Add 0.000s defuser
  • Loading branch information
kkthxbye-code authored May 18, 2020
2 parents d8740f2 + 9190b95 commit d2ccc3b
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 0 deletions.
Binary file added netcon_stuff/0s_defuser/000.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
169 changes: 169 additions & 0 deletions netcon_stuff/0s_defuser/0s_defuser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
'use strict';
const net = require('net');
const readline = require('readline');
const path = require('path');

const TICK_RATE = 64;

let previous = {};
let timeout10s;
let timeout5s;
let counter = 0;

let defuseMode = 0;
let explosionTime = 0;

const sendOnConnect = `developer 1;
con_filter_enable 2;
con_filter_text "Time until explosion: ";
bind 0 "echo defuse_0s_0";
bind - "echo defuse_0s_1";
bind = "echo defuse_0s_2";`;

const onChange = data => {
const hasPrevious = data.Name in previous;
const isDifferent = !hasPrevious || previous[data.Name].In !== data.In;

if (!isDifferent) {
return;
}

if (data.Name === 'bomb_planted') {
previous[data.Name] = data;

if (counter === 2) {
explosionTime = Date.now() + 40000;
clearTimeout(timeout10s);
clearTimeout(timeout5s);

// This should be set between 29970 - 29980

timeout10s = setTimeout(() => {
if (defuseMode === 1) {
socket.write(`+use\n`);
}
}, 29970);

timeout5s = setTimeout(() => {
if (defuseMode === 2) {
socket.write(`+use\n`);
}
}, 29970 + 5000);
}
} else if (data.Name === 'round_start') {
previous[data.Name] = data;

if (counter === 2) {
clearTimeout(timeout10s);
clearTimeout(timeout5s);
explosionTime = 0;
defuseMode = 0;
socket.write(`-use\n`);
}
}
};

const COMMAND = 'net_dumpeventstats';
const WANTED = {
Name: 'string',
Out: 'number',
In: 'number',
OutBits: 'number',
InBits: 'number',
OutSize: 'number',
InSize: 'number',
Notes: 'string'
};

const WANTED_KEYS = Object.keys(WANTED);
const WANTED_STRING = WANTED_KEYS.join(' ');
const WANTED_LENGTH = WANTED_KEYS.length;
const whitespaceRegExp = /\s{2,}/g;

const port = Number(process.argv[2] || 0);
if (process.argv.length !== 3 || !port) {
console.error(`Usage: node ${path.basename(process.argv[1])} [port]`);
return;
}

const socket = net.connect(port, '127.0.0.1', async () => {
console.log('Connected! Press CTRL+C to abort.');

socket.write(`${sendOnConnect}\n`);

const reader = readline.createInterface({
input: socket,
crlfDelay: Infinity
});

let reading = false;

for await (const line of reader) {
const processedLine = line.replace(whitespaceRegExp, ' ').trim();

if (processedLine === 'defuse_0s_0') {
defuseMode = 0;
} else if (processedLine === 'defuse_0s_1') {
defuseMode = 1;
} else if (processedLine === 'defuse_0s_2') {
defuseMode = 2;
} else {
if (reading) {
const parsedLine = processedLine.split(' ');

if (parsedLine.length !== WANTED_LENGTH) {
reading = false;
continue;
}

const object = {};

for (let index = 0; index < WANTED_KEYS.length; index++) {
const key = WANTED_KEYS[index];
const type = WANTED[key];

if (type === 'string') {
object[key] = parsedLine[index];
} else if (type === 'number') {
object[key] = Number(parsedLine[index]);

if (Number.isNaN(object[key])) {
reading = false;
}
}
}

if (reading) {
onChange(object);
}
}

if (processedLine === WANTED_STRING) {
if (counter < 2) {
counter++;
}

reading = true;
}
}
}
});

setInterval(() => {
socket.write(`clear\n${COMMAND}\n`);

const diff = Math.max(explosionTime - Date.now(), 0);

let mode;
if (defuseMode === 0) {
mode = '[NO AUTODEFUSE]';
} else if (defuseMode === 1) {
mode = '[AUTODEFUSE 10s]';
} else if (defuseMode === 2) {
mode = '[AUTODEFUSE 5s]';
}

socket.write(`echo "Time until explosion: ${(diff / 1000).toFixed(3)}s ${mode}"\n`);
}, Math.floor(1000 / TICK_RATE)).unref();

socket.setEncoding('utf8');
37 changes: 37 additions & 0 deletions netcon_stuff/0s_defuser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## 0s defuser

![](timer.png)

![](000.png)

Exploit made by [@szmarczak](https://github.com/szmarczak).

Works the same as the [hitmarker](../hitmarker), but it checks `bomb_planted` instead.

All necessary commands are executed immediately when you run the script. The following commands are run:

```
developer 1;
con_filter_enable 2;
con_filter_text "Time until explosion: ";
bind 0 "echo defuse_0s_0";
bind - "echo defuse_0s_1";
bind = "echo defuse_0s_2";
```

Key description:
- `0` - disables autodefuse,
- `-` - enables 10s autodefuse (IOW without defuse kit),
- `=` - enables 5s autodefuse (IOW with defuse kit).

What's an autodefuse? If you have killed all of your enemies and have plenty of time, you can enable autodefuse. It starts defusing automatically so you will have a `0.000s` defuse time.

**Note:** Your crosshair must be pointed at the bomb.

### Requirements

* [Node.js 14+](https://nodejs.org/en/download/current/)

### Usage

Start CS:GO with `-netconport 2121` and then run `node 0s_defuser.js 2121`. Works offline and online.
Binary file added netcon_stuff/0s_defuser/timer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d2ccc3b

Please sign in to comment.