forked from lavina/lavina
endpoint
This commit is contained in:
parent
fdaf10660e
commit
7bc2216ebc
|
@ -281,6 +281,19 @@ impl PlayerRegistry {
|
|||
inner.players.get(id).map(|(handle, _)| handle.clone())
|
||||
}
|
||||
|
||||
pub async fn stop_player(&self, id: &PlayerId) -> Result<Option<()>> {
|
||||
let mut inner = self.0.write().await;
|
||||
if let Some((handle, fiber)) = inner.players.remove(id) {
|
||||
handle.send(ActorCommand::Stop).await;
|
||||
drop(handle);
|
||||
fiber.await?;
|
||||
inner.metric_active_players.dec();
|
||||
Ok(Some(()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_or_launch_player(&mut self, id: &PlayerId) -> PlayerHandle {
|
||||
let inner = self.0.read().await;
|
||||
if let Some((handle, _)) = inner.players.get(id) {
|
||||
|
|
|
@ -11,6 +11,11 @@ pub struct CreatePlayerRequest<'a> {
|
|||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StopPlayerRequest<'a> {
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ChangePasswordRequest<'a> {
|
||||
pub player_name: &'a str,
|
||||
|
@ -19,6 +24,7 @@ pub struct ChangePasswordRequest<'a> {
|
|||
|
||||
pub mod paths {
|
||||
pub const CREATE_PLAYER: &'static str = "/mgmt/create_player";
|
||||
pub const STOP_PLAYER: &'static str = "/mgmt/stop_player";
|
||||
pub const SET_PASSWORD: &'static str = "/mgmt/set_password";
|
||||
}
|
||||
|
||||
|
|
37
src/http.rs
37
src/http.rs
|
@ -13,6 +13,7 @@ use serde::{Deserialize, Serialize};
|
|||
use tokio::net::TcpListener;
|
||||
|
||||
use lavina_core::auth::{Authenticator, UpdatePasswordResult};
|
||||
use lavina_core::player::{PlayerId, PlayerRegistry};
|
||||
use lavina_core::prelude::*;
|
||||
use lavina_core::repo::Storage;
|
||||
use lavina_core::room::RoomRegistry;
|
||||
|
@ -85,6 +86,7 @@ async fn route(
|
|||
(&Method::GET, "/metrics") => endpoint_metrics(registry),
|
||||
(&Method::GET, "/rooms") => endpoint_rooms(core.rooms).await,
|
||||
(&Method::POST, paths::CREATE_PLAYER) => endpoint_create_player(request, storage).await.or5xx(),
|
||||
(&Method::POST, paths::STOP_PLAYER) => endpoint_stop_player(request, storage).await.or5xx(),
|
||||
(&Method::POST, paths::SET_PASSWORD) => endpoint_set_password(request, storage).await.or5xx(),
|
||||
_ => not_found(),
|
||||
};
|
||||
|
@ -120,6 +122,39 @@ async fn endpoint_create_player(
|
|||
Ok(response)
|
||||
}
|
||||
|
||||
async fn endpoint_stop_player(
|
||||
request: Request<hyper::body::Incoming>,
|
||||
players: PlayerRegistry,
|
||||
) -> Result<Response<Full<Bytes>>> {
|
||||
let str = request.collect().await?.to_bytes();
|
||||
let Ok(res) = serde_json::from_slice::<StopPlayerRequest>(&str[..]) else {
|
||||
return Ok(malformed_request());
|
||||
};
|
||||
let Ok(player_id) = PlayerId::from(res.name) else {
|
||||
let payload = ErrorResponse {
|
||||
code: errors::PLAYER_NOT_FOUND,
|
||||
message: "No such player exists",
|
||||
}
|
||||
.to_body();
|
||||
let mut response = Response::new(payload);
|
||||
*response.status_mut() = StatusCode::UNPROCESSABLE_ENTITY;
|
||||
return Ok(response);
|
||||
};
|
||||
let Some(()) = players.stop_player(&player_id).await? else {
|
||||
let payload = ErrorResponse {
|
||||
code: errors::PLAYER_NOT_FOUND,
|
||||
message: "No such player exists",
|
||||
}
|
||||
.to_body();
|
||||
let mut response = Response::new(payload);
|
||||
*response.status_mut() = StatusCode::UNPROCESSABLE_ENTITY;
|
||||
return Ok(response);
|
||||
};
|
||||
let mut response = Response::new(Full::<Bytes>::default());
|
||||
*response.status_mut() = StatusCode::CREATED;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
async fn endpoint_set_password(
|
||||
request: Request<hyper::body::Incoming>,
|
||||
storage: Storage,
|
||||
|
@ -174,6 +209,7 @@ fn malformed_request() -> Response<Full<Bytes>> {
|
|||
trait Or5xx {
|
||||
fn or5xx(self) -> Response<Full<Bytes>>;
|
||||
}
|
||||
|
||||
impl Or5xx for Result<Response<Full<Bytes>>> {
|
||||
fn or5xx(self) -> Response<Full<Bytes>> {
|
||||
self.unwrap_or_else(|e| {
|
||||
|
@ -187,6 +223,7 @@ impl Or5xx for Result<Response<Full<Bytes>>> {
|
|||
trait ToBody {
|
||||
fn to_body(&self) -> Full<Bytes>;
|
||||
}
|
||||
|
||||
impl<T> ToBody for T
|
||||
where
|
||||
T: Serialize,
|
||||
|
|
Loading…
Reference in New Issue