2020-12-05 13:07:33 +00:00
|
|
|
use crate::db::{Dao, TenebrousDbConn};
|
2020-12-01 21:32:16 +00:00
|
|
|
use crate::errors::Error;
|
2020-12-08 21:47:01 +00:00
|
|
|
use crate::models::characters::{CharacterDataType, DynCharacterData, Visibility};
|
2020-12-05 20:15:14 +00:00
|
|
|
use crate::models::users::User;
|
2020-12-07 20:32:02 +00:00
|
|
|
use rocket::request::Form;
|
2020-12-03 19:45:56 +00:00
|
|
|
use rocket::response::Redirect;
|
2020-12-01 21:32:16 +00:00
|
|
|
use rocket_contrib::templates::Template;
|
2020-12-08 21:47:01 +00:00
|
|
|
use serde::Serialize;
|
2020-12-01 21:32:16 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
pub(crate) fn routes() -> Vec<rocket::Route> {
|
2020-12-03 19:45:56 +00:00
|
|
|
routes![
|
|
|
|
view_character,
|
|
|
|
new_character,
|
2020-12-07 20:32:02 +00:00
|
|
|
create_new_character,
|
2020-12-03 19:45:56 +00:00
|
|
|
new_character_not_logged_in,
|
|
|
|
edit_character
|
|
|
|
]
|
2020-12-01 21:32:16 +00:00
|
|
|
}
|
|
|
|
|
2020-12-07 20:32:02 +00:00
|
|
|
#[derive(FromForm)]
|
|
|
|
struct NewCharacterForm {
|
|
|
|
name: String, //TODO add game system
|
|
|
|
}
|
|
|
|
|
2020-12-08 08:47:34 +00:00
|
|
|
#[derive(Serialize)]
|
2020-12-08 21:47:01 +00:00
|
|
|
struct ViewCharacterTemplate<'a> {
|
2020-12-08 08:47:34 +00:00
|
|
|
pub name: &'a str,
|
|
|
|
pub username: &'a str,
|
2020-12-08 21:47:01 +00:00
|
|
|
pub sheet: Box<DynCharacterData>,
|
2020-12-08 08:47:34 +00:00
|
|
|
}
|
|
|
|
|
2020-12-05 13:07:33 +00:00
|
|
|
#[get("/<username>/<character_id>")]
|
2020-12-01 21:32:16 +00:00
|
|
|
fn view_character(
|
|
|
|
character_id: i32,
|
2020-12-05 13:07:33 +00:00
|
|
|
username: String,
|
2020-12-01 21:32:16 +00:00
|
|
|
conn: TenebrousDbConn,
|
2020-12-05 20:15:14 +00:00
|
|
|
logged_in_user: Option<&User>,
|
2020-12-01 21:32:16 +00:00
|
|
|
) -> Result<Template, Error> {
|
2020-12-05 13:07:33 +00:00
|
|
|
let user = conn.load_user(&username)?.ok_or(Error::NotFound)?;
|
2020-12-05 20:15:14 +00:00
|
|
|
|
|
|
|
let character = conn
|
|
|
|
.load_character(character_id)?
|
|
|
|
.and_then(|c| c.as_visible_for(logged_in_user))
|
|
|
|
.ok_or(Error::NotFound)?;
|
2020-12-01 21:32:16 +00:00
|
|
|
|
2020-12-08 21:47:01 +00:00
|
|
|
let context = ViewCharacterTemplate {
|
2020-12-08 08:47:34 +00:00
|
|
|
name: &character.character_name,
|
|
|
|
username: &user.username,
|
2020-12-08 21:47:01 +00:00
|
|
|
sheet: character.dyn_deserialize()?,
|
2020-12-08 08:47:34 +00:00
|
|
|
};
|
|
|
|
|
2020-12-01 21:32:16 +00:00
|
|
|
Ok(Template::render("view_character", context))
|
|
|
|
}
|
|
|
|
|
2020-12-03 19:45:56 +00:00
|
|
|
#[get("/new")]
|
2020-12-05 13:07:33 +00:00
|
|
|
fn new_character(logged_in_user: &User, conn: TenebrousDbConn) -> Result<Template, Error> {
|
2020-12-03 19:45:56 +00:00
|
|
|
let context = HashMap::<String, String>::new();
|
|
|
|
Ok(Template::render("new_character", context))
|
|
|
|
}
|
|
|
|
|
2020-12-07 20:32:02 +00:00
|
|
|
#[post("/new", data = "<form>")]
|
|
|
|
fn create_new_character(
|
|
|
|
form: Form<NewCharacterForm>,
|
|
|
|
logged_in_user: &User,
|
|
|
|
conn: TenebrousDbConn,
|
|
|
|
) -> Result<Redirect, Error> {
|
|
|
|
//TODO redirect to character edit page
|
|
|
|
//TODO redirect back to new character page with an error and filled-out form if validation errors.
|
|
|
|
//TODO add game system.
|
|
|
|
use crate::models::characters::NewCharacter;
|
|
|
|
use crate::models::proto::cofd::CofdSheet;
|
|
|
|
use prost::bytes::BytesMut;
|
|
|
|
use prost::Message;
|
|
|
|
|
2020-12-08 21:47:01 +00:00
|
|
|
let mut new_character = CofdSheet::default();
|
|
|
|
new_character.strength = 100;
|
2020-12-07 20:32:02 +00:00
|
|
|
let mut buf = BytesMut::with_capacity(std::mem::size_of_val(&new_character));
|
|
|
|
new_character.encode(&mut buf)?;
|
|
|
|
|
|
|
|
let insert = NewCharacter {
|
|
|
|
user_id: logged_in_user.id,
|
|
|
|
viewable: true,
|
|
|
|
character_name: &form.name,
|
2020-12-08 21:47:01 +00:00
|
|
|
data_type: CharacterDataType::ChroniclesOfDarknessV1,
|
2020-12-07 20:32:02 +00:00
|
|
|
data_version: 1,
|
|
|
|
data: &buf,
|
|
|
|
};
|
|
|
|
|
|
|
|
conn.insert_character(insert)?;
|
|
|
|
Ok(super::common::redirect_to_index())
|
|
|
|
}
|
|
|
|
|
2020-12-03 19:45:56 +00:00
|
|
|
#[get("/new", rank = 2)]
|
|
|
|
fn new_character_not_logged_in() -> Redirect {
|
|
|
|
super::common::redirect_to_login()
|
|
|
|
}
|
|
|
|
|
2020-12-01 21:32:16 +00:00
|
|
|
#[get("/<owner>/<character_id>/edit")]
|
|
|
|
fn edit_character(
|
|
|
|
character_id: i32,
|
2020-12-05 13:07:33 +00:00
|
|
|
owner: String,
|
|
|
|
logged_in_user: Option<&User>,
|
2020-12-01 21:32:16 +00:00
|
|
|
conn: TenebrousDbConn,
|
|
|
|
) -> Result<Template, Error> {
|
2020-12-05 13:07:33 +00:00
|
|
|
let owner = conn.load_user(&owner)?.ok_or(Error::NotFound)?;
|
2020-12-01 21:32:16 +00:00
|
|
|
let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?;
|
2020-12-05 13:07:33 +00:00
|
|
|
let character = conn.load_character(character_id)?.ok_or(Error::NotFound)?;
|
2020-12-01 21:32:16 +00:00
|
|
|
|
2020-12-05 13:07:33 +00:00
|
|
|
if logged_in_user != &owner {
|
2020-12-01 21:32:16 +00:00
|
|
|
return Err(Error::NoPermission);
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut context = HashMap::new();
|
2020-12-07 20:32:02 +00:00
|
|
|
context.insert("name", character.character_name);
|
2020-12-01 21:32:16 +00:00
|
|
|
context.insert("username", owner.username);
|
|
|
|
Ok(Template::render("view_character", context))
|
|
|
|
}
|