reversi/src/main.rs

111 lines
3.1 KiB
Rust

#[macro_use]
extern crate rocket;
#[macro_use]
extern crate lazy_static;
use clap::Parser;
use rocket::fs::{relative, FileServer};
use rocket_dyn_templates::Template;
use std::{collections::HashMap, mem::drop, sync::Mutex};
mod names;
mod rooms;
mod templates;
lazy_static! {
static ref ARGS: Args = Args::parse();
static ref ROOMS: Mutex<HashMap<String, rooms::Room>> = Mutex::new(HashMap::new());
}
/*
* Config options
*/
#[derive(Parser, Debug)]
#[clap(about, version, author)]
struct Args {
// Port number for server
#[clap(short, long, default_value_t = 8000)]
port: u16,
// this is here so that it shows up in help, it's actually used in templates.rs
// sucks
#[clap(short, long, default_value = "http://127.0.0.1:8000")]
base_url: String,
}
#[launch]
fn rocket() -> _ {
let mut config = rocket::Config::default();
config.port = ARGS.port;
rocket::custom(config)
.attach(Template::fairing())
.mount("/", FileServer::from(relative!("static")))
.mount("/", routes![index, room])
}
/*
* handles creating rooms, player counts and
*/
#[get("/?<roomname>")]
async fn index(mut roomname: String) -> Template {
// remove whitespace from roomname
roomname = roomname.split_whitespace().collect();
// generate roomname if there is none yet
if roomname.chars().count() == 0 {
roomname = names::get_random_name().await;
print!("{}", roomname)
}
// lock list of rooms
let mut rooms = ROOMS.lock().unwrap();
// do this if there are already people in the room
// first let the new player join and then lock the room for others
if rooms.contains_key(&roomname) {
let mut room = rooms.get_mut(&roomname).unwrap();
if room.full {
drop(rooms);
return templates::get_back_to_home(&roomname);
}
room.full = true;
let templ = templates::join_room(&roomname, room.token);
drop(rooms);
return templ;
}
//create a new room if it doesn't exist yet
else {
// create new room
let room = rooms::Room::new();
let templ = templates::join_new_room(&roomname, room.token);
rooms.insert(roomname.to_string(), room);
drop(rooms);
return templ;
}
}
/*
* handles requests for joining rooms and returns the real room page if token and room combination
* is correct
*/
#[get("/room?<roomname>&<token>&<player1>")]
async fn room(roomname: &str, token: usize, player1: bool) -> Template {
// lock room list mutex, don't forget to drop again
let rooms = ROOMS.lock().unwrap();
if rooms.contains_key(roomname) {
let room = rooms.get(roomname).unwrap();
// the room is real and the token is correct
if room.token == token {
drop(rooms);
//TODO: placeholder
templates::get_back_to_home("cool!")
}
// the room is real but the token is incorrect
else {
drop(rooms);
templates::get_back_to_home("illegalroom")
}
}
// the room doesn't exist
else {
drop(rooms);
templates::get_back_to_home("illegalroom")
}
}