Public landing page live map; docs for Discord, live embeds, email
This commit is contained in:
11 files changed
+195
-10
No files matched your search
@@ -65,6 +65,8 @@ pub fn api(state: &AppState) -> Router<AppState> {
|
||||
.route("/guilds/{id}/invites", post(map::send_invite))
|
||||
.route("/leaderboard", get(servers::global_leaderboard))
|
||||
.route("/landing", get(landing::public_landing))
|
||||
.route("/public/map/{id}", get(worldmap::public_info))
|
||||
.route("/public/map/{id}/overlay", get(worldmap::public_overlay))
|
||||
.route("/email/unsubscribe", get(emails::unsubscribe))
|
||||
.route("/launcher/authlib-injector.json", get(account::authlib_index))
|
||||
.route("/launcher/authlib-injector.jar", get(account::authlib_jar))
|
||||
|
||||
@@ -171,3 +171,49 @@ pub async fn tile(State(state): State<AppState>, Path((id, dim, z, x, file)): Pa
|
||||
}
|
||||
resp
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Public map (landing page)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// The landing page's map section decides what the public may see. Without an enabled map section, nothing is public.
|
||||
async fn landing_map(state: &AppState, requested: i64) -> AppResult<(i64, Value)> {
|
||||
let cfg = crate::routes::landing::get_config(state).await?;
|
||||
let block = cfg.blocks.iter().find(|b| b.block_type == "map" && b.enabled).ok_or_else(|| AppError::not_found("no public map"))?;
|
||||
let wanted = block.options.get("server_id").and_then(|v| v.as_i64().or_else(|| v.as_str().and_then(|s| s.parse().ok()))).unwrap_or(0);
|
||||
let id: i64 = if wanted > 0 {
|
||||
wanted
|
||||
} else {
|
||||
sqlx::query_scalar("SELECT COALESCE(MIN(id), 0) FROM game_servers WHERE live_map_enabled = 1").fetch_one(&state.db).await?
|
||||
};
|
||||
if id == 0 || (requested != 0 && requested != id) {
|
||||
return Err(AppError::not_found("no public map"));
|
||||
}
|
||||
let server = get_server(state, id).await?;
|
||||
if !server.map_enabled {
|
||||
return Err(AppError::not_found("no public map"));
|
||||
}
|
||||
let flag = |key: &str, default: bool| block.options.get(key).and_then(|v| v.as_bool().or_else(|| v.as_str().map(|s| s == "true"))).unwrap_or(default);
|
||||
Ok((id, json!({ "claims": flag("show_claims", true), "pins": flag("show_pins", true), "players": flag("show_players", false) })))
|
||||
}
|
||||
|
||||
/// `GET /api/v1/public/map/{server}`: tile key and dimensions for the landing page map (0 = the server the page chose).
|
||||
pub async fn public_info(State(state): State<AppState>, Path(requested): Path<i64>) -> AppResult<Json<Value>> {
|
||||
let (id, layers) = landing_map(&state, requested).await?;
|
||||
let mut v = info(&state, id, true).await;
|
||||
v["server_id"] = json!(id);
|
||||
v["layers"] = layers;
|
||||
Ok(Json(v))
|
||||
}
|
||||
|
||||
pub async fn public_overlay(State(state): State<AppState>, Path(requested): Path<i64>) -> AppResult<Json<Value>> {
|
||||
let (id, layers) = landing_map(&state, requested).await?;
|
||||
let overlay = state.worldmap.overlay(id);
|
||||
let on = |k: &str| layers[k].as_bool().unwrap_or(false);
|
||||
Ok(Json(json!({
|
||||
"players": if on("players") { json!(state.worldmap.live_players(id)) } else { json!([]) },
|
||||
"claims": if on("claims") { overlay.get("claims").cloned().unwrap_or(json!([])) } else { json!([]) },
|
||||
"pins": if on("pins") { overlay.get("pins").cloned().unwrap_or(json!([])) } else { json!([]) },
|
||||
"updated": state.worldmap.stats(id).last_overlay_at,
|
||||
})))
|
||||
}
|
||||
Reference in new issue
Block a user