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
43pub const MIGRATIONS: EmbeddedMigrations = diesel_migrations::embed_migrations!("migrations");
45
46fn run_migration(conn: &mut MysqlConnection) {
48 conn.run_pending_migrations(MIGRATIONS).unwrap();
49}
50
51#[actix_web::main]
59async fn main() -> std::io::Result<()> {
60 log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
61 info!("Application started");
62 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
122pub 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
150pub 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}