#![expect(clippy::wildcard_imports)]
mod auth;
mod battle;
mod chat;
mod cheat;
mod city;
mod continent;
mod infrastructure;
mod military;
mod npc;
mod player;
mod ranking;
mod report;
mod round;
mod server;
mod user;
mod websocket;
mod world;
use crate::app::App;
use crate::middleware::authorization::authorization;
use axum::http::{Method, StatusCode};
use axum::response::Redirect;
use axum::routing::{any, get, post, put};
use axum::{Router, middleware};
use tower_http::cors::{Any, CorsLayer};
use tower_http::trace::{
DefaultMakeSpan,
DefaultOnFailure,
DefaultOnRequest,
DefaultOnResponse,
TraceLayer,
};
use tracing::Level;
#[expect(clippy::too_many_lines)]
pub(crate) fn create() -> Router<App> {
#[rustfmt::skip]
let router = Router::new()
.route("/add-academy-recruit-order", post(infrastructure::academy::add_recruit_order))
.route("/add-prefecture-build-order", post(infrastructure::prefecture::add_build_order))
.route("/add-stable-recruit-order", post(infrastructure::stable::add_recruit_order))
.route("/add-workshop-recruit-order", post(infrastructure::workshop::add_recruit_order))
.route("/cancel-academy-recruit-order", post(infrastructure::academy::cancel_recruit_order))
.route("/cancel-prefecture-build-order", post(infrastructure::prefecture::cancel_build_order))
.route("/cancel-stable-recruit-order", post(infrastructure::stable::cancel_recruit_order))
.route("/cancel-workshop-recruit-order", post(infrastructure::workshop::cancel_recruit_order))
.route("/cheat-get-academy-recruit-queue", put(cheat::infrastructure::get_academy_recruit_queue))
.route("/cheat-get-academy-recruit-queues", put(cheat::infrastructure::get_academy_recruit_queues))
.route("/cheat-get-all-academy-recruit-queues", put(cheat::infrastructure::get_all_academy_recruit_queues))
.route("/cheat-get-all-prefecture-build-queues", put(cheat::infrastructure::get_all_prefecture_build_queues))
.route("/cheat-get-all-stable-recruit-queues", put(cheat::infrastructure::get_all_stable_recruit_queues))
.route("/cheat-get-build-steps", put(cheat::behavior::get_build_steps))
.route("/cheat-get-ethics", put(cheat::npc::get_ethics))
.route("/cheat-get-idle-armies-at", put(cheat::military::get_idle_armies_at))
.route("/cheat-get-idle-personnel-at", put(cheat::military::get_idle_personnel_at))
.route("/cheat-get-infrastructure", put(cheat::infrastructure::get_infrastructure))
.route("/cheat-get-maneuvers", put(cheat::military::get_maneuvers))
.route("/cheat-get-maneuvers-of", put(cheat::military::get_maneuvers_of))
.route("/cheat-get-player", put(cheat::player::get_player))
.route("/cheat-get-players", put(cheat::player::get_players))
.route("/cheat-get-prefecture-build-queue", put(cheat::infrastructure::get_prefecture_build_queue))
.route("/cheat-get-prefecture-build-queues", put(cheat::infrastructure::get_prefecture_build_queues))
.route("/cheat-get-resources", put(cheat::resources::get_resources))
.route("/cheat-get-stable-recruit-queue", put(cheat::infrastructure::get_stable_recruit_queue))
.route("/cheat-get-stable-recruit-queues", put(cheat::infrastructure::get_stable_recruit_queues))
.route("/cheat-get-storage-capacity", put(cheat::infrastructure::get_storage_capacity))
.route("/cheat-set-bot-ethics", post(cheat::npc::set_bot_ethics))
.route("/cheat-set-building-level", post(cheat::infrastructure::set_building_level))
.route("/cheat-set-food", post(cheat::resources::set_food))
.route("/cheat-set-iron", post(cheat::resources::set_iron))
.route("/cheat-set-max-food", post(cheat::resources::set_max_food))
.route("/cheat-set-max-infrastructure", post(cheat::infrastructure::set_max_infrastructure))
.route("/cheat-set-max-iron", post(cheat::resources::set_max_iron))
.route("/cheat-set-max-resources", post(cheat::resources::set_max_resources))
.route("/cheat-set-max-silo-resources", post(cheat::resources::set_max_silo_resources))
.route("/cheat-set-max-stone", post(cheat::resources::set_max_stone))
.route("/cheat-set-max-warehouse-resources", post(cheat::resources::set_max_warehouse_resources))
.route("/cheat-set-max-wood", post(cheat::resources::set_max_wood))
.route("/cheat-set-resources", post(cheat::resources::set_resources))
.route("/cheat-set-stability", post(cheat::city::set_stability))
.route("/cheat-set-stone", post(cheat::resources::set_stone))
.route("/cheat-set-wood", post(cheat::resources::set_wood))
.route("/cheat-skip-round", post(cheat::round::skip))
.route("/cheat-spawn-bot", post(cheat::npc::spawn_bot))
.route("/cheat-spawn-personnel", post(cheat::military::spawn_personnel))
.route("/create-remote-world", post(world::remote::create))
.route("/delete-remote-world", post(world::remote::delete))
.route("/forward-report", post(report::forward))
.route("/get-academy-recruit-catalog", put(infrastructure::academy::get_recruit_catalog))
.route("/get-chat-history", put(chat::get))
.route("/get-city", put(city::get_city))
.route("/get-player", put(player::get_player))
.route("/get-player-maintenance", put(player::get_maintenance))
.route("/get-player-military", put(player::get_military))
.route("/get-player-reports", put(player::get_reports))
.route("/get-player-storage-capacity", put(player::get_storage_capacity))
.route("/get-prefecture-build-catalog", put(infrastructure::prefecture::get_build_catalog))
.route("/get-report", put(report::get))
.route("/get-reports", put(report::get_by))
.route("/get-stable-recruit-catalog", put(infrastructure::stable::get_recruit_catalog))
.route("/get-workshop-recruit-catalog", put(infrastructure::workshop::get_recruit_catalog))
.route("/leave", post(world::leave))
.route("/push-chat-message", post(chat::push))
.route("/remove-report", post(report::remove))
.route("/rename-city", post(city::rename_city))
.route("/request-maneuver", post(military::request_maneuver))
.route("/save-local-world", post(world::local::save))
.route("/search-city", put(city::search_city))
.route("/set-player-ready", post(round::set_ready))
.route("/set-player-status", post(player::set_status))
.route("/spawn-player", post(player::spawn))
.route("/start-round", post(round::start))
.route("/toggle-building", post(infrastructure::toggle))
.route("/websocket", any(websocket::websocket))
.route_layer(middleware::from_fn(authorization))
.route("/authorize", post(auth::authorize))
.route("/create-user", post(user::create))
.route("/get-bot-coords", put(npc::bot::get_coords))
.route("/get-city-score", put(city::get_city_score))
.route("/get-continent-size", put(continent::size))
.route("/get-player-coords", put(player::get_coords))
.route("/get-player-ids", put(player::get_ids))
.route("/get-player-status", put(player::get_status))
.route("/get-player-worlds", put(player::get_worlds))
.route("/get-precursor-coords", put(npc::precursor::get_coords))
.route("/get-public-bot", put(npc::bot::get_public_bot))
.route("/get-public-bots", put(npc::bot::get_public_bots))
.route("/get-public-cities", put(city::get_public_cities))
.route("/get-public-city", put(city::get_public_city))
.route("/get-public-field", put(continent::get_public_field))
.route("/get-public-fields", put(continent::get_public_fields))
.route("/get-public-player", put(player::get_public_player))
.route("/get-public-players", put(player::get_public_players))
.route("/get-public-precursor", put(npc::precursor::get_public_precursor))
.route("/get-public-precursors", put(npc::precursor::get_public_precursors))
.route("/get-rank", put(ranking::get_rank))
.route("/get-ranking", put(ranking::get))
.route("/get-remote-world", put(world::remote::get))
.route("/get-remote-world-limit", get(world::remote::get_limit))
.route("/get-remote-world-limit-per-user", get(world::remote::get_limit_per_user))
.route("/get-round", put(round::get))
.route("/get-server-kind", get(server::kind))
.route("/get-world-bots", put(world::get_bots))
.route("/get-world-config", put(world::get_config))
.route("/get-world-personnel", put(world::get_personnel))
.route("/get-world-players", put(world::get_players))
.route("/get-world-precursors", put(world::get_precursors))
.route("/get-world-stats", put(world::get_stats))
.route("/player-exists", put(player::exists))
.route("/search-public-city", put(city::search_public_city))
.route("/simulate-battle", put(battle::simulate))
.route("/user-exists", put(user::exists))
.route("/validate-token", put(auth::validate_token))
.route("/license", any(license))
.route("/robots.txt", any(robots_txt));
router.merge(with_cors()).layer(
TraceLayer::new_for_http()
.make_span_with(DefaultMakeSpan::new().include_headers(true))
.on_request(DefaultOnRequest::new().level(Level::TRACE))
.on_response(DefaultOnResponse::new().level(Level::TRACE))
.on_failure(DefaultOnFailure::new().level(Level::TRACE))
.on_body_chunk(())
.on_eos(()),
)
}
fn with_cors() -> Router<App> {
let cors = CorsLayer::new()
.allow_methods([Method::GET])
.allow_origin(Any);
#[rustfmt::skip]
let router = Router::new()
.route("/", get(ok))
.route("/get-remote-worlds", get(world::remote::get_all))
.route("/version", get(server::version))
.route_layer(cors);
router
}
async fn ok() -> StatusCode {
StatusCode::OK
}
async fn license() -> Redirect {
Redirect::to("https://spdx.org/licenses/AGPL-3.0-only.html")
}
async fn robots_txt() -> &'static str {
"User-agent: *\nDisallow: /"
}