Skip to content

Commit 50ea860

Browse files
committedNov 3, 2013
Use a doT.js template for the serverlist
1 parent 68bbdf1 commit 50ea860

File tree

5 files changed

+195
-153
lines changed

5 files changed

+195
-153
lines changed
 

Diff for: ‎util/master/README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Minetest server list
2+
====================
3+
4+
Setting up the webpage
5+
----------------------
6+
You will have to install node.js, doT.js and their dependencies to compile
7+
the serverlist webpage template.
8+
9+
First install node.js, eg:
10+
# apt-get install nodejs
11+
# pacman -S nodejs
12+
# emerge nodejs
13+
14+
Then install doT.js and it's dependencies:
15+
$ cd ~/code
16+
$ git clone https://github.com/olado/doT.git
17+
$ cd doT
18+
$ npm install
19+
20+
And finally compile the template:
21+
$ cd ~/minetest/util/master
22+
$ ~/code/doT/bin/dot-packer -s . -d .
23+
24+

Diff for: ‎util/master/index.html

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
<!DOCTYPE html>
22
<html>
3-
<head>
4-
<meta charset="utf-8">
5-
<title>Minetest server list</title>
6-
<link rel="stylesheet" href="style.css"/>
7-
</head>
8-
<body><div id="servers_table"></div></body>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Minetest server list</title>
6+
<link rel="stylesheet" href="style.css" />
7+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
8+
<script src="servers.js"></script>
9+
<script src="list.js"></script>
10+
</head>
11+
<body>
12+
<div id="server_list"></div>
13+
</body>
914
</html>
10-
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
11-
<script>//var master = {root: 'http://servers.minetest.net/', limit:10, clients_min:1, no_flags:1, no_ping:1, no_uptime:1};</script>
12-
<script src="list.js"></script>
15+

Diff for: ‎util/master/list.js

+70-122
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,80 @@
1-
var master_root, output_to;
21
var master;
3-
if (!master) master = {
4-
root: master_root,
5-
output: output_to
6-
};
2+
if (!master) {
3+
master = {
4+
url: "http://servers.minetest.net/list",
5+
output: "#server_list"
6+
};
7+
}
8+
9+
function humanTime(seconds) {
10+
if (!seconds) return '?';
11+
var conv = {
12+
y: 31536000,
13+
d: 86400,
14+
h: 3600,
15+
m: 60
16+
}
17+
for (var i in conv) {
18+
if (seconds >= conv[i]) {
19+
return (seconds / conv[i]).toFixed(1) + i;
20+
}
21+
}
22+
}
723

8-
function e(s) {
9-
if (typeof s === "undefined") s = '';
10-
if (typeof s === "number") return s;
11-
return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); //mc"
24+
function escapeHTML(str) {
25+
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
1226
}
1327

14-
function human_time(t, abs) {
15-
var n = 's';
16-
if (!t || t < 0) t = 0;
17-
var f = 0;
18-
var s = parseInt(abs ? (t || 0) : (new Date().getTime() / 1000 - (t || 0)));
19-
if (!s || s <= 0) s = 0;
20-
if (s == 0) return 'now';
21-
if (s >= 60) {
22-
s /= 60;
23-
n = 'm';
24-
if (s >= 60) {
25-
s /= 60;
26-
n = 'h';
27-
f = 1;
28-
if (s >= 24) {
29-
s /= 24;
30-
n = 'd';
31-
f = 1;
32-
if (s >= 30) {
33-
s /= 30;
34-
n = 'M';
35-
f = 1;
36-
if (s >= 12) {
37-
s /= 12;
38-
n = 'y';
39-
f = 1;
40-
}
41-
}
42-
}
43-
}
44-
}
45-
return ((f ? parseFloat(s).toFixed(1) : parseInt(s)) + n);
28+
function addressString(server) {
29+
var isIPv6 = server.address.indexOf(":") != -1;
30+
var addrStr = (isIPv6 ? '[' : '') +
31+
escapeHTML(server.address) +
32+
(isIPv6 ? ']' : '');
33+
var shortStr = addrStr;
34+
addrStr += ':' + server.port;
35+
var str = '<span'
36+
if (shortStr.length > 25) {
37+
shortStr = shortStr.substr(0, 23) + "&hellip;";
38+
str += ' class="tooltip" title="' + addrStr + '"'
39+
}
40+
if (server.port != 30000)
41+
shortStr += ':' + server.port;
42+
return str + '>' + shortStr + '</span>';
4643
}
4744

48-
function success(r) {
49-
if (!r || !r.list) return;
50-
var h = '';
51-
if (!master.no_total && r.total && r.total_max)
52-
h += '<div class="mts_total">Players: ' + r.total.clients + ('/' + r.total_max.clients) + ' servers: ' + r.total.servers + ('/' + r.total_max.servers) + '</div>';
53-
h += '<table class="mts_table">';
54-
if (r.list.length) {
55-
h += '<tr class="mts_head">';
56-
if (!master.no_address) h += '<th>ip[:port]</th>';
57-
if (!master.no_clients) h += '<th>players/max</th>';
58-
if (!master.no_version) h += '<th>version gameid mapgen</th>';
59-
if (!master.no_name) h += '<th>name</th>';
60-
if (!master.no_description) h += '<th>description</th>';
61-
if (!master.no_flags) h += '<th>flags</th>';
62-
if (!master.no_uptime) h += '<th>uptime age</th>';
63-
if (!master.no_ping) h += '<th>ping</th>';
64-
h += '</tr>';
65-
}
66-
var count = 0;
67-
for (var i = 0; i < r.list.length; ++i) {
68-
if (++count > master.limit && master.limit) break;
69-
var s = r.list[i];
70-
if (!s) continue;
71-
if (master.clients_min && s.clients < master.clients_min) continue;
72-
if (/:/.test(s.address)) s.address = '[' + s.address + ']';
73-
h += '<tr class="mts_row">';
74-
if (!master.no_address) h += '<td class="mts_address">' + e(s.address) + (s.port != 30000 ? (':' + e(s.port)) : '') + '</td>';
75-
if (!master.no_clients) {
76-
h += '<td class="mts_clients' + (s.clients && s.clients_list ? ' mts_is_clients' : '') + '">';
77-
if (!master.no_clients_list && s.clients && s.clients_list) {
78-
h += '<div class="mts_clients_list">Players (' + e(s.clients) + '):<br/>';
79-
for (var ii in s.clients_list)
80-
h += e(s.clients_list[ii]) + '<br/>';
81-
h += '</div>';
82-
}
83-
h += e(s.clients) + (s.clients_max ? '/' + e(s.clients_max) : '') + (s.clients_top ? ', ' + e(s.clients_top) : '') + '</td>';
84-
}
85-
var mods = 0;
86-
if (s.mods && jQuery.isArray(s.mods))
87-
mods = s.mods.length;
88-
if (!master.no_version) {
89-
h += '<td class="mts_version' + (mods ? ' mts_is_mods' : '') + '">' + e(s.version) + ' ' + e(s.gameid) + ' ' + e(s.mapgen);
90-
if (!master.no_mods && mods) {
91-
h += '<div class="mts_mods">Mods (' + mods + '):<br/>';
92-
for (var ii in s.mods)
93-
h += e(s.mods[ii]) + '<br/>';
94-
h += '</div>';
95-
}
96-
h += '</td>';
97-
}
98-
if (!master.no_name) {
99-
h += '<td class="mts_url">';
100-
if (s.url) h += '<a href="' + e(s.url) + '">';
101-
h += e(s.name || s.url);
102-
if (s.url) h += '</a>';
103-
h += '</td>';
104-
}
105-
if (!master.no_description) h += '<td class="mts_description">' + e(s.description) + '</td>';
106-
if (!master.no_flags) {
107-
h += '<td class="mts_flags">' +
108-
(s.password ? 'Pwd ' : '') +
109-
(s.creative ? 'Cre ' : '') +
110-
(s.damage ? 'Dmg ' : '') +
111-
(s.pvp ? 'Pvp ' : '') +
112-
(s.dedicated ? 'Ded ' : '') +
113-
(s.rollback ? 'Rol ' : '') +
114-
(s.liquid_finite ? 'Liq ' : '') +
115-
'</td>';
116-
}
117-
if (!s.start || s.start < 0) s.start = 0;
118-
if (!master.no_uptime) h += '<td class="mts_uptime">' + (s.uptime ? human_time(s.uptime, 1) : s.start ? human_time(s.start) : '') + (s.game_time ? ' ' + human_time(s.game_time, 1) : '') + '</td>';
119-
if (!master.no_ping) h += '<td class="mts_ping">' + (s.ping ? parseFloat(s.ping).toFixed(3) * 1000 : '') + '</td>';
120-
h += '</tr>';
121-
}
122-
h += '</table>';
123-
if (master.clients_min || master.limit)
124-
h += '<a href="#" onclick="delete master.limit;delete master.clients_min; get(1);">more...</a>';
125-
jQuery(master.output || '#servers_table').html(h);
45+
function tooltipString(str, maxLen) {
46+
str = escapeHTML(str);
47+
var shortStr = str;
48+
var ret = '<span';
49+
if (shortStr.length > maxLen) {
50+
shortStr = shortStr.substr(0, maxLen - 2) + "&hellip;";
51+
ret += ' class="tooltip" title="' + str + '"';
52+
}
53+
return ret + '>' + shortStr + '</span>';
12654
}
12755

128-
function get(refresh) {
129-
jQuery.getJSON((master.root || '') + 'list', success);
130-
if (!refresh && !master.no_refresh) setTimeout(get, 60000);
56+
function hoverList(name, list) {
57+
if (!list || list.length == 0) return '';
58+
var str = '<div class="hover_list">'
59+
str += name + '(' + list.length + ')<br />';
60+
for (var i in list) {
61+
str += escapeHTML(list[i]) + '<br />';
62+
}
63+
return str + '</div>';
13164
}
65+
66+
function draw(json) {
67+
html = window.render.servers(json);
68+
jQuery(master.output || '#server_list').html(html);
69+
}
70+
71+
function get() {
72+
jQuery.getJSON(master.url, draw);
73+
}
74+
75+
if (!master.no_refresh) {
76+
setInterval(get, 60 * 1000);
77+
}
78+
13279
get();
80+

Diff for: ‎util/master/servers.jst

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{{? !master.no_total}}
2+
<div class="total">
3+
Players: {{=it.total.clients}}/{{=it.total_max.clients}}&nbsp;
4+
Servers: {{=it.total.servers}}/{{=it.total_max.servers}}
5+
</div>
6+
{{?}}
7+
<table>
8+
<tr>
9+
{{? !master.no_address}}<th>IP[:Port]</th>{{?}}
10+
{{? !master.no_clients}}<th>Players/Max</th>{{?}}
11+
{{? !master.no_version}}<th>Version, Gameid, MapGen</th>{{?}}
12+
{{? !master.no_name}}<th>Name</th>{{?}}
13+
{{? !master.no_description}}<th>Description</th>{{?}}
14+
{{? !master.no_flags}}<th>Flags</th>{{?}}
15+
{{? !master.no_uptime}}<th>Uptime, Age</th>{{?}}
16+
{{? !master.no_ping}}<th>Ping</th>{{?}}
17+
</tr>
18+
{{~it.list :server:index}}
19+
{{ if (master.limit && index + 1 > master.limit) break;}}
20+
<tr>
21+
{{? !master.no_address}}
22+
<td class ="address">
23+
{{=addressString(server)}}
24+
</td>{{?}}
25+
{{? !master.no_clients}}
26+
<td class="clients{{? server.clients_list && server.clients_list.length > 0}} hover_list_text{{?}}">
27+
{{=server.clients}}/{{=server.clients_max}} {{=server.clients_top}}
28+
{{=hoverList("Clients", server.clients_list)}}
29+
</td>{{?}}
30+
{{? !master.no_version}}
31+
<td class="version{{? server.mods && server.mods.length > 0}} hover_list_text{{?}}">
32+
{{=escapeHTML(server.version)}}, {{=escapeHTML(server.gameid)}},&nbsp;
33+
{{=escapeHTML(server.mapgen || '?')}}
34+
{{=hoverList("Mods", server.mods)}}
35+
</td>{{?}}
36+
{{? !master.no_name}}
37+
<td class="name">
38+
{{? server.url}}
39+
<a href="{{=escapeHTML(server.url)}}">{{=tooltipString(server.name, 25)}}</a>
40+
{{??}}
41+
{{=tooltipString(server.name, 25)}}
42+
{{?}}
43+
</td>{{?}}
44+
{{? !master.no_description}}
45+
<td class="description">
46+
{{=tooltipString(server.description, 50)}}
47+
</td>{{?}}
48+
{{? !master.no_flags}}
49+
<td class="flags">
50+
{{=server.creative ? 'Cre ' : ''}}
51+
{{=server.dedicated ? 'Ded ' : ''}}
52+
{{=server.damage ? 'Dmg ' : ''}}
53+
{{=server.liquid_finite ? 'Liq ' : ''}}
54+
{{=server.pvp ? 'PvP ' : ''}}
55+
{{=server.password ? 'Pwd ' : ''}}
56+
{{=server.rollback ? 'Rol ' : ''}}
57+
</td>{{?}}
58+
{{? !master.no_uptime}}
59+
<td class="uptime">
60+
{{=humanTime(server.uptime)}}, {{=humanTime(server.game_time)}}
61+
</td>{{?}}
62+
{{? !master.no_ping}}
63+
<td class="ping">
64+
{{=Math.floor(server.ping * 1000)}}
65+
</td>{{?}}
66+
</tr>
67+
{{~}}
68+
</table>

Diff for: ‎util/master/style.css

+21-22
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
1-
table {
2-
max-width: 100%;
3-
background-color: transparent;
4-
border-collapse: collapse;
5-
border-spacing: 0;
1+
#server_list table {
2+
max-width: 100%;
3+
width: 100%;
4+
background-color: transparent;
5+
border-collapse: collapse;
6+
border-spacing: 0;
7+
font-size: small;
68
}
79

8-
td, th {
9-
border: 1px solid gray;
10+
#server_list td, #server_list th {
11+
border: 1px solid gray;
1012
}
1113

12-
div#table table {
13-
width: 100%;
14+
.hover_list{
15+
visibility: hidden;
16+
border: gray solid 1px;
17+
position: absolute;
18+
z-index: 100;
19+
background-color: white;
20+
padding: 0.5em;
1421
}
1522

16-
.mts_mods, .mts_clients_list {
17-
visibility: hidden;
18-
border:gray solid 1px;
19-
position:absolute;
20-
z-index:100;
21-
background-color:white;
22-
padding:.5em;
23+
td:hover .hover_list {
24+
visibility: visible;
2325
}
2426

25-
.mts_version:hover .mts_mods, .mts_clients:hover .mts_clients_list {
26-
visibility: visible;
27+
.hover_list_text, .tooltip {
28+
text-decoration: underline;
29+
text-decoration-style: dashed;
2730
}
2831

29-
.mts_version.mts_is_mods, .mts_clients.mts_is_clients {
30-
text-decoration:underline;
31-
text-decoration-style:dashed;
32-
}

0 commit comments

Comments
 (0)
Please sign in to comment.