forked from deadvey/button
added seperate route for leaderboards
This commit is contained in:
Binary file not shown.
+29
-25
@@ -37,36 +37,40 @@
|
|||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
const regex = new RegExp("^[a-zA-Z0-9_-]+$");
|
const regex = new RegExp("^[a-zA-Z0-9_-]+$");
|
||||||
|
const ws = new WebSocket('ws://localhost:8084/ws');
|
||||||
let name = validate_data(prompt("Nickname for the leaderboard"));
|
let name = validate_data(prompt("Nickname for the leaderboard"));
|
||||||
console.log(name)
|
console.log(name)
|
||||||
const ws = new WebSocket('ws://deadvey.com:8084/ws');
|
|
||||||
ws.onopen = (event) => {
|
|
||||||
ws.send(name);
|
|
||||||
};
|
|
||||||
let firstMessage = true;
|
|
||||||
let latestMessage = 0;
|
let latestMessage = 0;
|
||||||
|
ws.onopen = (event) => {
|
||||||
|
ws_leaderboard.send(name);
|
||||||
|
}
|
||||||
|
const ws_leaderboard = new WebSocket('ws://localhost:8084/ws-leaderboard');
|
||||||
|
ws_leaderboard.onopen = (event) => {
|
||||||
|
ws_leaderboard.send("1");
|
||||||
|
};
|
||||||
|
ws_leaderboard.onmessage = (event) => {
|
||||||
|
console.log(event.data);
|
||||||
|
firstMessage = false;
|
||||||
|
data = JSON.parse(event.data);
|
||||||
|
const tableDiv = document.getElementById("score-table");
|
||||||
|
const table = document.createElement("table");
|
||||||
|
// Add header row
|
||||||
|
table.innerHTML = `<tr><th>Rank</th><th>Score</th><th>Name</th><th>P</th></tr>`;
|
||||||
|
// Add data rows concisely using forEach
|
||||||
|
data.hiscores.forEach((entry, index) => {
|
||||||
|
table.innerHTML += `<tr>
|
||||||
|
<td>#${index + 1}</td>
|
||||||
|
<td>${validate_data(entry.score)}</td>
|
||||||
|
<td>${validate_data(entry.person)}</td>
|
||||||
|
<td>${((2/3)**validate_data(entry.score)).toExponential(2)}</td>
|
||||||
|
</tr>`;
|
||||||
|
});
|
||||||
|
tableDiv.appendChild(table);
|
||||||
|
};
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
console.log(event.data);
|
console.log(event.data);
|
||||||
if (firstMessage) {
|
latestMessage = validate_data(event.data);
|
||||||
firstMessage = false;
|
}
|
||||||
data = JSON.parse(event.data);
|
|
||||||
const tableDiv = document.getElementById("score-table");
|
|
||||||
const table = document.createElement("table");
|
|
||||||
// Add header row
|
|
||||||
table.innerHTML = `<tr><th>Rank</th><th>Score</th><th>Name</th><th>P</th></tr>`;
|
|
||||||
// Add data rows concisely using forEach
|
|
||||||
data.hiscores.forEach((entry, index) => {
|
|
||||||
table.innerHTML += `<tr>
|
|
||||||
<td>#${index + 1}</td>
|
|
||||||
<td>${validate_data(entry.score)}</td>
|
|
||||||
<td>${validate_data(entry.person)}</td>
|
|
||||||
<td>${((2/3)**validate_data(entry.score)).toExponential(2)}</td>
|
|
||||||
</tr>`;
|
|
||||||
});
|
|
||||||
tableDiv.appendChild(table);
|
|
||||||
}
|
|
||||||
else { latestMessage = validate_data(event.data); }
|
|
||||||
};
|
|
||||||
function send_click()
|
function send_click()
|
||||||
{
|
{
|
||||||
ws.send(true);
|
ws.send(true);
|
||||||
|
|||||||
+2
-2
@@ -23,10 +23,10 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
const ws = new WebSocket('ws://deadvey.com:8084/ws');
|
const ws = new WebSocket('ws://localhost:8084/ws-leaderboard');
|
||||||
const regex = new RegExp("^[a-zA-Z0-9_-]+$");
|
const regex = new RegExp("^[a-zA-Z0-9_-]+$");
|
||||||
ws.onopen = (event) => {
|
ws.onopen = (event) => {
|
||||||
ws.send("");
|
ws.send('0'); // send all
|
||||||
};
|
};
|
||||||
let latestMessage = 0;
|
let latestMessage = 0;
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
|
|||||||
Binary file not shown.
+88
-32
@@ -1,3 +1,4 @@
|
|||||||
|
// TODO rename pingscores userscores
|
||||||
use std::
|
use std::
|
||||||
{
|
{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
@@ -18,15 +19,15 @@ use axum::
|
|||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
routing::get,
|
routing::get,
|
||||||
};
|
};
|
||||||
use futures::StreamExt as _;
|
|
||||||
use rand::random_bool;
|
|
||||||
use serde::{Deserialize, Serialize, de};
|
|
||||||
use serde_json::json;
|
|
||||||
use tokio::
|
use tokio::
|
||||||
{
|
{
|
||||||
sync::{Mutex, mpsc},
|
sync::{Mutex, mpsc},
|
||||||
time::{Duration, sleep},
|
time::{Duration, sleep},
|
||||||
};
|
};
|
||||||
|
use futures::StreamExt as _;
|
||||||
|
use rand::random_bool;
|
||||||
|
use serde::{Deserialize, Serialize, de};
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Ord, Eq, PartialEq, PartialOrd, Clone)]
|
#[derive(Deserialize, Serialize, Debug, Ord, Eq, PartialEq, PartialOrd, Clone)]
|
||||||
struct Entry
|
struct Entry
|
||||||
@@ -131,6 +132,7 @@ async fn main() -> anyhow::Result<()>
|
|||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.route("/ws", get(ws_handler))
|
.route("/ws", get(ws_handler))
|
||||||
|
.route("/ws-leaderboard", get(leaderboard_handler))
|
||||||
.route("/leaderboard", get(leaderboard))
|
.route("/leaderboard", get(leaderboard))
|
||||||
.with_state
|
.with_state
|
||||||
(AppState {
|
(AppState {
|
||||||
@@ -148,16 +150,6 @@ async fn main() -> anyhow::Result<()>
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn index() -> Html<&'static str>
|
|
||||||
{
|
|
||||||
Html(include_str!("../index.html"))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn leaderboard() -> Html<&'static str>
|
|
||||||
{
|
|
||||||
Html(include_str!("../leaderboard.html"))
|
|
||||||
}
|
|
||||||
// receiver: 0 for hiscore, 1 for loscore, 2 for pingscore
|
// receiver: 0 for hiscore, 1 for loscore, 2 for pingscore
|
||||||
async fn handle_hiscores
|
async fn handle_hiscores
|
||||||
(
|
(
|
||||||
@@ -281,6 +273,76 @@ async fn handle_hiscores
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn leaderboard_handler
|
||||||
|
(
|
||||||
|
ws: WebSocketUpgrade,
|
||||||
|
State(state): State<AppState>
|
||||||
|
)
|
||||||
|
-> impl IntoResponse
|
||||||
|
{
|
||||||
|
ws.on_upgrade
|
||||||
|
(|socket| async move {
|
||||||
|
handle_leaderboard
|
||||||
|
(
|
||||||
|
socket,
|
||||||
|
&state.hiscores,
|
||||||
|
&state.loscores,
|
||||||
|
&state.pingscores,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async fn handle_leaderboard
|
||||||
|
(
|
||||||
|
mut socket: WebSocket,
|
||||||
|
hiscores: &Mutex<Vec<Entry>>,
|
||||||
|
loscores: &Mutex<Vec<Entry>>,
|
||||||
|
pingscores: &Mutex<HashMap<String, (u64, u32)>>,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
match socket.next().await
|
||||||
|
{
|
||||||
|
Some(Ok(Message::Text(selection))) =>
|
||||||
|
{
|
||||||
|
let msg;
|
||||||
|
match selection.as_str()
|
||||||
|
{
|
||||||
|
"0" => // all the leaderboards
|
||||||
|
{
|
||||||
|
msg =
|
||||||
|
{
|
||||||
|
json!
|
||||||
|
({
|
||||||
|
"hiscores": &*hiscores.lock().await,
|
||||||
|
"loscores": &*loscores.lock().await,
|
||||||
|
"pingscores": &*pingscores.lock().await
|
||||||
|
})
|
||||||
|
.to_string()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
"1" => // just the hiscores table
|
||||||
|
{
|
||||||
|
msg = json! ({ "hiscores": &*hiscores.lock().await }).to_string()
|
||||||
|
},
|
||||||
|
"2" => // just the loscores table
|
||||||
|
{
|
||||||
|
msg = json! ({ "loscores": &*hiscores.lock().await }).to_string()
|
||||||
|
},
|
||||||
|
"3" => // just the pingscores table
|
||||||
|
{
|
||||||
|
msg = json! ({ "pingscores": &*hiscores.lock().await }).to_string()
|
||||||
|
},
|
||||||
|
_ => { msg = "Invalid leaderboard selection, please use 0,1,2 or 3".to_string() },
|
||||||
|
}
|
||||||
|
let _ = socket.send(Message::Text(msg.into())).await;
|
||||||
|
},
|
||||||
|
_ =>
|
||||||
|
{
|
||||||
|
let _ = socket.send(Message::Text("Invalid leaderboard selection, please use 0,1,2 or 3".into())).await;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn ws_handler
|
async fn ws_handler
|
||||||
(
|
(
|
||||||
ws: WebSocketUpgrade,
|
ws: WebSocketUpgrade,
|
||||||
@@ -294,9 +356,6 @@ async fn ws_handler
|
|||||||
(
|
(
|
||||||
socket,
|
socket,
|
||||||
&state.tx,
|
&state.tx,
|
||||||
&state.hiscores,
|
|
||||||
&state.loscores,
|
|
||||||
&state.pingscores,
|
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
})
|
})
|
||||||
@@ -306,22 +365,10 @@ async fn handle_socket
|
|||||||
(
|
(
|
||||||
mut socket: WebSocket,
|
mut socket: WebSocket,
|
||||||
tx: &mpsc::Sender<LeaderboardUpdate>,
|
tx: &mpsc::Sender<LeaderboardUpdate>,
|
||||||
hiscores: &Mutex<Vec<Entry>>,
|
|
||||||
loscores: &Mutex<Vec<Entry>>,
|
|
||||||
pingscores: &Mutex<HashMap<String, (u64, u32)>>,
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let mut value: u32 = 0;
|
let mut value: u32 = 0;
|
||||||
let msg =
|
let msg: String;
|
||||||
{
|
|
||||||
json!
|
|
||||||
({
|
|
||||||
"hiscores": &*hiscores.lock().await,
|
|
||||||
"loscores": &*loscores.lock().await,
|
|
||||||
"pingscores": &*pingscores.lock().await
|
|
||||||
})
|
|
||||||
.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(name) = socket.next().await else
|
let Some(name) = socket.next().await else
|
||||||
{
|
{
|
||||||
@@ -344,8 +391,6 @@ async fn handle_socket
|
|||||||
let mut resets: u32 = 0;
|
let mut resets: u32 = 0;
|
||||||
let mut prev: u32 = 0;
|
let mut prev: u32 = 0;
|
||||||
|
|
||||||
let _ = socket.send(Message::Text(msg.into())).await;
|
|
||||||
|
|
||||||
while let Some(msg) = socket.next().await
|
while let Some(msg) = socket.next().await
|
||||||
{
|
{
|
||||||
match msg
|
match msg
|
||||||
@@ -409,3 +454,14 @@ fn validate_name(input: &str) -> bool {
|
|||||||
|
|
||||||
input.chars().all(|c| c.is_ascii_alphanumeric())
|
input.chars().all(|c| c.is_ascii_alphanumeric())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static routes
|
||||||
|
async fn index() -> Html<&'static str>
|
||||||
|
{
|
||||||
|
Html(include_str!("../index.html"))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn leaderboard() -> Html<&'static str>
|
||||||
|
{
|
||||||
|
Html(include_str!("../leaderboard.html"))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user