diff --git a/src/scoreboard b/src/scoreboard index 817384c..dab44c8 100755 --- a/src/scoreboard +++ b/src/scoreboard @@ -1,30 +1,61 @@ #! /usr/bin/awk -f -function output() { +function qsort(A, left, right, i, last) { + if (left >= right) + return + swap(A, left, left+int((right-left+1)*rand())) + last = left + for (i = left+1; i <= right; i++) + if (A[i] < A[left]) + swap(A, ++last, i) + swap(A, left, last) + qsort(A, left, last-1) + qsort(A, last+1, right) +} +function swap(A, i, j, t) { + t = A[i]; A[i] = A[j]; A[j] = t +} + +function escape(s) { + gsub("&", "&", s) + gsub("<", "<", s) + gsub(">", ">", s) + return s +} + +function output( t, c) { for (t in teams) { score = 0; for (c in points_by_cat) { - score += points_by_cat_team[c, t] / points_by_cat[c]; + if (points_by_cat[c] > 0) { + score += points_by_cat_team[c, t] / points_by_cat[c]; + } } if (score > maxscore) { maxscore = score } + if (score > maxscores_by_team[t]) { + maxscores_by_team[t] = score + } scores_by_team_time[t, lasttime] = score } timestamps[tslen++] = lasttime } BEGIN { - # High-contrast colors for accessibility - colors[0] = "e41a1c" - colors[1] = "377eb8" - colors[2] = "4daf4a" - colors[3] = "984ea3" - colors[4] = "ff7f00" - colors[5] = "ffff33" - colors[6] = "a65628" - colors[7] = "f781bf" - + # It took me like 7 hours to find a color palette that worked for + # people with protanopia. Don't change these colors. + colors[0] = "33cc33" + colors[1] = "863a3a" + colors[2] = "5c5ce6" + colors[3] = "bfbf4d" + colors[4] = "408080" + colors[5] = "b336b2" + colors[6] = "ffa500" + colors[7] = "00bfff" + colors[8] = "8db6cd" + ncolors = 9 + # Every 2.5 minutes interval = 150 tslen = 0 @@ -52,34 +83,138 @@ BEGIN { output() + # Get team colors and names + for (team in teams) { + fn = "/var/lib/ctf/teams/colors/" team ".color" + getline colors_by_team[team] < fn + close(fn) + + fn = "/var/lib/ctf/teams/" team + getline names_by_team[team] < fn + close(fn) + } + + # Get team names + width = lasttime - start print "" print "" print " " print " foo" - print " " - print " " + print " " + print " " print " " + print " " print " " print " " - print " " + print "

Scoreboard

" + print " " + print " " + + # Sort categories + ncats = 0 + for (cat in points_by_cat) { + cats[ncats++] = cat + } + qsort(cats, 0, ncats-1) + + # Print out category names + for (i = 0; i < ncats; i += 1) { + cat = cats[i] + points = points_by_cat[cat] + if (0 == points) continue + printf("\n", cat, points) + } + print " " + + print " " + print " " + for (i = 0; i < ncats; i += 1) { + cat = cats[i] + points = points_by_cat[cat] + if (0 == points) break; + + print "" + } + print " " + print "
Overall%s (%d)
" + print "
    " + + # Create a sorted list of scores + nteams = 0 + for (team in teams) { + scores[nteams++] = scores_by_team_time[team, lasttime] + } + qsort(scores, 0, nteams-1) + + # Print out teams, ranked by score + bottom = nteams - 10 + if (bottom < 0) bottom = 0 + for (i = nteams-1; i >= bottom; i -= 1) { + if (scores[i] == scores[i-1]) continue; + for (team in teams) { + if (scores[i] == scores_by_team_time[team, lasttime]) { + name = names_by_team[team] + printf("
  1. %s (%.2f)
  2. \n", + team, escape(name), scores[i]) + } + } + } + print "
" + print "
" + + # Create sorted list of scores in this category + n = 0 + for (team in teams) { + l[n++] = points_by_cat_team[cat, team]; + } + qsort(l, 0, n) + + # Print out teams, ranked by points + for (j = n; j > 0; j -= 1) { + if (l[j] == l[j-1]) continue; + if (0 == l[j]) break; + for (team in teams) { + points = points_by_cat_team[cat, team] + if (l[j] == points) { + name = names_by_team[team] + printf("
\n", + team, + 100 * points / points_by_cat[cat], + colors_by_team[team]) + printf(" %s: %d\n", + cat, escape(name), points) + printf("
\n") + } + } + } + + print "
" + + + print " " print " " print "" } diff --git a/www/plot.js b/www/plot.js index e62ec60..bda72a9 100644 --- a/www/plot.js +++ b/www/plot.js @@ -1,42 +1,66 @@ -function Plot(id, width, height) { +function dbg(o) { + e = document.getElementById("debug"); + e.innerHTML = o; +} + +function torgba(color, alpha) { + var r = parseInt(color.substring(1,3), 16); + var g = parseInt(color.substring(3,5), 16); + var b = parseInt(color.substring(5,7), 16); + + return "rgba(" + r + "," + g + "," + b + "," + alpha + ")"; +} + +function plot(id, width, height, lines) { var canvas = document.getElementById(id); var ctx = canvas.getContext('2d'); - canvas.width = 800; - canvas.height = 200; - // We'll let the canvas do all the tricksy math - xscale = canvas.width/width; - yscale = canvas.height/height; - ctx.lineWidth = 2; + var xscale = canvas.width/width; + var yscale = canvas.height/height; + var nlines = lines.length; function moveTo(x, y) { - ctx.moveTo(Math.round(x * xscale), Math.round(y * yscale)); + ctx.moveTo(Math.round(x * xscale), Math.round((height - y) * yscale)); } function lineTo(x, y) { - ctx.lineTo(Math.round(x * xscale), Math.round(y * yscale)); + ctx.lineTo(Math.round(x * xscale), Math.round((height - y) * yscale)); } - function draw(values) { - ctx.beginPath(); - moveTo(values[0][0], height); + function draw(line) { + var color = line[0]; + var values = line[1]; var lasty = 0; + + ctx.strokeStyle = torgba(color, 0.99); + ctx.lineWidth = 2; + ctx.beginPath(); + moveTo(values[0][0], 0); for (i in values) { var x = values[i][0]; var y = values[i][1]; - lineTo(x, height - lasty); - lineTo(x, height - y); + lineTo(x, lasty); + lineTo(x, y); lasty = y; } - lineTo(width, height - lasty); - } - - - this.line = function(color, values) { - ctx.fillStyle = color; - ctx.strokeStyle = color; - - draw(values); + lineTo(width, lasty); ctx.stroke(); } + + + var cur = 0; + + function update() { + var line = lines[cur]; + + draw(line); + cur = (cur + 1) % nlines; + + if (cur > 0) { + setTimeout(update, 66); + } + } + + + update() }