Skip to main content

hvz/
main.rs

1use std::env;
2
3use actix_cors::Cors;
4use actix_web::{App, HttpServer, middleware};
5use diesel::{Connection, MysqlConnection};
6use diesel_migrations::{EmbeddedMigrations, MigrationHarness};
7use dotenv::dotenv;
8use log::info;
9
10pub mod admin;
11pub mod endpoints;
12use endpoints::{
13    admin::revive_zombie,
14    admin::{
15        corpsify, cure_zombie, feed_player, feed_players, get_all_players, get_logs, inject_sql,
16        kill_all_not_at_checkpoint, player_at_checkpoint, player_count, recover_password,
17        revive_human, set_checkpoint,
18    },
19    interactions::{get_interactions, leaderboard, zombie_tree},
20    notifications::{send_notification, subscribe, unsubscribe},
21    player::{
22        change_password, delete_player, edit_player, get_checkpoint, get_other_player, get_pfp,
23        get_player, get_users, login, logout, new_player, pfp, set_pfp,
24    },
25    zombie::{hunt, next_feeding, starvation},
26};
27
28pub mod groupchat;
29pub mod interactions;
30pub mod messages;
31pub mod notifications;
32pub mod player;
33pub mod schema;
34pub mod settings;
35pub mod time;
36use settings::UPLOAD_PATH;
37pub mod token;
38pub mod zombie;
39use zombie::Zombie;
40
41use crate::endpoints::admin::zombies_add_day;
42
43/// Embedded migrations for the application.
44pub const MIGRATIONS: EmbeddedMigrations = diesel_migrations::embed_migrations!("migrations");
45
46/// Runs the pending database migrations.
47fn run_migration(conn: &mut MysqlConnection) {
48    conn.run_pending_migrations(MIGRATIONS).unwrap();
49}
50
51/// Main entry point for the application.
52///
53/// This function initializes the server and routes for the application.
54///
55/// It spawns the zombie death monitor as a background task that runs until the program terminates.
56///
57/// It also creates the necessary directories for file uploads.
58#[actix_web::main]
59async fn main() -> std::io::Result<()> {
60    log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
61    info!("Application started");
62    // Spawn the zombie death monitor as a background task that runs until the program terminates.
63    actix_rt::spawn(async {
64        Zombie::monitor_zombie_death().await;
65    });
66    async_fs::create_dir_all(UPLOAD_PATH).await?;
67    
68    let host = env::var("API_HOST").unwrap_or_else(|_| "127.0.0.1".to_string());
69    let port = 8080;
70    HttpServer::new(|| {
71        let cors = Cors::default()
72            .allow_any_origin()
73            .allow_any_method()
74            .allow_any_header()
75            .max_age(3600);
76        App::new()
77            .wrap(cors)
78            .wrap(middleware::Logger::default())
79            .service(corpsify)
80            .service(cure_zombie)
81            .service(feed_player)
82            .service(feed_players)
83            .service(zombies_add_day)
84            .service(get_all_players)
85            .service(get_logs)
86            .service(inject_sql)
87            .service(kill_all_not_at_checkpoint)
88            .service(player_at_checkpoint)
89            .service(player_count)
90            .service(recover_password)
91            .service(revive_human)
92            .service(revive_zombie)
93            .service(set_checkpoint)
94            .service(change_password)
95            .service(delete_player)
96            .service(edit_player)
97            .service(get_checkpoint)
98            .service(get_pfp)
99            .service(get_other_player)
100            .service(pfp)
101            .service(get_player)
102            .service(get_users)
103            .service(login)
104            .service(logout)
105            .service(new_player)
106            .service(set_pfp)
107            .service(hunt)
108            .service(next_feeding)
109            .service(starvation)
110            .service(get_interactions)
111            .service(leaderboard)
112            .service(zombie_tree)
113            .service(subscribe)
114            .service(unsubscribe)
115            .service(send_notification)
116    })
117    .bind((host, port))?
118    .run()
119    .await
120}
121
122/// This function establishes a connection to the MySQL database.
123///
124/// Note that the connection has to be set in a configuration file called `.env`, with the following format:
125///
126/// ```sh
127/// DATABASE_URL=mysql://username:password@localhost/database_name
128/// ```
129///
130/// # Returns
131/// A `MysqlConnection` object representing the connection to the database.
132///
133/// # Usage
134/// This function is used to establish a connection to the MySQL database. It is usually called with:
135///
136/// ```
137/// let connection = &mut establish_connection();
138/// ```
139pub fn establish_connection() -> MysqlConnection {
140    info!("Retrieving database URL from .env file");
141
142    dotenv().ok();
143
144    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
145
146    MysqlConnection::establish(&database_url)
147        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
148}
149
150/// Retrieves the VAPID keys from environment variables.
151///
152/// # Returns
153/// A `Result` containing a tuple of the VAPID private key, public key, and email.
154///
155/// # Usage
156/// This function is used to retrieve the VAPID keys from environment variables. It is usually called with:
157///
158/// ```
159/// let (vapid_private_key, vapid_public_key, vapid_email) = vapid_keys().unwrap();
160/// ```
161pub fn vapid_keys() -> Result<(String, String, String), String> {
162    let vapid_private_key =
163        std::env::var("VAPID_PRIVATE_KEY").expect("VAPID private key is missing.");
164    let vapid_public_key = std::env::var("VAPID_PUBLIC_KEY").expect("VAPID public key is missing.");
165    let vapid_email = std::env::var("VAPID_EMAIL").expect("VAPID email is missing.");
166
167    Ok((vapid_private_key, vapid_public_key, vapid_email))
168}