Skip to content

Instantly share code, notes, and snippets.

@ericek111
Created May 18, 2018 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericek111/32b6ba19344aeb878db2bfa5dddc9abe to your computer and use it in GitHub Desktop.
Save ericek111/32b6ba19344aeb878db2bfa5dddc9abe to your computer and use it in GitHub Desktop.
CS:GO Bhop Detector 3000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="./browser/bundle.js"></script>
</head>
<body>
<h1>Select a file</h1>
<form>
<input type="file" id="file">
<label>
<input type="checkbox" id="printEvents">
Print events
</label>
<label>
<input type="checkbox" id="printUserInfo">
Print player info
</label>
</form>
<h1>Parsed output</h1>
<progress id="progress" max="100"></progress>
<pre id="output"></pre>
<script type="text/javascript">
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
var file = document.getElementById('file');
var output = document.getElementById('output');
var progress = document.getElementById('progress');
var printEventsElement = document.getElementById('printEvents');
var printPlayerInfoElement = document.getElementById('printUserInfo');
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'hante.dem', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
progress.value = 0;
output.textContent = '';
var printEvents = printEventsElement.checked;
var printPlayerInfo = printPlayerInfoElement.checked;
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = function() {
var buf = new Buffer(reader.result);
demo = new demofile.DemoFile();
voicedatabufs = [];
demo.on('progress', function(perc) {
progress.value = perc * 100;
});
demo.on('end', function() {
output.textContent += '\nParse complete.';
});
demo.on('start', () => {
output.textContent += '\n' + 'Demo header: ' + demo.header;
});
demo.on('end', () => {
output.textContent += '\n' + 'Finished.';
});
/*demo.on('svc_UpdateStringTable', e => {
output.textContent += '\n' + '=> svc_UpdateStringTable: ' + e.name + (e.tableId !== 'undefined' ? (" / " + e.tableId):"");
console.log(e);
});
demo.on('svc_CreateStringTable', e => {
output.textContent += '\n' + '=> svc_CreateStringTable: ' + e.name + (e.tableId !== 'undefined' ? (" / " + e.tableId):"");
});*/
demo.conVars.on('change', e => {
if(e.oldValue)
output.textContent += '\n' + e.name + ": " + e.oldValue + " -> " + e.value;
else
output.textContent += '\n' + e.name + ": " + e.value;
});
demo.gameEvents.on('player_death', e => {
let victim = demo.entities.getByUserId(e.userid);
let attacker = demo.entities.getByUserId(e.attacker);
if (victim && attacker) {
output.textContent += '\n' + attacker.name + ' killed ' + victim.name + ' with ' + e.weapon;
}
});
demo.gameEvents.on('event', function(e) {
//output.textContent += '\n' + e.name + ' ' + JSON.stringify(e.event);
/*if (e.name == 'player_hurt') {
var player = demo.entities.getByUserId(e.event.userid);
if(player != null) {
output.textContent += '\n' + dec2bin(player.props.DT_BasePlayer.m_fFlags);
}
}*/
});
var uniquetables = [];
demo.stringTables.on('update', function(e) {
//output.textContent += '\nuser update: ' + e.entryIndex + ' ' + JSON.stringify(relevantData);
//console.log(e);
if(!uniquetables.includes(e.table.name)) {
output.textContent += "\n" + demo.currentTick + ": ";
output.textContent += 'table: ' + e.table.name;
if(e.table.name == "GameRulesCreation") {
//debugger;
}
uniquetables.push(e.table.name);
}
if (e.table.name !== 'userinfo' || e.userData == null) {
return;
}
var relevantData = {name: e.userData.name, steamId: e.userData.guid, userId: e.userData.userId};
output.textContent += "\n" + demo.currentTick + ": ";
output.textContent += 'user update: ' + e.entryIndex + ' / ' + ' ' + JSON.stringify(relevantData);
//debugger;
});
demo.stringTables.on('message', function(e) {
output.textContent += '\n=> ' + e.name + ': ' + e.msg;
});
demo.gameEvents.on('round_end', e => {
return;
demo.entities.players.forEach(function(player) {
console.log(player);
var player = demo.entities.getByUserId(player.userData.userId);
if(player !== null && player !== 'undefined') {
output.textContent += '\ne: ' + JSON.stringify({ index: player.index, clientSlot: player.clientSlot});
}
});
let teams = demo.teams;
let terrorists = teams[demo.TEAM_TERRORISTS];
let cts = teams[demo.TEAM_CTS];
output.textContent += '\n' + '*** Round ended';// CT:T: ' + cts.score + " : " + terrorists.score;
//output.textContent += '\n' + '*** Round ended \'%s\' (reason: %s)\n\tTerrorists: %s score %d\n\tCTs: %s score %d', demo.gameRules.phase, e.reason, terrorists.clanName, terrorists.score, cts.clanName, cts.score;
//output.textContent += '\n' + '*** Round ended ' + demo.gameRules.phase + ' (reason: ' + e.reason + ')\n\tTerrorists: ' + terrorists.clanName ? terrorists.clanName : "" + ' score ' + terrorists.score + '\n\tCTs: ' + cts.clanName ? cts.clanName : "" + ' score ' + cts.score;
});
demo.on('svc_VoiceInit', e => {
console.log(e);
});
demo.on('svc_VoiceData', e => {
//if(e.audibleMask == 2) return;
//if(e.voiceData == null) return;
voicedatabufs.push(e.voiceData);
//console.log(e);
});
playersjumps = [];
playersjumpsrec = [];
playersjumpdelays = Array(512).fill(new Array());
demo.on('tickend', function(tick) {
demo.entities.players.forEach(function(player) {
//console.log(player);
var i = player.index - 1;
if((player.props.DT_BasePlayer.m_hObserverTarget & 0xFFF) != 0xFFF) return;
if(player.props.DT_BasePlayer.m_fFlags & 1 > 0) { // FL_ONGROUND
if(!playersjumpsrec[i])
playersjumps[i] = tick;
playersjumpsrec[i] = true;
} else {
if(playersjumpsrec[i]) {
if(player.userInfo == null) output.textContent += '\n@ ' + tick + ' Jumped ' + i + ' => ' + (tick - playersjumps[i]);
else output.textContent += '\n@ ' + tick + ' Jumped ' + i + ' (' + player.name + ') => ' + (tick - playersjumps[i]);
//console.log(player);
//output.textContent += '\n' + JSON.stringify(player);
playersjumpsrec[i] = false;
playersjumpdelays[i] = playersjumpdelays[i].concat([tick - playersjumps[i]]);
}
}
//playersjumps[i] = e.currentTick;
});
});
demo.on('end', () => {
output.textContent += '\n' + 'Finished.';
demo.entities.players.forEach(function(player, i) {
if(player.userInfo == null) output.textContent += '\n# ' + (player.index - 1) + ': ';
else output.textContent += '\n# ' + (player.index - 1) + ' (' + player.name + '): ';
playersjumpdelays[player.index - 1].forEach((d) => {
output.textContent += d + ', ';
});
});
});
/*if (true || printPlayerInfo) {
demo.stringTables.on('update', function(e) {
if (e.table.name !== 'userinfo' || e.userData == null) {
return;
}
var relevantData = {name: e.userData.name, steamId: e.userData.guid};
output.textContent += '\nuser update: ' + e.entryIndex + ' ' + JSON.stringify(relevantData);
});
}*/
/*demo.entities.on('create', e => {
if (e.entity.serverClass.name !== 'CCSPlayer') {
return;
}
if (e.entity.userInfo) {
console.log('%s (%s) joined the game', e.entity.name, e.entity.steamId);
}
});*/
demo.parse(buf);
};
// Read in the image file as a data URL.
reader.readAsArrayBuffer(this.response);
}
};
xhr.send();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment