Last active
January 29, 2017 18:35
-
-
Save Asbra/f654e827632b608997ebb4970f7cef9d to your computer and use it in GitHub Desktop.
UserScript enhancing the HDB in the game Hacker Experience 1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name HE1x.HDB | |
// @namespace https://asbra.net/ | |
// @version 0.5 | |
// @description Search, filter and more improvements for HE1 Hacked Database | |
// @author Asbra | |
// @match http://legacy.hackerexperience.com/list* | |
// @match https://legacy.hackerexperience.com/list* | |
// @updateURL https://gist.github.com/Asbra/f654e827632b608997ebb4970f7cef9d/raw/he1x.hdb.user.js | |
// @run-at document-end | |
// ==/UserScript== | |
(function(){ | |
'use strict'; | |
$ = $ || jQuery; | |
// http://stackoverflow.com/questions/12155512/ | |
function relativeTime(timestamp) { | |
var time_formats = [ | |
[60, 'seconds', 1], // 60 | |
[120, '1 minute ago', '1 minute from now'], // 60*2 | |
[3600, 'minutes', 60], // 60*60, 60 | |
[7200, '1 hour ago', '1 hour from now'], // 60*60*2 | |
[86400, 'hours', 3600], // 60*60*24, 60*60 | |
[172800, 'yesterday', 'tomorrow'], // 60*60*24*2 | |
[604800, 'days', 86400], // 60*60*24*7, 60*60*24 | |
[1209600, 'last week', 'next week'], // 60*60*24*7*4*2 | |
[2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7 | |
[4838400, 'last month', 'next month'], // 60*60*24*7*4*2 | |
[29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4 | |
[58060800, 'last year', 'next year'], // 60*60*24*7*4*12*2 | |
[2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12 | |
[5806080000, 'last century', 'next century'], // 60*60*24*7*4*12*100*2 | |
[58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100 | |
]; | |
var seconds = (new Date() - timestamp) / 1000, | |
token = 'ago', | |
format = time_formats[0]; | |
if (seconds < 0) { | |
seconds = Math.abs(seconds); | |
token = 'from now'; | |
} | |
for (var i = 0; i < time_formats.length; format = time_formats[i++]) { | |
if (!format) { break; } | |
if (seconds < format[0]) { | |
if (typeof format[2] == 'string') { | |
return format[(token == 'ago' ? 1 : 2)]; | |
} else { | |
return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token; | |
} | |
} | |
} | |
return time; | |
} | |
// http://stackoverflow.com/a/15252131 | |
String.prototype.fuzzy = function(s) { | |
var hay = this.toLowerCase(), i = 0, n = -1, l; | |
s = s.toLowerCase(); | |
for (; l = s[i++] ;) { | |
if (!~(n = hay.indexOf(l, n + 1))) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
function create_list_item(slave) { | |
var html = '<li id="'+slave.id+'">'; | |
html += '<div class="span4">'; | |
html += '<div class="list-ip">'; | |
html += '<a href="internet?ip='+slave.ip+'"><span class="label pull-left label-'+(slave.type == 'NPC' ? 'info' : 'success')+'">'+slave.type+'</span><span id="ip">'+slave.ip+'</span></a>'; | |
html += '</div>'; | |
html += '<div class="list-user">'; | |
html += '<span class="he16-user heicon" title="User"></span><span class="small">'+slave.user+'</span>'; | |
html += '<span class="he16-password heicon" title="Password"></span><span class="small">'+slave.pass+'</span>'; | |
html += '</div>'; | |
html += '</div>'; | |
html += '<div class="span4">'; | |
html += '<div class="list-virus">'; | |
html += '<span id="vname">'+slave.virus+'</span>'+(!slave.virus ? 'No running virus' : '')+' </div>'; | |
html += '<div class="list-time">'; | |
html += '<span class="small" id="v-1" title=""></span>'; | |
html += '</div>'; | |
html += '</div>'; | |
html += '<div class="span3">'; | |
html += '<div class="span6">'; | |
html += '<span class="small hide-phone"><span class="he16-net heicon icon-tab nomargin"></span>'+slave.net+'</span><br>'; | |
html += '<span class="small hide-phone"><span class="he16-hdd heicon icon-tab nomargin"></span>'+slave.hdd+'</span>'; | |
html += '</div>'; | |
html += '<div class="span6">'; | |
html += '<span class="small hide-phone"><span class="he16-cpu heicon icon-tab nomargin"></span>'+slave.cpu+'</span><br>'; | |
html += '<span class="small hide-phone"><span class="he16-ram heicon icon-tab nomargin"></span>'+slave.ram+'</span>'; | |
html += '</div>'; | |
html += '</div>'; | |
html += '<div class="span1" style="text-align: right;">'; | |
html += '<div class="list-actions">'; | |
html += '<span class="tip-top delete-ip he16-delete icon-tab link" title="Remove" id="'+slave.id+'"></span>'; | |
html += '</div>'; | |
html += '</div>'; | |
html += '<div style="clear: both;"></div>'; | |
html += '</li>'; | |
return html; | |
} | |
function scan_hdb() { | |
var slaves = []; | |
var max_page = parseInt($('div.pagination > ul > li:last').prev().text()) || 1; | |
var temp = []; | |
var page = 1; | |
var count_vpc = 0, count_npc = 0; | |
for (; page <= max_page; page++) { | |
console.log('grabbing page', page, '/', max_page); | |
$('span#scan-progress').text(Math.floor((page/max_page) * 100)+'%'); | |
var response = $.ajax({ | |
url: 'list?page='+page, | |
async: false | |
}); | |
var timestamp = +new Date() / 1000; | |
if (response.status == 200) { | |
var html = response.responseText; | |
var content = html.match(/<ul class="list ip" id="list">((?:.|\n)*?)<\/ul>/); | |
if (content.length < 2) { console.log(html); console.log(content); continue; } | |
var list = content[1].trim().match(/<li id="(l[0-9]+)">((?:.|\n)*?)<\/li>/g); | |
for (var n = 0; n < list.length; n++) { | |
var parts = []; | |
var slave = {}; | |
slave.page = page; | |
slave.id = parseInt(list[n].match(/delete-ip he16-delete(?:[^"]*)" title="[^"]+" id="([0-9]+)"><\/span>/)[1]); | |
slave.ip = list[n].match(/href="internet\?ip=([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})">/)[1]; | |
slave.type = list[n].match(/">([A-Z]{3})<\/span><span id="ip"/)[1]; | |
slave.user = list[n].match(/"User"><\/span><span class="small">([A-Za-z0-9]+)<\/s/)[1]; | |
slave.pass = list[n].match(/"Password"><\/span><span class="small">(?:<i>)?([A-Za-z0-9]+)(?:<\/i>)?<\/s/)[1]; | |
var match = list[n].match(/id="vname">([^<]+)</); | |
slave.virus = (match && match[1]) || ''; | |
if (slave.virus) { | |
match = list[n].match(/<div class="list-time">(?:(?:.|\n)*?)<span class="small" id="v[0-9]" title="([^"]+)">/); | |
var slave_vtime = (match && match[1]) || null; | |
if (slave_vtime) { | |
var vtime_hours = (slave_vtime.match(/([0-9]+)h/) && parseInt(slave_vtime.match(/([0-9]+)h/)[1])) || 0; | |
var vtime_minutes = (slave_vtime.match(/([0-9]+)m/) && parseInt(slave_vtime.match(/([0-9]+)m/)[1])) || 0; | |
var vtime_seconds = (slave_vtime.match(/([0-9]+)s/) && parseInt(slave_vtime.match(/([0-9]+)s/)[1])) || 0; | |
var vtime_stamp = timestamp; | |
vtime_stamp -= (vtime_hours * 3600); | |
vtime_stamp -= (vtime_minutes * 60); | |
vtime_stamp -= vtime_seconds; | |
slave.vtime = vtime_stamp * 1000; | |
} | |
} else { | |
slave.vtime = 0; | |
} | |
slave.net = list[n].match(/class="he16-net heicon icon-tab nomargin"><\/span>(.+)<\/span/)[1].replace(/(<([^>]+)>)/, ''); | |
slave.hdd = list[n].match(/class="he16-hdd heicon icon-tab nomargin"><\/span>(.+)<\/span/)[1].replace(/(<([^>]+)>)/, ''); | |
slave.cpu = list[n].match(/class="he16-cpu heicon icon-tab nomargin"><\/span>(.+)<\/span/)[1].replace(/(<([^>]+)>)/, ''); | |
slave.ram = list[n].match(/class="he16-ram heicon icon-tab nomargin"><\/span>(.+)<\/span/)[1].replace(/(<([^>]+)>)/, ''); | |
slaves.push(slave); | |
} | |
console.log('scraped page', page, '/', max_page); | |
} else { console.log('HTTP status', response.status); } | |
} | |
localStorage.setItem('hx_slaves', JSON.stringify(slaves)); | |
localStorage.setItem('hx_ts_scan_hdb', +new Date()); | |
alert('Scanned '+page+' pages, found '+slaves.length+' slaves'); | |
if (slaves.length > 15 * max_page) { alert("Hmm.. found more slaves than there should be, something's gone wrong\nPlease try again!"); } | |
$(overlay).remove(); | |
location.reload(); | |
} | |
function filter_hdb() { | |
$('ul.list.ip > li').remove(); | |
$('div.pagination').remove(); | |
var filter_ip = $('input[name=ip]').val().trim(); | |
// var filter_user = $('input[name=user]').val().trim().toLowerCase(); | |
// var filter_pass = $('input[name=pass]').val().trim().toLowerCase(); | |
var filter_virus = $('input[name=virus]').val().trim().toLowerCase(); | |
var filter_net = $('input[name=net]').val().trim().toLowerCase(); | |
var filter_hdd = $('input[name=hdd]').val().trim().toLowerCase(); | |
var filter_cpu = $('input[name=cpu]').val().trim().toLowerCase(); | |
var filter_ram = $('input[name=ram]').val().trim().toLowerCase(); | |
var filter_type = $('select[name=type]').val(); | |
var slaves = JSON.parse(localStorage.getItem('hx_slaves')) || [], | |
parts = []; | |
$(slaves).each(function(i,slave){ | |
if (!slave) { return true; } | |
if ($('input[name=fuzzy]').prop('checked')) { | |
if (filter_ip && slave.ip.indexOf(filter_ip) === -1) { return true; } | |
if (filter_virus && !slave.virus.fuzzy(filter_virus)) { return true; } | |
if (filter_net && !slave.net.fuzzy(filter_net)) { return true; } | |
if (filter_hdd && !slave.hdd.fuzzy(filter_hdd)) { return true; } | |
if (filter_cpu && !slave.cpu.fuzzy(filter_cpu)) { return true; } | |
if (filter_ram && !slave.ram.fuzzy(filter_ram)) { return true; } | |
if (filter_type && slave.type !== filter_type) { return true; } | |
} /* else if ($('input[name=full_text]').prop('checked')) { | |
if (filter_ip && slave.ip.indexOf(filter_ip) === -1) { return true; } | |
// if (filter_user && slave.user.toLowerCase().indexOf(filter_user) === -1) { return true; } | |
// if (filter_pass && slave.pass.toLowerCase().indexOf(filter_pass) === -1) { return true; } | |
if (filter_virus && slave.virus.toLowerCase().indexOf(filter_virus) === -1) { return true; } | |
if (filter_net && slave.net.toLowerCase().indexOf(filter_net) === -1) { return true; } | |
if (filter_hdd && slave.hdd.toLowerCase().indexOf(filter_hdd) === -1) { return true; } | |
if (filter_cpu && slave.cpu.toLowerCase().indexOf(filter_cpu) === -1) { return true; } | |
if (filter_ram && slave.ram.toLowerCase().indexOf(filter_ram) === -1) { return true; } | |
if (filter_type && slave.type !== filter_type) { return true; } | |
} */ else { | |
if (filter_ip && slave.ip.substring(0, filter_ip.length) !== filter_ip) { return true; } | |
if (filter_virus && slave.virus.toLowerCase().substring(0, filter_virus.length) !== filter_virus) { return true; } | |
if (filter_net && slave.net.toLowerCase().substring(0, filter_net.length) !== filter_net) { return true; } | |
if (filter_hdd && slave.hdd.toLowerCase().substring(0, filter_hdd.length) !== filter_hdd) { return true; } | |
if (filter_cpu) { | |
if (slave.cpu.indexOf('~') > -1) { | |
parts = slave.cpu.toLowerCase().split('~'); | |
if (parts[0].substring(0, filter_cpu.length) !== filter_cpu && parts[1].substring(0, filter_cpu.length) !== filter_cpu) { return true; } | |
} else { | |
if (filter_cpu && slave.cpu.toLowerCase().substring(0, filter_cpu.length) !== filter_cpu) { return true; } | |
} | |
} | |
if (filter_ram) { | |
if (slave.ram.indexOf('~') > -1) { | |
parts = slave.ram.toLowerCase().split('~'); | |
if (parts[0].substring(0, filter_ram.length) !== filter_ram && parts[1].substring(0, filter_ram.length) !== filter_ram) { return true; } | |
} else { | |
if (slave.ram.toLowerCase().substring(0, filter_ram.length) !== filter_ram) { return true; } | |
} | |
} | |
if (filter_type && slave.type !== filter_type) { return true; } | |
} | |
$('ul.list.ip').append(create_list_item(slave)); | |
}); | |
} | |
var url = document.location.href.split('/')[3]; | |
var slaves = JSON.parse(localStorage.getItem('hx_slaves')) || []; | |
var updated_slaves = false; | |
// Look for dead IP/virus messages | |
var content = $('.widget-content.padding.noborder > .span12').text(); | |
var i = 0; | |
// Virus Basic Anti-Virus (1.1) isn't responding anymore from IP [32.68.226.247]. | |
var rx_antivirus = /isn't responding anymore from IP \[([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\]/g; | |
var match = rx_antivirus.exec(content); | |
while (match !== null) { | |
if (match[1] !== undefined && match[1]) { | |
for (i = 0; i < slaves.length; i++) { | |
if (slaves[i].ip == match[1]) { | |
slaves[i].virus = ''; | |
slaves[i].vtime = 0; | |
updated_slaves = true; | |
break; | |
} | |
} | |
} | |
match = rx_antivirus.exec(content); | |
} | |
// IP [0.0.0.0] isn't responding anymore. | |
var rx_deadslave = /IP \[([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\] isn't responding anymore/g; | |
match = rx_deadslave.exec(content); | |
while (match !== null) { | |
if (match[1] !== undefined && match[1]) { | |
for (i = 0; i < slaves.length; i++) { | |
if (slaves[i].ip == match[1]) { | |
delete slaves[i]; | |
updated_slaves = true; | |
break; | |
} | |
} | |
} | |
match = rx_deadslave.exec(content); | |
} | |
if (updated_slaves) { | |
slaves = slaves.filter(function(n){ return (n !== undefined && n !== null); }); | |
localStorage.setItem('hx_slaves', JSON.stringify(slaves)); | |
} | |
// Let's go! | |
if (url.indexOf('?action=collect') > -1) { | |
$(slaves).each(function(i,slave){ | |
if (slave.vtime > 0) { | |
slave.vtime = +new Date(); | |
} | |
}); | |
localStorage.setItem('hx_slaves', JSON.stringify(slaves)); | |
} else { | |
var count_vpc = 0, count_npc = 0, count_infected = 0; | |
var viruses = {}, virus_types = {}, longest_collect_time = Number.MAX_SAFE_INTEGER; | |
var timestamp = +new Date(); | |
$(slaves).each(function(i,slave){ | |
if (slave.type == 'VPC') { count_vpc++; } | |
else if (slave.type == 'NPC') { count_npc++; } | |
if (slave.virus) { | |
count_infected++; | |
if (!viruses[slave.virus]) { viruses[slave.virus] = 1; } | |
else { viruses[slave.virus]++; } | |
var vtype = slave.virus.split('.')[1]; | |
if (!virus_types[vtype]) { virus_types[vtype] = 1; } | |
else { virus_types[vtype]++; } | |
} | |
if (slave.vtime && slave.vtime < longest_collect_time) { | |
longest_collect_time = slave.vtime; | |
} | |
}); | |
var top_count = 0, top_virus = ''; | |
var top_count_type = 0, top_virus_type = ''; | |
/* for (var virus in viruses) { | |
if (viruses[virus] > top_count) { | |
top_count = viruses[virus]; | |
top_virus = virus; | |
} | |
} */ | |
for (var vtype in virus_types) { | |
if (virus_types[vtype] > top_count_type) { | |
top_count_type = virus_types[vtype]; | |
top_virus_type = vtype.charAt(1).toUpperCase() + vtype.substring(2); | |
} | |
} | |
var perc_infected = (count_infected / slaves.length) * 100 || 0; | |
// Loading/progress overlay | |
var overlay = document.createElement('div'); | |
overlay.style.cssText = 'z-index:2147483647;position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.5);overflow:hidden;text-align:center;'; | |
var help_text = document.createElement('span'); | |
help_text.style.cssText = 'position:absolute;top:50%;left:50%;margin-left:-80px;'; | |
help_text.innerHTML = '<small style="color:white">Please wait, scanning page <span id="scan-progress">1/?</span> ..<br/><small>Page will be refreshed when done.</small></small>'; | |
overlay.appendChild(help_text); | |
// Add scan button & statistics | |
var html = '<div class="container"><div class="span6">'; | |
var last_scan_time = localStorage.getItem('hx_ts_scan_hdb') || 0, | |
minutes_ago = (last_scan_time ? ((timestamp - last_scan_time) / 1000) / 60 : Number.MAX_SAFE_INTEGER), | |
scan_time_ago = (last_scan_time ? relativeTime(last_scan_time) : '<strong style="color:#f44">too long ago</strong>'); | |
html += '<p><button id="scanhdb" class="btn btn-'+(minutes_ago >= 720 ? 'danger' : (minutes_ago >= 60 ? 'warning' : (minutes_ago >= 30 ? 'primary' : 'default')))+'">Scan HDB</button> '; | |
html += '<small class="small">(last scan was '+(minutes_ago >= 60 ? '<span style="color:#f44">'+scan_time_ago+'</span>' : scan_time_ago)+')</small></p>'; | |
html += '</div>'; | |
html += '<div class="span6">'; | |
html += '<p class="small">'; | |
html += 'Your database contains <strong style="color:#000">'+slaves.length+' slaves</strong>, they are <strong class="type-npc" style="color:#5AA7CD">'+count_npc+' NPC</strong>, <strong class="type-vpc" style="color:#66AA67">'+count_vpc+' VPC</strong>.<br/>'; | |
html += 'Currently <strong style="color:#'+(perc_infected <= 5 ? 'f00' : (perc_infected <= 10 ? 'f90' : (perc_infected <= 30 ? '09f' : '0e0')))+'">'+count_infected+'</strong> slaves are infected'; | |
if (count_infected && top_virus_type) { | |
// html += ', your most running virus is <strong style="color:#AA4647">'+top_virus+'</strong>'; | |
html += ', you\'re mostly running <strong style="color:#DD4647">'+top_virus_type+'</strong> viruses'; | |
} | |
html += '.'; | |
if (count_infected && longest_collect_time < Number.MAX_SAFE_INTEGER) { | |
var collect_ago = relativeTime(longest_collect_time); | |
minutes_ago = (longest_collect_time ? ((timestamp - longest_collect_time) / 1000) / 60 : Number.MAX_SAFE_INTEGER); | |
html += '<br/>The longest running virus hasn\'t been collected since <strong style="color:#'+(minutes_ago >= 1440 ? 'f00' : (minutes_ago >= 720 ? 'f89406' : (minutes_ago >= 60 ? '0a0' : '000')))+'">'+collect_ago+'</strong>.'; | |
} | |
html += '</p></div></div>'; | |
$('.row-fluid > .span12').prepend(html); | |
// Add filters | |
if (url == 'list' || url.substring(0, 10) == 'list?page=' || | |
url == 'list.php' || url.substring(0, 14) == 'list.php?page=') | |
{ | |
html = '<p>'; | |
html += '<select name="type" style="width:70px"><option value="">All</option><option value="VPC">VPC</option><option value="NPC">NPC</option></select> '; | |
html += '<strong style="vertical-align:text-bottom">IP</strong> <input type="text" name="ip" style="width:120px"/> '; | |
html += '<span class="he16-bug heicon icon-tab" style="vertical-align:baseline"></span> <input type="text" name="virus" style="width:120px"/> '; | |
html += '<span class="he16-net heicon icon-tab" style="vertical-align:baseline"></span> <input type="text" name="net" style="width:80px"/> '; | |
html += '<span class="he16-hdd heicon icon-tab" style="vertical-align:baseline"></span> <input type="text" name="hdd" style="width:80px"/> '; | |
html += '<span class="he16-cpu heicon icon-tab" style="vertical-align:baseline"></span> <input type="text" name="cpu" style="width:80px"/> '; | |
html += '<span class="he16-ram heicon icon-tab" style="vertical-align:baseline"></span> <input type="text" name="ram" style="width:80px"/> '; | |
// html += '<span class="he16-user heicon icon-tab" style="vertical-align:baseline"></span> <input type="text" name="user" style="width:80px"/> '; | |
// html += '<span class="he16-password heicon icon-tab" style="vertical-align:baseline"></span> <input type="text" name="pass" style="width:80px"/> '; | |
// html += '<span style="vertical-align:super"><input type="checkbox" name="full_text" style="vertical-align:sub"/> <small style="font-size:.75em">Full text search <strong class="text-warning">(slow)</strong></small></span> '; | |
html += '<span style="vertical-align:super"><input type="checkbox" name="fuzzy" style="vertical-align:sub" checked/> <small style="font-size:.75em">Fuzzy search <strong class="text-warning">(slow)</strong></small></span> '; | |
html += '</p>'; | |
$('.widget-content.padding.noborder > .span12').prepend(html); | |
} | |
$('input[name=ip]').on('keyup', function(evt){ filter_hdb(); }); | |
$('input[name=user]').on('keyup', function(evt){ filter_hdb(); }); | |
$('input[name=pass]').on('keyup', function(evt){ filter_hdb(); }); | |
$('input[name=virus]').on('keyup', function(evt){ filter_hdb(); }); | |
$('input[name=net]').on('keyup', function(evt){ filter_hdb(); }); | |
$('input[name=hdd]').on('keyup', function(evt){ filter_hdb(); }); | |
$('input[name=cpu]').on('keyup', function(evt){ filter_hdb(); }); | |
$('input[name=ram]').on('keyup', function(evt){ filter_hdb(); }); | |
$('select[name=type]').on('change', function(evt){ filter_hdb(); }); | |
// $('input[name=full_text]').on('change', function(evt){ filter_hdb(); }); | |
$('.type-npc').on('click', function(evt){ $('select[name=type]').val('NPC').change(); }); | |
$('.type-vpc').on('click', function(evt){ $('select[name=type]').val('VPC').change(); }); | |
$('button#scanhdb').on('click', function(evt){ | |
evt.preventDefault(); | |
document.body.appendChild(overlay); | |
setTimeout(function(){ scan_hdb(); }, 100); | |
}); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment