148 lines
6.2 KiB
Rust
148 lines
6.2 KiB
Rust
use actix_cors::Cors;
|
|
use actix_files as fs;
|
|
use actix_web::{web, middleware, App, Error, HttpResponse, HttpServer, Either};
|
|
use futures::{Future, IntoFuture};
|
|
use std::env;
|
|
|
|
use lootalot_db as db;
|
|
use crate::api;
|
|
|
|
type AppPool = web::Data<db::Pool>;
|
|
type PlayerId = web::Path<i32>;
|
|
type ItemId = web::Json<i32>;
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
struct NewGroupLoot {
|
|
source_name: String,
|
|
items: Vec<db::Item>,
|
|
}
|
|
|
|
type MaybeForbidden = actix_web::Either<Box<dyn Future<Item = HttpResponse, Error = Error>>, HttpResponse>;
|
|
|
|
/// Wraps call to the database query and convert its result as a async HttpResponse
|
|
fn db_call(
|
|
pool: AppPool,
|
|
query: api::ApiActions,
|
|
) -> impl Future<Item = HttpResponse, Error = Error>
|
|
{
|
|
let conn = pool.get().unwrap();
|
|
web::block(move || api::execute(&conn, query)).then(|res| match res {
|
|
Ok(r) => HttpResponse::Ok().json(r),
|
|
Err(e) => {
|
|
dbg!(&e);
|
|
HttpResponse::InternalServerError().finish()
|
|
}
|
|
})
|
|
}
|
|
|
|
fn forbidden_to_players(id: i32, params: (AppPool, api::ApiActions)) -> MaybeForbidden {
|
|
if id != 0 {
|
|
Either::B(HttpResponse::Forbidden().finish())
|
|
} else {
|
|
Either::A(Box::new(db_call(params.0, params.1)))
|
|
}
|
|
|
|
}
|
|
|
|
fn configure_app(config: &mut web::ServiceConfig) {
|
|
use api::ApiActions as Q;
|
|
config.service(
|
|
web::scope("/api")
|
|
.service(
|
|
web::scope("/players")
|
|
.service(
|
|
web::resource("/").route(
|
|
web::get().to_async(|pool| db_call(pool, Q::FetchPlayers)),
|
|
), //.route(web::post().to_async(endpoints::new_player))
|
|
) // List of players
|
|
.service(
|
|
web::scope("/{player_id}")
|
|
.route("/", web::get().to_async(|pool, player: PlayerId| {
|
|
db_call(pool, Q::FetchPlayer(*player))
|
|
}))
|
|
.route("/notifications", web::get().to_async(|pool, player: PlayerId| {
|
|
db_call(pool, Q::FetchNotifications(*player))
|
|
}))
|
|
.service(
|
|
web::resource("/claims")
|
|
//.route(web::get().to_async(endpoints::player_claims))
|
|
.route(web::put().to_async(
|
|
|pool, (player, data): (PlayerId, ItemId)| {
|
|
db_call(pool, Q::ClaimItem(*player, *data))
|
|
},
|
|
))
|
|
.route(web::delete().to_async(
|
|
|pool, (player, data): (PlayerId, ItemId)| {
|
|
db_call(
|
|
pool,
|
|
Q::UnclaimItem(*player, *data),
|
|
)
|
|
},
|
|
)),
|
|
)
|
|
.service(
|
|
web::resource("/wealth")
|
|
//.route(web::get().to_async(...))
|
|
.route(web::put().to_async(
|
|
|pool, (player, data): (PlayerId, web::Json<f64>)| {
|
|
db_call(
|
|
pool,
|
|
Q::UpdateWealth(*player, *data),
|
|
)
|
|
},
|
|
)),
|
|
)
|
|
.service(
|
|
web::resource("/loot")
|
|
.route(web::get().to_async(|pool, player: PlayerId| {
|
|
db_call(pool, Q::FetchLoot(*player))
|
|
}))
|
|
.route(web::put().to_async(
|
|
move |pool, (player, data): (PlayerId, web::Json<api::ItemListWithMods>)| {
|
|
db_call(pool, Q::BuyItems(*player, data.into_inner()))
|
|
},
|
|
))
|
|
.route(web::post().to(
|
|
move |pool, (player, data): (PlayerId, web::Json<NewGroupLoot>)| {
|
|
forbidden_to_players(*player, (pool, Q::AddLoot(data.into_inner().items)))
|
|
},
|
|
))
|
|
.route(web::delete().to_async(
|
|
move |pool, (player, data): (PlayerId, web::Json<api::SellParams>)| {
|
|
db_call(pool, Q::SellItems(*player, data.into_inner()))
|
|
},
|
|
)),
|
|
),
|
|
),
|
|
)
|
|
.route("/claims", web::get().to_async(|pool| db_call(pool, Q::FetchClaims)))
|
|
.route(
|
|
"/items",
|
|
web::get()
|
|
.to_async(move |pool: AppPool| db_call(pool, Q::FetchInventory)),
|
|
),
|
|
);
|
|
}
|
|
|
|
pub fn serve() -> std::io::Result<()> {
|
|
let www_root: String = env::var("WWW_ROOT").expect("WWW_ROOT must be set");
|
|
let pool = db::create_pool();
|
|
dbg!(&www_root);
|
|
|
|
HttpServer::new(move || {
|
|
App::new()
|
|
.data(pool.clone())
|
|
.configure(configure_app)
|
|
.wrap(
|
|
Cors::new()
|
|
.allowed_origin("http://localhost:8080")
|
|
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"])
|
|
.max_age(3600),
|
|
)
|
|
.wrap(middleware::Logger::default())
|
|
.service(fs::Files::new("/", www_root.clone()).index_file("index.html"))
|
|
})
|
|
.bind("127.0.0.1:8088")?
|
|
.run()
|
|
}
|