~starkingdoms/starkingdoms

ref: 352122796ab7c444e7cce1a564e9a2e158f6e9b7 starkingdoms/server/src/main.rs -rw-r--r-- 4.7 KiB
35212279 — ghostlyzsh idk what changed 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// StarKingdoms.IO, an open source browser game
//      Copyright (C) 2023 ghostly_zsh (and contributors, depending on the license you choose)
//
//      <license disclaimer here>

#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![allow(clippy::must_use_candidate)]
#![allow(clippy::too_many_lines)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::missing_panics_doc)]

use crate::manager::{ClientManager};
use crate::timer::timer_main;
use crate::entity::Entity;
use async_std::net::{TcpListener};
use async_std::sync::Arc;
use async_std::sync::RwLock;
use bevy::prelude::*;
use components::PlayerSpawnEvent;
use entity::EntityHandler;
use lazy_static::lazy_static;
use log::{error, info, warn, Level};
use manager::PhysicsData;
use nalgebra::vector;
use parking_lot::deadlock::check_deadlock;
use rapier2d_f64::prelude::{
    BroadPhase, CCDSolver, ColliderSet, ImpulseJointSet, IntegrationParameters, IslandManager,
    MultibodyJointSet, NarrowPhase, RigidBodySet,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::SocketAddr;
use std::thread;
use std::time::Duration;
use crate::tcp_handler::handle_request;

pub mod handler;
pub mod manager;
pub mod timer;
#[macro_use]
pub mod macros;
pub mod api;
pub mod entity;
pub mod module;
pub mod orbit;
pub mod planet;
pub mod tcp_handler;
pub mod components;

const SCALE: f64 = 10.0;

pub const PANIC_ON_DEADLOCK: bool = true;

//noinspection ALL
#[async_std::main]
async fn main() {
    #[allow(clippy::expect_used)]
    {
        simple_logger::init_with_level(Level::Debug).expect("Unable to start logging service");
    }

    info!(
        "StarKingdoms server (v: {}, build {}) - initializing",
        env!("STK_VERSION"),
        env!("STK_BUILD")
    );

    info!("{}", std::mem::size_of::<Entity>());

    if std::env::var("STK_API_KEY").is_err() {
        error!(
            "Unable to read the API key from STK_API_KEY. Ensure it is set, and has a valid value."
        );
        std::process::exit(1);
    }
    if std::env::var("STK_API_URL").is_err() {
        error!("Unable to read the API server URL from STK_API_URL. Ensure it is set, and has a valid value.");
        std::process::exit(1);
    }

    info!("Starting deadlock detector...");

    thread::spawn(move || loop {
        thread::sleep(Duration::from_secs(10));
        let deadlocks = check_deadlock();
        if deadlocks.is_empty() {
            continue;
        }

        error!("---- DEADLOCK DETECTED ----");
        error!("{} deadlocks were detected.", deadlocks.len());
        for (i, threads) in deadlocks.iter().enumerate() {
            error!("-= Deadlock #{}", i);
            for t in threads {
                error!("-= Thread ID = {:#?}", t.thread_id());
                error!("-= Backtrace:\n{:#?}", t.backtrace());
            }
        }
        if PANIC_ON_DEADLOCK {
            error!("StarKingdoms is configured to panic when deadlocks are detected.");
            error!("Bye!");
            panic!("Deadlock detected on one or more threads");
        } else {
            error!("StarKingdoms is not configured to panic when deadlocks are detected.");
        }
    });


    App::new()
        .add_plugins(MinimalPlugins)
        .add_event::<PlayerJoinEvent>()
        .add_systems(Startup, handle_request)
        .run();

    let mgr_timer = CMGR.clone();
    let physics_data = DATA.clone();
    let entities_timer = ENTITIES.clone();
    let _timer_thread = async_std::task::spawn(async move {
        match timer_main(mgr_timer, physics_data, entities_timer).await {
            Ok(_) => (),
            Err(e) => {
                error!("timer thread exited with error: {}", e);
                std::process::exit(1);
            }
        }
    });

    /*let try_socket = TcpListener::bind(&addr).await;

    let listener = match try_socket {
        Ok(l) => l,
        Err(e) => {
            error!("error binding to socket: {}", e);
            std::process::exit(1);
        }
    };

    while let Ok((stream, peer_addr)) = listener.accept().await {
        async_std::task::spawn(handle_request(
            stream,
            peer_addr,
            CMGR.clone(),
            ENTITIES.clone(),
            DATA.clone(),
        ));
    }*/
}

#[derive(Serialize, Deserialize)]
pub struct ServerPingResponse {
    pub version: ServerPingResponseVersion,
    pub players: u32,
    pub description: String,
}

#[derive(Serialize, Deserialize)]
pub struct ServerPingResponseVersion {
    pub name: String,
    pub number: String,
    pub protocol: u32,
    pub channel: String,
    pub build: String,
}