pub mod account; pub mod achievements; pub mod activity; pub mod admin; pub mod connections; pub mod economy; pub mod guild_bank; pub mod guilds; pub mod landing; pub mod livemap; pub mod leveling; pub mod meta; pub mod progression; pub mod public; pub mod quests; pub mod servers; pub mod social; use crate::state::AppState; use axum::extract::DefaultBodyLimit; use axum::routing::{delete, get, post, put}; use axum::Router; pub fn api(state: &AppState) -> Router { let upload_limit = state.cfg.max_upload_mb * 1024 * 1024; let launcher = Router::new() .route("/launcher/manifest", get(public::manifest)) .route("/launcher/instances/{id}", get(public::instance_manifest)) .route("/launcher/events", post(public::event)) .route("/instances", get(admin::list_instances)) .route("/auth/login", post(public::login)) .route("/auth/register", post(public::register)) .route("/auth/me", get(public::me)) .route("/auth/connections/config", get(connections::public_config)) .route("/auth/forgot-password", post(connections::forgot_password)) .route("/auth/reset-password", post(connections::reset_password)) .route("/auth/discord/start", get(connections::discord_start)) .route("/auth/discord/callback", get(connections::discord_callback)) .route("/auth/discord/poll", get(connections::discord_poll)) .route("/account/connections/discord", get(connections::my_discord).delete(connections::unlink_discord)) .route("/account/profile", get(account::profile)) .route("/account/stats", get(servers::account_player_stats)) .route("/account/username", axum::routing::put(account::set_username)) .route("/account/skin", post(account::upload_skin).delete(account::delete_skin)) .route("/account/skin/model", axum::routing::put(account::set_model)) .route("/account/cape", axum::routing::put(account::set_cape)) .route("/avatar/{id}", get(account::avatar)) .route("/servers/public", get(servers::public_servers)) .route("/servers/{id}/leaderboard", get(servers::public_server_leaderboard)) .route("/servers/{id}/livemap", get(livemap::viewer_info)) .route("/leaderboard", get(servers::global_leaderboard)) .route("/landing", get(landing::public_landing)) .route("/launcher/authlib-injector.json", get(account::authlib_index)) .route("/launcher/authlib-injector.jar", get(account::authlib_jar)) // Leveling & Rewards .route("/levels/me", get(leveling::get_my_levels)) .route("/leveling/me", get(leveling::get_my_levels)) .route("/levels/player/{uuid}", get(leveling::get_player_levels)) .route("/levels/leaderboard", get(leveling::get_level_leaderboard)) .route("/levels/rewards", get(leveling::list_rewards)) // Daily & Weekly Quests .route("/quests/my", get(quests::get_my_quests)) .route("/quests/me", get(quests::get_my_quests)) .route("/quests/{id}/claim", post(quests::claim_quest)) // Achievements .route("/achievements/my", get(achievements::get_my_achievements)) .route("/achievements/me", get(achievements::get_my_achievements)) .route("/achievements/player/{uuid}", get(achievements::get_player_achievements)) // Guilds & Land Claims .route("/guilds", get(guilds::list_guilds).post(guilds::create_guild)) .route("/guilds/my", get(guilds::get_my_guild)) .route("/guilds/claims/grid", get(guilds::get_chunk_grid)) .route("/guilds/claims/{id}", delete(guilds::unclaim_by_id)) .route("/guilds/{id}", get(guilds::get_guild_by_id).put(guilds::update_guild)) .route("/guilds/{id}/members", get(guilds::get_guild_members).post(guilds::add_guild_member)) .route("/guilds/{id}/members/{uuid}", delete(guilds::remove_guild_member)) .route("/guilds/{id}/posts", get(guilds::get_guild_posts).post(guilds::create_guild_post)) .route("/guilds/{id}/wallet", get(guilds::guild_wallet)) .route("/guilds/{id}/wallet/deposit", post(guilds::guild_wallet_deposit)) .route("/guilds/{id}/wallet/withdraw", post(guilds::guild_wallet_withdraw)) .route("/guilds/{id}/claims", post(guilds::claim_chunk).delete(guilds::unclaim_chunk)) .route("/guilds/{id}/claim", post(guilds::claim_chunk)) .route("/guilds/{id}/unclaim", post(guilds::unclaim_chunk)) // Economy .route("/economy/me", get(economy::get_my_balances)) .route("/economy/balances", get(economy::get_my_balances)) .route("/economy/transactions", get(economy::get_my_transactions)) .route("/servers/{id}/economy/baltop", get(economy::get_server_baltop)) .route("/servers/{id}/economy/market", get(economy::get_server_market)) // Social: Friends, DMs, Invites, Profiles, Posts, Members Search .route("/friends", get(social::list_friends)) .route("/friends/request", post(social::send_friend_request)) .route("/friends/respond", post(social::respond_friend_request)) .route("/friends/{uuid}/accept", post(social::accept_friend_request)) .route("/friends/{uuid}", delete(social::remove_friend)) .route("/messages/{uuid}", get(social::get_direct_messages).post(social::send_direct_message)) .route("/invites", get(social::list_my_game_invites).post(social::send_game_invite)) .route("/invites/{id}/respond", post(social::respond_game_invite)) .route("/profiles/me", put(social::update_my_profile)) .route("/profiles/{uuid}", get(social::get_player_profile)) .route("/profiles/me/posts", post(social::create_user_post)) .route("/profiles/me/posts/{id}", delete(social::delete_user_post)) .route("/posts/{id}/like", post(social::like_user_post)) .route("/social/friends", get(social::list_friends)) .route("/social/friends/request", post(social::send_friend_request)) .route("/social/friends/respond", post(social::respond_friend_request)) .route("/social/messages/{uuid}", get(social::get_direct_messages).post(social::send_direct_message)) .route("/social/profile/me", put(social::update_my_profile)) .route("/social/profile/{uuid}", get(social::get_player_profile)) .route("/social/posts", post(social::create_user_post)) .route("/social/posts/{id}/like", post(social::like_user_post)) .route("/social/members", get(social::search_members)) .route("/members/search", get(social::search_members)) .layer(DefaultBodyLimit::max(4 * 1024 * 1024)); let admin = Router::new() .route("/connections", get(connections::admin_get).put(connections::admin_put)) .route("/connections/test-email", post(connections::admin_test_email)) .route("/activity", get(activity::list)) .route("/stats", get(admin::stats)) .route("/users", get(admin::list_users).post(admin::create_user)) .route("/users/{id}", axum::routing::patch(admin::update_user).delete(admin::delete_user)) .route("/groups", get(admin::list_groups).post(admin::create_group)) .route("/groups/{id}", delete(admin::delete_group)) .route("/branding", get(admin::get_branding).put(admin::put_branding)) .route("/settings", get(admin::get_settings).put(admin::put_settings)) .route("/landing", get(landing::admin_get_landing).put(landing::admin_put_landing)) .route("/landing/upload-launcher", post(landing::upload_launcher)) .route("/instances", get(admin::list_instances).post(admin::create_instance)) .route("/instances/{id}", get(admin::get_instance).put(admin::update_instance).delete(admin::delete_instance)) .route("/instances/{id}/reset", post(admin::reset_source)) .route("/instances/{id}/import/modrinth", post(admin::import_modrinth)) .route("/instances/{id}/import/curseforge", post(admin::import_curseforge)) .route("/instances/{id}/import/upload", post(admin::import_upload)) .route("/instances/{id}/files", post(admin::upload_files).delete(admin::delete_file)) .route("/uploads", post(admin::upload_media)) .route("/users/{id}/skin", post(admin::admin_set_skin).delete(admin::admin_delete_skin)) .route("/users/{id}/skin/model", axum::routing::put(admin::admin_set_model)) .route("/users/{id}/cape", axum::routing::put(admin::admin_set_cape)) .route("/capes", get(admin::list_capes).post(admin::create_cape)) .route("/capes/{id}", axum::routing::put(admin::update_cape).delete(admin::delete_cape)) .route("/auth-server", get(admin::auth_server_info)) .route("/servers", get(servers::list).post(servers::create)) .route("/servers/{id}", get(servers::detail).put(servers::update).delete(servers::remove)) .route("/servers/{id}/token", post(servers::regenerate_token)) .route("/servers/{id}/livemap", get(livemap::admin_status).delete(livemap::admin_reset)) .route("/users/{id}/activity", get(servers::user_activity)) .route("/meta/minecraft", get(meta::minecraft)) .route("/meta/loaders/{loader}", get(meta::loaders)) .route("/modrinth/search", get(meta::modrinth_search)) .route("/modrinth/project/{id}/versions", get(meta::modrinth_versions)) .route("/curseforge/search", get(meta::curseforge_search)) .route("/curseforge/mod/{id}/files", get(meta::curseforge_files)) // Admin Quests & Achievements & Rewards & Guilds .route("/rewards", get(leveling::list_rewards).post(leveling::admin_create_reward)) .route("/rewards/{id}", put(leveling::admin_update_reward).delete(leveling::admin_delete_reward)) .route("/levels/rewards", get(leveling::list_rewards).post(leveling::admin_create_reward)) .route("/levels/rewards/{id}", put(leveling::admin_update_reward).delete(leveling::admin_delete_reward)) .route("/quests", get(quests::admin_list_quests).post(quests::admin_create_quest)) .route("/quests/{id}", put(quests::admin_update_quest).delete(quests::admin_delete_quest)) .route("/achievements", get(achievements::admin_list_achievements).post(achievements::admin_create_achievement)) .route("/achievements/{id}", put(achievements::admin_update_achievement).delete(achievements::admin_delete_achievement)) .route("/progression", get(progression::get_settings).put(progression::put_settings)) .route("/progression/players", get(progression::list_players)) .route("/progression/players/{uuid}", get(progression::get_player)) .route("/progression/players/{uuid}/adjust", post(progression::adjust_player)) .route("/guilds", get(guilds::admin_list_guilds)) .route("/guilds/{id}", delete(guilds::admin_delete_guild)) .layer(DefaultBodyLimit::max(upload_limit)); // Called by the SCOPENET Paper plugin and Fabric/Forge mods. let game = Router::new() .route("/hello", post(servers::hello)) .route("/login", post(servers::login)) .route("/sync", post(servers::sync)) .route("/guilds/check-chunk", post(guilds::server_check_chunk)) .route("/guilds/claim-snapshot", post(guilds::server_claim_snapshot)) .route("/guilds/claim-index", post(guilds::server_claim_index)) .route("/guilds/claim", post(guilds::server_claim_chunk)) .route("/guilds/unclaim", post(guilds::server_unclaim_chunk)) .route("/guilds/player", post(guilds::server_get_player_guild)) .route("/guilds/create", post(guilds::server_create_guild)) .route("/guilds/leave", post(guilds::server_guild_leave)) .route("/guilds/bank", post(guild_bank::server_bank_info)) .route("/guilds/bank/transfer", post(guild_bank::server_bank_transfer)) .route("/guilds/bank/credit", post(guild_bank::server_bank_credit)) .route("/guilds/bank/pay", post(guild_bank::server_bank_pay)) .route("/economy/balance", post(economy::server_get_balance)) .route("/economy/pay", post(economy::server_transfer)) .route("/economy/transfer", post(economy::server_transfer)) .route("/economy/adjust", post(economy::server_adjust_balance)) .route("/economy/market", post(economy::server_market_read)) .route("/economy/sync-balance", post(economy::server_sync_balance)) .route("/economy/baltop", post(economy::server_baltop)) .route("/economy/market/list", post(economy::server_market_list)) .route("/economy/market/buy", post(economy::server_market_buy)) .layer(DefaultBodyLimit::max(2 * 1024 * 1024)); // Live map ingest: chunk batches are larger than the other game calls. let livemap_game = Router::new() .route("/livemap/config", get(livemap::game_config_route)) .route("/livemap/manifest", get(livemap::game_manifest)) .route("/livemap/chunks", post(livemap::game_chunks)) .route("/livemap/level", post(livemap::game_level)) .route("/livemap/players", post(livemap::game_players)) .route("/livemap/ws", get(livemap::game_ws)) .layer(DefaultBodyLimit::max(10 * 1024 * 1024)); Router::new() .route("/api/livemap/{id}/{dim}/{*path}", get(livemap::proxy)) .nest("/api/v1", launcher) .nest("/api/server/v1", game.merge(livemap_game)) .nest("/api/admin", admin) .merge(crate::yggdrasil::routes().layer(DefaultBodyLimit::max(4 * 1024 * 1024))) .layer(axum::middleware::from_fn_with_state(state.clone(), activity::audit)) }