Commit da1a5f20 authored by Philipp Hochkamp's avatar Philipp Hochkamp

added autoreload of the leaderboard

closes #30
parent b2c2511b
......@@ -8,6 +8,7 @@ require (
github.com/gorilla/mux v1.7.3
github.com/gorilla/securecookie v1.1.1
github.com/gorilla/sessions v1.2.0
github.com/gorilla/websocket v1.4.1
github.com/mattn/go-sqlite3 v1.11.0
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586
xorm.io/core v0.7.0
......
......@@ -54,6 +54,8 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
......
{{ template "header" . }}
<main class="flexcell gridcontainer-leader">
<div id="table" class="col-0" style="width: 20%;">
<div id="table" class="col-0 row-0" style="width: 20%;">
<table>
<tbody>
<tr>
<th>Name</th>
<th>Points</th>
......@@ -12,22 +13,27 @@
<td>{{ .Points }}</td>
</tr>
{{ end }}
</tbody>
</table>
</div>
<div class="col-1" style="height: 100%;">
<div class="col-1 row-0">
<canvas id="graph"></canvas>
</div>
<script src="static/Chart.bundle.min.js" type="text/javascript"></script>
<script>
var score = {name: [{{ range .AllUsers }}{{ .DisplayName }},{{end}}], points: [ { label: "Points", data: [{{ range .AllUsers }}{{ .Points }},{{end}}]}] };
var chart;
(function(){
var c = document.getElementById("graph").getContext('2d');
c.height = 800;
var chart = new Chart(c, {
chart = new Chart(c, {
type: 'horizontalBar',
data: {
labels: [{{ range .AllUsers }}{{ .DisplayName }},{{end}}],
datasets: [ { label: "Points", data: [{{ range .AllUsers }}{{ .Points }},{{end}}]}]
labels: score.name,
datasets: score.points
},
options: {
scales: {
......@@ -45,6 +51,38 @@
responsive: true,
},
});
ws = new WebSocket("ws://"+window.location.host+"/ws");
ws.onopen = function() {
// Web Socket is connected, send data uting send()
console.log("ws connected");
};
ws.onclose = function() {
alert("WS Disconnected, reload the page")
};
ws.onmessage = (evt)=>{
var rec = evt.data;
console.log(evt.data);
score = JSON.parse(rec);
chart.data = {
labels: score.name,
datasets: [{data: score.points, label: "Solved Challenges" }]
};
chart.update();
table = document.getElementsByTagName("tbody")[0];
table.innerHTML = "<tr><th>Name</th><th>Points</th></tr>";
for(i=0; i < score.name.length; i++){
row = table.insertRow();
namecell = row.insertCell();
namecell.innerHTML = score.name[i];
pointcell = row.insertCell();
pointcell.innerHTML = score.points[i];
}
};
})();
</script>
</main>
......
package wtfd
import (
"encoding/json"
"github.com/gorilla/websocket"
"log"
"net/http"
)
var (
serverChan = make(chan chan string, 4)
messageChan = make(chan string, 1)
upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
)
func leaderboardMessageServer(serverChan chan chan string) {
var clients []chan string
// And now we listen to new clients and new messages:
for {
select {
case client, _ := <-serverChan:
clients = append(clients, client)
case msg, _ := <-messageChan:
// Send the uptime to all connected clients:
for _, c := range clients {
c <- msg
}
}
}
}
func leaderboardServer(serverChan chan chan string) {
var clients []chan string
for {
select {
case client, _ := <-serverChan:
clients = append(clients, client)
}
}
}
func leaderboardWS(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
if _, ok := err.(websocket.HandshakeError); !ok {
log.Println(err)
}
return
}
client := make(chan string, 1)
serverChan <- client // i have no idea what this go magic is
for {
select {
case text, _ := <-client:
writer, _ := ws.NextWriter(websocket.TextMessage)
writer.Write([]byte(text))
writer.Close()
}
}
}
func updateScoreboard() error {
log.Printf("Scoreboard Update\n")
type userNamePoints struct {
Name []string `json:"name"`
Points []int `json:"points"`
}
var name []string
var points []int
allu, err := ormAllUsersSortedByPoints()
if err != nil {
log.Printf("Scoreboard Update Error: %v\n", err)
return err
}
for _, u := range allu {
name = append(name, u.DisplayName)
points = append(points, u.Points)
}
json, err := json.Marshal(&userNamePoints{Name: name, Points: points})
if err != nil {
log.Printf("Scoreboard Update Error: %v\n", err)
return err
}
messageChan <- string(json)
log.Printf("Scoreboard Update String: %s\n", string(json))
return nil
}
package wtfd
import (
"encoding/base64"
"encoding/gob"
"encoding/json"
"encoding/base64"
"errors"
"fmt"
"github.com/gomarkdown/markdown"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
"github.com/gorilla/securecookie"
"github.com/gorilla/sessions"
"golang.org/x/crypto/bcrypt"
"html/template"
"io/ioutil"
......@@ -497,6 +497,7 @@ func submitFlag(w http.ResponseWriter, r *http.Request) {
}
_, _ = fmt.Fprintf(w, "correct")
_ = updateScoreboard()
} else {
_, _ = fmt.Fprintf(w, "not correct")
......@@ -533,7 +534,8 @@ func register(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprintf(w, "Server Error: %v", err)
} else {
_ = ormNewUser(u)
login(w,r)
login(w, r)
_ = updateScoreboard()
}
......@@ -732,6 +734,7 @@ func Server() error {
if err != nil {
return err
}
go leaderboardMessageServer(serverChan)
// Http sturf
r := mux.NewRouter()
r.HandleFunc("/", mainpage)
......@@ -741,6 +744,7 @@ func Server() error {
r.HandleFunc("/logout", logout)
r.HandleFunc("/register", register)
r.HandleFunc("/submitflag", submitFlag)
r.HandleFunc("/ws", leaderboardWS)
r.HandleFunc("/{chall}", mainpage)
r.HandleFunc("/detailview/{chall}", detailview)
r.HandleFunc("/solutionview/{chall}", solutionview)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment