summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main.rs39
1 files changed, 31 insertions, 8 deletions
diff --git a/server/src/main.rs b/server/src/main.rs
index d6d85d3..1e734b9 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -1,18 +1,20 @@
use anyhow::anyhow;
use futures_util::{SinkExt, StreamExt};
use rand::Rng;
+use rand::seq::SliceRandom;
use std::io::prelude::*;
use std::net::SocketAddr;
use std::sync::LazyLock;
use tokio::io::AsyncWriteExt;
use tungstenite::protocol::Message;
+use std::time::{SystemTime, Duration};
const PUZZLE_ID_CHARSET: &[u8] = b"23456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
-const PUZZLE_ID_LEN: usize = 6;
+const PUZZLE_ID_LEN: usize = 7;
fn generate_puzzle_id() -> [u8; PUZZLE_ID_LEN] {
let mut rng = rand::thread_rng();
- [(); 6].map(|()| PUZZLE_ID_CHARSET[rng.gen_range(0..PUZZLE_ID_CHARSET.len())])
+ [(); 7].map(|()| *PUZZLE_ID_CHARSET.choose(&mut rng).unwrap())
}
struct Server {
@@ -82,6 +84,10 @@ async fn handle_connection(
return Err(anyhow!("too many pieces"));
}
let mut puzzle_data = vec![width, height];
+ let timestamp: u64 = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("time went backwards :/").as_secs();
+ for byte in timestamp.to_le_bytes() {
+ puzzle_data.push(byte);
+ }
// pick nib types
{
let mut rng = rand::thread_rng();
@@ -278,12 +284,6 @@ async fn main() {
return;
}
};
- tokio::task::spawn(async {
- loop {
- // TODO : sweep
- tokio::time::sleep(std::time::Duration::from_secs(3600)).await;
- }
- });
static SERVER_VALUE: LazyLock<Server> = LazyLock::new(|| {
let wikimedia_featured =
read_to_lines("featuredpictures.txt").expect("Couldn't read featuredpictures.txt");
@@ -301,6 +301,29 @@ async fn main() {
}
});
let server: &Server = &SERVER_VALUE;
+ tokio::task::spawn(async {
+ loop {
+ // TODO : sweep
+ let now = SystemTime::now();
+ let mut to_delete = vec![];
+ for item in server.puzzles.iter() {
+ let (key, value) = item.expect("sweep failed to read database");
+ let timestamp: [u8; 8] = value[2..2 + 8].try_into().unwrap();
+ let timestamp = SystemTime::UNIX_EPOCH + Duration::from_secs(u64::from_le_bytes(timestamp));
+ if now.duration_since(timestamp).unwrap_or_default() >= Duration::from_secs(60 * 60 * 24 * 7) {
+ // delete puzzles created at least 1 week ago
+ to_delete.push(key);
+ }
+ }
+ for key in to_delete {
+ // technically there is a race condition here but stop being silly
+ server.puzzles.remove(&key).expect("sweep failed to delete entry");
+ server.pieces.remove(&key).expect("sweep failed to delete entry");
+ server.connectivity.remove(&key).expect("sweep failed to delete entry");
+ }
+ tokio::time::sleep(std::time::Duration::from_secs(3600)).await;
+ }
+ });
loop {
let (mut stream, addr) = match listener.accept().await {
Ok(result) => result,