mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-07-12 17:42:19 +01:00
421 lines
16 KiB
HTML
421 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Ban Panel</title>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
<link rel="stylesheet" type="text/css" href="{{resource("css/font-awesome.css")}}">
|
|
<link rel="stylesheet" type="text/css" href="{{resource("css/style.css")}}">
|
|
<style type="text/css">
|
|
body {font-size: 8pt; font-family: Arial; padding-top: 30px;}
|
|
a {color: green; text-decoration: none;}
|
|
a:hover, a:visited {color: #076307;}
|
|
.header {height: 30px; padding: 0 10px; position: fixed; top: 0; left: 0; right: 0; background: #ddd; font-size: 1.1em; border-bottom: 1px solid #ccc;}
|
|
.header strong {float: left; line-height: 30px;}
|
|
.header form {float: right;}
|
|
.header .text {float: left; border: 0; width: 150px; height: 20px; line-height: 20px; margin: 5px 0 0 0; padding: 0 5px; font-size: 0.9em; border-bottom: 1px solid #ccc; border-right: 1px solid #aaa;}
|
|
.header form select {float: left; width: 60px; height: 21px; line-height: 20px; margin: 5px 0 0 5px; font-size: 0.9em; border: 0; border-bottom: 1px solid #ccc; border-right: 1px solid #aaa;}
|
|
.header .search {float: left; border: 0; margin: 5px 0 0 5px; height: 20px; line-height: 20px; padding: 0 5px; background: #076307; color: #eee; font-size: 0.8em; vertical-align: middle;}
|
|
.header .search:hover {background: green; cursor: pointer;}
|
|
.header .searchInfo {float: left; line-height: 30px; margin: 0 5px; font-size: 0.9em;}
|
|
.header .refresh {float: left; text-decoration: none; margin: 0 10px 0 -10px; padding: 0 10px; background: #ccc; font-size: 0.8em; color: green; display: inline-block; height: 30px; line-height: 30px; vertical-align: middle;}
|
|
.header .addNew {float: right; text-decoration: none; margin: 0 -10px 0 10px; padding: 0 10px; background: #ccc; font-size: 0.8em; color: green; display: inline-block; height: 30px; line-height: 30px; vertical-align: middle;}
|
|
.header .refresh:hover, .header .addNew:hover {background: #bbb;}
|
|
|
|
table {width: 100%;}
|
|
td {padding: 6px 5px; border-bottom: 1px solid #ededed;}
|
|
table thead {background: #eee;}
|
|
table thead th {padding: 5px 0; border-bottom: 1px solid #ccc;}
|
|
th.blank {color: #eee;}
|
|
th .sortBy i {margin-left: 5px;}
|
|
td.full {padding: 10px;}
|
|
td.actions {width: 70px;}
|
|
td.actions a {display: inline-block; padding: 2px; text-align: center;}
|
|
td.actions i {font-size: 1.3em;}
|
|
td.actions a:hover {background: #ccc;}
|
|
td.ckey {width: 90px; word-break: break-all;}
|
|
td.time {width: 60px;}
|
|
td.akey {width: 80px; word-break: break-all;}
|
|
td.reason {line-height: 1.4;}
|
|
td.compID {width: 60px;}
|
|
td.ip {width: 70px;}
|
|
|
|
.pagination {float: left; padding: 0 0 0 30px; list-style-type: none; text-align: center; margin: 0; height: 30px;}
|
|
.pagination li {float: left; line-height: 30px;}
|
|
.pagination a {text-decoration: none; display: inline-block; padding: 5px 7px; line-height: 20px;}
|
|
.pagination a:hover {background: #ccc;}
|
|
.pagination .current {background: #ccc;}
|
|
|
|
.switchRemoved {display: block; position: fixed; bottom: 0; right: 170px; padding: 8px; background: #ddd; border-top: 1px solid #bbb; border-left: 1px solid #ccc; border-right: 1px solid #ccc;}
|
|
.switchRemoved:hover {background: #ccc;}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<a href="" data-start="0" class="refresh" title="Refresh"><i class="icon-refresh icon-large"></i></a>
|
|
<strong><span class="results">0 total bans</span> | <span class="sortedBy">By id desc</span></strong>
|
|
<ul class="pagination"></ul>
|
|
<a href="" class="addNew" title="Add New Ban"><i class="icon-plus icon-large"></i></a>
|
|
<form method="GET" action="">
|
|
<span class="searchInfo"></span>
|
|
<input type="text" class="text" />
|
|
<select>
|
|
<option value="all" selected="selected">All</option>
|
|
<option value="ckey">Key</option>
|
|
<option value="akey">Admin</option>
|
|
<option value="reason">Reason</option>
|
|
<option value="compID">CompID</option>
|
|
<option value="ip">IP</option>
|
|
</select>
|
|
<input type="submit" value="Search" class="search" />
|
|
</form>
|
|
</div>
|
|
|
|
<table border=0 cellspacing=0 cellpadding=0 id="bansTable">
|
|
<thead>
|
|
<tr>
|
|
<th class="blank">Actions</th>
|
|
<th><a href="" class="sortBy" data-value="ckey">Key</a></th>
|
|
<th>Time</th>
|
|
<th><a href="" class="sortBy" data-value="akey">Admin</a></th>
|
|
<th><a href="" class="sortBy" data-value="reason">Reason</a></th>
|
|
<th><a href="" class="sortBy" data-value="compID">Comp ID</a></th>
|
|
<th><a href="" class="sortBy" data-value="ip">IP</a></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td colspan="7" class="full">Loading bans...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<a href="" class="switchRemoved" title="Switch the view to show removed bans">Removed Bans View</a>
|
|
|
|
<script type="text/javascript" src="{{resource("js/jquery.min.js")}}"></script>
|
|
<script type="text/javascript" language="JavaScript">
|
|
var ref_src = null /* ref_src */;
|
|
var CMinutes = null /* cminutes */;
|
|
var windowName = null /* window_name */;
|
|
var apiKey = null /* api_key */;
|
|
var totalBans = 0;
|
|
var pageLimit = 100; //How many rows per page
|
|
var viewRemoved = 0;
|
|
var searchValues = {
|
|
'term': '',
|
|
'column': 'all',
|
|
'offset': 0,
|
|
'sort': 'id',
|
|
'order': 'desc'
|
|
};
|
|
|
|
function urldecode(str) {
|
|
return decodeURIComponent((str+'').replace(/\+/g, '%20'));
|
|
}
|
|
function htmlEncode(value) {
|
|
return $('<div/>').text(value).html();
|
|
}
|
|
function urlEncodeParams(data) {
|
|
var string = '';
|
|
$.each(data, function(key, val) {
|
|
string += '&'+key+'='+encodeURIComponent(val);
|
|
});
|
|
return string;
|
|
}
|
|
|
|
function ehjaxCallback (data) {
|
|
var parsed = $.parseJSON(data);
|
|
if (parsed.cminutes) {
|
|
CMinutes = parseInt(parsed.cminutes);
|
|
delete parsed.cminutes;
|
|
}
|
|
if (parsed.callback) {
|
|
var callback = parsed.callback;
|
|
delete parsed.callback;
|
|
window[callback](2, parsed);
|
|
}
|
|
}
|
|
|
|
function getExpiry (minutes) {
|
|
minutes = parseInt(minutes);
|
|
var exp = minutes - CMinutes;
|
|
if (minutes === 0)
|
|
return 'Permanent';
|
|
else {
|
|
var timeleftstring;
|
|
if (exp >= 1440) { //1440 = 1 day in minutes
|
|
exp = Math.round((exp / 1440) * 10) / 10;
|
|
timeleftstring = exp+' Day'+(exp > 1 || exp < -1 ? 's' : '');
|
|
}
|
|
else if (exp >= 60) { //60 = 1 hour in minutes
|
|
exp = Math.round((exp / 60) * 10) / 10;
|
|
timeleftstring = exp+' Hour'+(exp > 1 || exp < -1 ? 's' : '');
|
|
}
|
|
else
|
|
timeleftstring = exp+' Minute'+(exp > 1 || exp < -1 ? 's' : '');
|
|
return timeleftstring;
|
|
}
|
|
}
|
|
|
|
function parseRow (row, hideChain) {
|
|
if (typeof(hideChain) === 'undefined') hideChain = 0;
|
|
|
|
var html =
|
|
'<tr>'+
|
|
'<td class="actions">';
|
|
|
|
if (!viewRemoved) {
|
|
html += '<a href="?src='+ref_src+'&action=unbane'+urlEncodeParams({id: row.id, target: row.ckey, compID: row.compID, ip: row.ip, reason: row.reason, timestamp: row.timestamp})+'" title="Edit"><i class="icon-edit"></i></a>'+
|
|
'<a href="?src='+ref_src+'&action=unbanf'+urlEncodeParams({id: row.id, target: row.ckey, compID: row.compID, ip: row.ip})+'" title="Unban"><i class="icon-trash"></i></a>';
|
|
}
|
|
|
|
html += '<a href="?src='+ref_src+'&action=notes'+urlEncodeParams({target: row.ckey})+'" title="Notes"><i class="icon-comments-alt"></i></a>'+
|
|
'</td>'+
|
|
'<td class="ckey">'+
|
|
'<a href="'+row.ckey+'" class="searchFor">'+row.ckey+'</a>'+
|
|
'</td>'+
|
|
'<td class="time">'+getExpiry(row.timestamp)+'</td>'+
|
|
'<td class="akey">'+
|
|
(row.oakey == 'N/A' || row.akey == 'Auto Banner' ? '<a href="'+row.akey+'" class="searchFor">'+row.akey+'</a>' : '<a href="'+row.oakey+'" class="searchFor">'+row.oakey+'</a>')+
|
|
(row.oakey != row.akey && row.oakey != 'N/A' ? (row.akey == 'Auto Banner' ? '<br /><small>Original: <a href="'+row.oakey+'" class="searchFor">'+row.oakey+'</a></small>': '<br /><small>Edited by: <a href="'+row.akey+'" class="searchFor">'+row.akey+'</a></small>') : '')+
|
|
(hideChain ? '' : (parseInt(row.previous) > 0 ? '<br /><small><a href="'+row.previous+'" class="previous" data-previous="'+row.previous+'">(Show chain)</a></small>' : '') )+
|
|
'</td>'+
|
|
'<td class="reason">'+(parseInt(row.chain) > 0 ? '[Evasion Attempt x'+row.chain+'] Previous Reason: ' : '') + row.reason +'</td>'+
|
|
'<td class="compID"><a href="'+row.compID+'" class="searchFor">'+row.compID+'</a></td>'+
|
|
'<td class="ip"><a href="'+row.ip+'" class="searchFor">'+row.ip+'</a></td>'+
|
|
'</tr>';
|
|
return html;
|
|
}
|
|
|
|
function buildPagination (total, start) {
|
|
var pages = Math.ceil(total / pageLimit);
|
|
var pagination = '';
|
|
for (var i = 1; i <= pages; i++) {
|
|
var elStart = (i - 1) * pageLimit;
|
|
var className = '';
|
|
if (elStart == parseInt(start)) {
|
|
className += 'current';
|
|
}
|
|
var html = '<li><a href="" data-start="'+elStart+'" class="'+className+'">'+i+'</a></li>';
|
|
pagination += html;
|
|
}
|
|
return pagination;
|
|
}
|
|
|
|
function updateBans (step, data) {
|
|
if (step === 1) {
|
|
data = (data ? data : {});
|
|
var term = (data.term ? data.term : '');
|
|
var column = (data.column ? data.column : 'all');
|
|
var offset = (data.offset ? data.offset : 0);
|
|
var sort = (data.sort ? data.sort : 'id');
|
|
var order = (data.order ? data.order : 'desc');
|
|
|
|
//Assign to globals
|
|
searchValues = {
|
|
'term': term,
|
|
'column': column,
|
|
'offset': offset,
|
|
'sort': sort,
|
|
'order': order
|
|
};
|
|
|
|
$('#bansTable tbody').html('<tr><td colspan="7" class="full">Loading bans...</td></tr>');
|
|
window.scrollTo(0, 0);
|
|
|
|
if (apiKey) {
|
|
if (window.XMLHtpRequest) {
|
|
xmlHttp = new XMLHttpRequest();
|
|
} else {
|
|
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
|
|
}
|
|
|
|
xmlHttp.open('GET', 'http://goonhub.com/ss13/bans/get?search['+column+']='+term+'&sort='+sort+'&order='+order+'&offset='+offset+'&limit='+pageLimit+'&removed='+viewRemoved+'&bypass=1&forcejson=1&auth='+apiKey+'&t='+Math.random(), false);
|
|
xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
|
xmlHttp.send();
|
|
var bansData = xmlHttp.responseText;
|
|
try {
|
|
bansData = $.parseJSON(bansData);
|
|
} catch(err) {
|
|
$('#bansTable tbody').html('<tr><td colspan="7" class="full">JSON is invalid: '+err+'<br/>'+xmlHttp.responseText+'</td></tr>');
|
|
return;
|
|
}
|
|
window.location = '?action=ehjax&window='+windowName+'&proc=getWorldMins'; //Update the cminutes var
|
|
updateBans(2, bansData);
|
|
} else { //Local bans db lookup
|
|
window.location = '?action=ehjax&window='+windowName+'&proc=getBanApiFallback¶m[searchCol]='+column+'¶m[search]='+term+'¶m[sort]='+sort+'¶m[order]='+order+'¶m[offset]='+offset+'¶m[limit]='+pageLimit+'¶m[removed]='+viewRemoved;
|
|
}
|
|
}
|
|
|
|
if (step === 2) {
|
|
var totalBans = data.total;
|
|
delete data.total;
|
|
var term = searchValues.term;
|
|
var column = searchValues.column;
|
|
var offset = searchValues.offset;
|
|
var sort = searchValues.sort;
|
|
var order = searchValues.order;
|
|
|
|
//Shove all our results in the table
|
|
var html = '';
|
|
$.each(data, function(id, row) {
|
|
html += parseRow(row, 0);
|
|
});
|
|
$('#bansTable tbody').html(html);
|
|
$('.header .results').text(totalBans+' total bans');
|
|
|
|
//Update the pagination
|
|
var paginationEl = $('.pagination');
|
|
var pagination = buildPagination(totalBans, offset);
|
|
if (pagination != paginationEl.html()) {
|
|
paginationEl.html(pagination);
|
|
}
|
|
|
|
var sortedHtml = 'By '+sort+' '+order;
|
|
if (sort != 'id') {
|
|
sortedHtml += ' <a href=""><i class="icon-remove"></i></a>';
|
|
}
|
|
$('.header .sortedBy').html(sortedHtml);
|
|
|
|
$('.header .searchInfo').html((term.length > 0 ? 'Searching for '+term+' '+(column ? 'in '+column+' ' : '')+'<a href="" data-start="0"><i class="icon-remove"></i> Cancel</a>' : ''));
|
|
}
|
|
}
|
|
|
|
function getPreviousBans(id) { //This is annoying enough to be in it's own mostly copy and pasted function
|
|
if (typeof(id) === 'undefined') id = '1';
|
|
|
|
$('#bansTable tbody').html('<tr><td colspan="7" class="full">Loading bans...</td></tr>');
|
|
window.scrollTo(0, 0);
|
|
|
|
if (window.XMLHtpRequest) {
|
|
xmlHttp = new XMLHttpRequest();
|
|
} else {
|
|
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
|
|
}
|
|
|
|
xmlHttp.open('GET', 'http://goonhub.com/ss13/bans/getPrevious?id='+id+'&forcejson=1&bypass=1&auth='+apiKey+'&t='+Math.random(), false);
|
|
xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
|
xmlHttp.send();
|
|
var bansData = htmlEncode(xmlHttp.responseText);
|
|
try {
|
|
bansData = $.parseJSON(bansData);
|
|
} catch(err) {
|
|
$('#bansTable tbody').html('<tr><td colspan="7" class="full">JSON is invalid: '+err+'</td></tr>');
|
|
return;
|
|
}
|
|
window.location = '?action=ehjax&window='+windowName+'&proc=getWorldMins'; //Update the cminutes var
|
|
|
|
totalBans = bansData.total;
|
|
delete bansData.total;
|
|
|
|
//Shove all our results in the table
|
|
var html = '';
|
|
$.each(bansData, function(id, row) {
|
|
html += parseRow(row, 1);
|
|
});
|
|
$('#bansTable tbody').html(html);
|
|
$('.header .results').text(totalBans+' total bans');
|
|
$('.pagination').html(''); //Remove pagination because fuck it I'm not doing this for this too
|
|
$('.header .searchInfo').html('Searching for previous bans of ID: '+id+' <a href="" data-start="0"> <i class="icon-remove"></i> Cancel</a>');
|
|
}
|
|
|
|
function searchBans (term, column) {
|
|
term = term.replace(/^\s+|\s+$/gm,'');
|
|
if (term.length <= 2) {
|
|
$('.header .searchInfo').html('3 characters minimum');
|
|
return;
|
|
}
|
|
searchValues.term = term;
|
|
if (!column || column.length < 1) {
|
|
column = 'all';
|
|
}
|
|
searchValues.column = column;
|
|
$('.header form .text').val(term);
|
|
searchValues.offset = 0;
|
|
updateBans(1, searchValues);
|
|
}
|
|
|
|
$(function() {
|
|
updateBans(1); //Initial load
|
|
|
|
//Events!
|
|
$('body').on('click', '.pagination a, .header a.refresh', function(e) {
|
|
e.preventDefault();
|
|
searchValues.offset = $(this).attr('data-start');
|
|
updateBans(1, searchValues);
|
|
});
|
|
|
|
$('body').on('click', '.searchInfo a', function(e) {
|
|
e.preventDefault();
|
|
searchValues.term = '';
|
|
searchValues.offset = $(this).attr('data-start');
|
|
$('.header form select').val('all');
|
|
updateBans(1, searchValues);
|
|
});
|
|
|
|
$('body').on('click', '.sortedBy a', function(e) {
|
|
e.preventDefault();
|
|
searchValues.sort = 'id';
|
|
searchValues.order = 'desc';
|
|
$('#bansTable a.sortBy').each(function(key, el) {
|
|
$(el).find('i').remove();
|
|
});
|
|
updateBans(1, searchValues);
|
|
});
|
|
|
|
$('.header form').submit(function(e) {
|
|
e.preventDefault();
|
|
var term = $(this).children('input').val();
|
|
var column = $(this).children('select').val();
|
|
searchBans(term, column);
|
|
});
|
|
|
|
$('#bansTable').on('click', 'a.searchFor', function(e) {
|
|
e.preventDefault();
|
|
var column = $(this).parent().attr('class');
|
|
column = (column ? column : 'all');
|
|
searchBans($(this).text(), column);
|
|
});
|
|
|
|
$('#bansTable').on('click', 'a.sortBy', function(e) {
|
|
e.preventDefault();
|
|
var sort = $(this).attr('data-value');
|
|
if (searchValues.sort == sort) {
|
|
searchValues.order = (searchValues.order == 'asc' ? 'desc' : 'asc');
|
|
} else {
|
|
searchValues.sort = sort;
|
|
searchValues.order = 'desc';
|
|
}
|
|
$('#bansTable a.sortBy').each(function(key, el) {
|
|
$(el).find('i').remove();
|
|
});
|
|
var iconClass = (searchValues.order == 'asc' ? 'icon-caret-up' : 'icon-caret-down');
|
|
$(this).append('<i class="'+iconClass+'"></i>');
|
|
updateBans(1, searchValues);
|
|
});
|
|
|
|
$('body').on('click', '#bansTable a.previous', function(e) {
|
|
e.preventDefault();
|
|
getPreviousBans($(this).attr('data-previous'));
|
|
});
|
|
|
|
$('.header .addNew').attr('href', '?src='+ref_src+';action=addban');
|
|
|
|
$('.switchRemoved').click(function(e) {
|
|
e.preventDefault();
|
|
searchValues.term = '';
|
|
searchValues.sort = 'id';
|
|
searchValues.order = 'desc';
|
|
$('.header form select').val('all');
|
|
if (viewRemoved) {
|
|
$(this).text('Removed Bans View');
|
|
viewRemoved = 0;
|
|
} else {
|
|
$(this).text('Current Bans View');
|
|
viewRemoved = 1;
|
|
}
|
|
updateBans(1, searchValues);
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |