Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #[tokio::main]
- async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
- println!("Starting server...");
- let db_user = std::env::var("POSTGRES_USER").unwrap_or("gameserver".to_string());
- let db_password = std::env::var("POSTGRES_PASSWORD").unwrap_or("gameserverpass".to_string());
- let db = std::env::var("POSTGRES_DB").unwrap_or("gameserver_db".to_string());
- let db_port = std::env::var("POSTGRES_PORT").unwrap_or("5432".to_string());
- let db_host = std::env::var("POSTGRES_HOST").unwrap_or("gameserver-postgres".to_string());
- let conn = sqlx::postgres::PgPool::connect(&format!("postgres://{}:{}@{}:{}/{}", db_user, db_password, db_host, db_port, db)).await.unwrap();
- let database = database::Postgres::new(conn);
- let verbose = std::env::var("VERBOSE").is_ok();
- let base_path = std::env::var("SITE_URL")
- .map(|s| {
- let mut s = s.trim().to_string();
- if !s.is_empty() {
- if !s.starts_with('/') { s.insert(0, '/'); }
- if s.ends_with('/') && s != "/" { s.pop(); }
- }
- s
- })
- .unwrap_or_default();
- const ENABLE_K8S_CLIENT: bool = true;
- const ENABLE_INITIAL_CONNECTION: bool = false;
- const FORCE_REBUILD: bool = false;
- const BUILD_DOCKER_IMAGE: bool = true;
- const BUILD_DEPLOYMENT: bool = true;
- let (ws_tx, _) = broadcast::channel::<String>(CHANNEL_BUFFER_SIZE);
- let (tcp_tx, tcp_rx) = mpsc::channel::<Vec<u8>>(CHANNEL_BUFFER_SIZE);
- let mut client: Option<Client> = None;
- if ENABLE_K8S_CLIENT && K8S_WORKS {
- client = Some(Client::try_default().await?);
- }
- let state = AppState {
- tcp_tx: Arc::new(Mutex::new(tcp_tx)),
- tcp_rx: Arc::new(Mutex::new(tcp_rx)),
- ws_tx: ws_tx.clone(),
- base_path: base_path.clone(),
- database,
- client,
- };
- if ENABLE_INITIAL_CONNECTION && state.client.is_some() {
- println!("Trying initial connection...");
- if try_initial_connection(ws_tx.clone(), state.tcp_tx.clone()).await.is_err() || FORCE_REBUILD {
- eprintln!("Initial connection failed or force rebuild enabled");
- if BUILD_DOCKER_IMAGE {
- docker::build_docker_image().await?;
- }
- if BUILD_DEPLOYMENT {
- kubernetes::create_k8s_deployment(state.client.as_ref().unwrap()).await?;
- }
- }
- }
- let bridge_rx = state.tcp_rx.clone();
- let bridge_tx = state.ws_tx.clone();
- tokio::spawn(async move {
- if let Err(e) = connect_to_server(bridge_rx, bridge_tx).await {
- eprintln!("Connection task failed: {}", e);
- }
- });
- let cors = CorsLayer::new()
- .allow_origin(Any)
- .allow_methods([Method::GET, Method::POST])
- .allow_headers(Any);
- let fallback_router = routes_static(state.clone().into());
- let inner = Router::new()
- .route("/api/message", get(get_message))
- .route("/api/nodes", get(get_nodes))
- .route("/api/ws", get(ws_handler))
- .route("/api/users", get(users))
- .route("/api/send", post(receive_message))
- .route("/api/general", post(process_general))
- .route("/api/signin", post(sign_in))
- .route("/api/createuser", post(create_user))
- .route("/api/deleteuser", post(delete_user))
- .merge(fallback_router)
- .with_state(state.clone());
- let app = if base_path.is_empty() || base_path == "/" {
- inner.layer(cors)
- } else {
- Router::new().nest(&base_path, inner).layer(cors)
- };
- let addr: SocketAddr = LocalUrl.parse().unwrap();
- println!("Listening on http://{}{}", addr, base_path);
- // let addr: SocketAddr = "0.0.0.0:8081".parse().unwrap();
- // println!("Listening on http://{}{}", addr, base_path);
- // axum::serve(TcpListener::bind(addr).await?, app).await?;
- // Updated server start:
- let listener = TcpListener::bind(addr).await?;
- axum::serve(listener, app.into_make_service())
- .await?;
- Ok(())
- }
- pub async fn serve_html_with_replacement(
- file: &str,
- state: &AppState,
- ) -> Result<Response<Body>, StatusCode> {
- let path = Path::new("src/svelte/build").join(file);
- if path.extension().and_then(|e| e.to_str()) == Some("html") {
- let html = tokio_fs::read_to_string(&path)
- .await
- .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
- let mut replaced = html.replace(
- "<head>",
- &format!(r#"
- <head>
- <script>window.__sveltekit_base = '[[SITE_URL]]';</script>
- <base href="[[SITE_URL]]/" />
- "#)
- );
- replaced = replaced.replace("[[SITE_URL]]", &state.base_path);
- return Ok(Html(replaced).into_response());
- }
- // For static files (CSS, JS, images), just serve normally
- let bytes = tokio_fs::read(&path)
- .await
- .map_err(|_| StatusCode::NOT_FOUND)?;
- let content_type = from_path(&path).first_or_octet_stream().to_string();
- Ok(Response::builder()
- .header("Content-Type", content_type)
- .body(Body::from(bytes))
- .unwrap())
- }
- async fn handle_static_request(
- Extension(state): Extension<Arc<AppState>>,
- req: Request<Body>,
- ) -> Result<Response<Body>, StatusCode> {
- let base_path = &state.base_path;
- let full_path = req.uri().path();
- // Strip base_path
- let relative_path = full_path.strip_prefix(base_path).unwrap_or(full_path);
- let file = if relative_path == "/" || relative_path.is_empty() {
- "index.html".to_string()
- } else {
- relative_path.trim_start_matches('/').to_string()
- };
- let ext = Path::new(&file)
- .extension()
- .and_then(|e| e.to_str())
- .unwrap_or("");
- if ext == "html" {
- serve_html_with_replacement(&file, &state).await
- } else {
- let path = Path::new("src/svelte/build").join(&file);
- let bytes = tokio_fs::read(&path)
- .await
- .map_err(|_| StatusCode::NOT_FOUND)?;
- let content_type = from_path(&path).first_or_octet_stream().to_string();
- Ok(Response::builder()
- .header("Content-Type", content_type)
- .body(Body::from(bytes))
- .unwrap())
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement