M Cargo.lock => Cargo.lock +3 -2
@@ 511,9 511,9 @@ dependencies = [
[[package]]
name = "async-tungstenite"
-version = "0.21.0"
+version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6d2c69d237cf761215175f390021344f5530101cca8164d69878b8a1779e80c"
+checksum = "ce01ac37fdc85f10a43c43bc582cbd566720357011578a935761075f898baf58"
dependencies = [
"futures-io",
"futures-util",
@@ 3436,6 3436,7 @@ dependencies = [
"log",
"nalgebra",
"parking_lot 0.12.1",
+ "protobuf 3.2.0",
"rand",
"rapier2d-f64",
"reqwest",
M api/src/config.rs => api/src/config.rs +1 -1
@@ 32,7 32,7 @@ pub struct StarkingdomsApiConfig {
pub base: String,
pub game: String,
pub realms: HashMap<String, StarkingdomsApiConfigRealm>,
- pub servers: Vec<String>
+ pub servers: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug)]
M api/src/main.rs => api/src/main.rs +1 -1
@@ 1,5 1,6 @@
use crate::config::CONFIG;
use crate::error::{APIError, APIErrorsResponse};
+use actix_cors::Cors;
use actix_request_identifier::RequestIdentifier;
use actix_web::http::header::HeaderValue;
use actix_web::web::{Data, JsonConfig};
@@ 9,7 10,6 @@ use sea_orm::{ConnectOptions, Database, DatabaseConnection};
use starkingdoms_api_migration::{Migrator, MigratorTrait};
use std::error::Error;
use std::time::Duration;
-use actix_cors::Cors;
use tera::Tera;
pub mod config;
M api/src/routes/mod.rs => api/src/routes/mod.rs +1 -1
@@ 2,4 2,4 @@ pub mod beamin;
pub mod beamout;
pub mod callback;
pub mod select_realm;
-pub mod server_list;>
\ No newline at end of file
+pub mod server_list;
M api/src/routes/select_realm.rs => api/src/routes/select_realm.rs +1 -1
@@ 16,7 16,7 @@ pub struct RealmsListTemplateContext {
#[get("/select-realm")]
pub async fn select_realm(state: Data<AppState>) -> HttpResponse {
- let context = match Context::from_serialize(&RealmsListTemplateContext {
+ let context = match Context::from_serialize(RealmsListTemplateContext {
back_to: format!("{}/callback", CONFIG.base),
realms: CONFIG.realms.clone(),
}) {
M api/src/routes/server_list.rs => api/src/routes/server_list.rs +4 -4
@@ 1,11 1,11 @@
-use actix_web::{get};
+use crate::config::CONFIG;
+use actix_web::get;
use actix_web::web::Json;
use serde::Serialize;
-use crate::config::CONFIG;
#[derive(Serialize)]
pub struct ServerListResponse {
- pub servers: Vec<String>
+ pub servers: Vec<String>,
}
#[get("server-list")]
@@ 13,4 13,4 @@ pub async fn server_list() -> Json<ServerListResponse> {
Json(ServerListResponse {
servers: CONFIG.servers.clone(),
})
-}>
\ No newline at end of file
+}
M assets/dist/spritesheet-125.json => assets/dist/spritesheet-125.json +32 -23
@@ 9,7 9,7 @@
"pivot": { "x": 128, "y": 128 },
"9slicedFrame": { "x": 0, "y": 0, "w": 256, "h": 256 }
},
- "earth.png": {
+ "mars.png": {
"frame": { "x": 0, "y": 256, "w": 256, "h": 256 },
"rotated": false,
"trimmed": false,
@@ 18,7 18,7 @@
"pivot": { "x": 128, "y": 128 },
"9slicedFrame": { "x": 0, "y": 0, "w": 256, "h": 256 }
},
- "moon.png": {
+ "earth.png": {
"frame": { "x": 0, "y": 512, "w": 256, "h": 256 },
"rotated": false,
"trimmed": false,
@@ 27,8 27,17 @@
"pivot": { "x": 128, "y": 128 },
"9slicedFrame": { "x": 0, "y": 0, "w": 256, "h": 256 }
},
+ "moon.png": {
+ "frame": { "x": 0, "y": 768, "w": 256, "h": 256 },
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": { "x": 0, "y": 0, "w": 256, "h": 256 },
+ "sourceSize": { "w": 256, "h": 256 },
+ "pivot": { "x": 128, "y": 128 },
+ "9slicedFrame": { "x": 0, "y": 0, "w": 256, "h": 256 }
+ },
"hearty_party.png": {
- "frame": { "x": 0, "y": 768, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1024, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 37,7 46,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"trackindicator.png": {
- "frame": { "x": 0, "y": 832, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1088, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 46,7 55,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"hearty.png": {
- "frame": { "x": 0, "y": 896, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1152, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 55,7 64,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"autoplr_cfg.png": {
- "frame": { "x": 0, "y": 960, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1216, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 64,7 73,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"autoplr_error.png": {
- "frame": { "x": 0, "y": 1024, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1280, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 73,7 82,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"hearty_ferris.png": {
- "frame": { "x": 0, "y": 1088, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1344, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 82,7 91,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"superthruster_on.png": {
- "frame": { "x": 0, "y": 1152, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1408, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 91,7 100,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"ecothruster_on.png": {
- "frame": { "x": 0, "y": 1216, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1472, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 100,7 109,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"landingthruster_on.png": {
- "frame": { "x": 0, "y": 1280, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1536, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 109,7 118,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"thruster_on.png": {
- "frame": { "x": 0, "y": 1344, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1600, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 118,7 127,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"landingleg.png": {
- "frame": { "x": 0, "y": 1408, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1664, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 127,7 136,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"hub_on.png": {
- "frame": { "x": 0, "y": 1472, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1728, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 136,7 145,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"powerhub_on.png": {
- "frame": { "x": 0, "y": 1536, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1792, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 145,7 154,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"autoplr_on.png": {
- "frame": { "x": 0, "y": 1600, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1856, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 154,7 163,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"superthruster_off.png": {
- "frame": { "x": 0, "y": 1664, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1920, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 163,7 172,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"landingthruster_off.png": {
- "frame": { "x": 0, "y": 1728, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 1984, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 172,7 181,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"thruster_off.png": {
- "frame": { "x": 0, "y": 1792, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 2048, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 181,7 190,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"cargo_on.png": {
- "frame": { "x": 0, "y": 1856, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 2112, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 190,7 199,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"cargo_off.png": {
- "frame": { "x": 0, "y": 1920, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 2176, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 199,7 208,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"hub_off.png": {
- "frame": { "x": 0, "y": 1984, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 2240, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
@@ 208,7 217,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 64, "h": 64 }
},
"powerhub_off.png": {
- "frame": { "x": 0, "y": 2048, "w": 64, "h": 64 },
+ "frame": { "x": 0, "y": 2304, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
M assets/dist/spritesheet-125.png => assets/dist/spritesheet-125.png +0 -0
M assets/dist/spritesheet-375.json => assets/dist/spritesheet-375.json +32 -23
@@ 9,7 9,7 @@
"pivot": { "x": 384, "y": 384 },
"9slicedFrame": { "x": 0, "y": 0, "w": 768, "h": 768 }
},
- "earth.png": {
+ "mars.png": {
"frame": { "x": 0, "y": 768, "w": 768, "h": 768 },
"rotated": false,
"trimmed": false,
@@ 18,7 18,7 @@
"pivot": { "x": 384, "y": 384 },
"9slicedFrame": { "x": 0, "y": 0, "w": 768, "h": 768 }
},
- "moon.png": {
+ "earth.png": {
"frame": { "x": 0, "y": 1536, "w": 768, "h": 768 },
"rotated": false,
"trimmed": false,
@@ 27,8 27,17 @@
"pivot": { "x": 384, "y": 384 },
"9slicedFrame": { "x": 0, "y": 0, "w": 768, "h": 768 }
},
+ "moon.png": {
+ "frame": { "x": 0, "y": 2304, "w": 768, "h": 768 },
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": { "x": 0, "y": 0, "w": 768, "h": 768 },
+ "sourceSize": { "w": 768, "h": 768 },
+ "pivot": { "x": 384, "y": 384 },
+ "9slicedFrame": { "x": 0, "y": 0, "w": 768, "h": 768 }
+ },
"hearty_party.png": {
- "frame": { "x": 0, "y": 2304, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 3072, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 37,7 46,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"trackindicator.png": {
- "frame": { "x": 0, "y": 2496, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 3264, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 46,7 55,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"hearty.png": {
- "frame": { "x": 0, "y": 2688, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 3456, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 55,7 64,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"autoplr_cfg.png": {
- "frame": { "x": 0, "y": 2880, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 3648, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 64,7 73,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"autoplr_error.png": {
- "frame": { "x": 0, "y": 3072, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 3840, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 73,7 82,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"hearty_ferris.png": {
- "frame": { "x": 0, "y": 3264, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 4032, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 82,7 91,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"superthruster_on.png": {
- "frame": { "x": 0, "y": 3456, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 4224, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 91,7 100,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"ecothruster_on.png": {
- "frame": { "x": 0, "y": 3648, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 4416, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 100,7 109,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"landingthruster_on.png": {
- "frame": { "x": 0, "y": 3840, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 4608, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 109,7 118,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"thruster_on.png": {
- "frame": { "x": 0, "y": 4032, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 4800, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 118,7 127,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"landingleg.png": {
- "frame": { "x": 0, "y": 4224, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 4992, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 127,7 136,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"hub_on.png": {
- "frame": { "x": 0, "y": 4416, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 5184, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 136,7 145,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"powerhub_on.png": {
- "frame": { "x": 0, "y": 4608, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 5376, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 145,7 154,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"autoplr_on.png": {
- "frame": { "x": 0, "y": 4800, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 5568, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 154,7 163,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"landingthruster_off.png": {
- "frame": { "x": 0, "y": 4992, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 5760, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 163,7 172,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"superthruster_off.png": {
- "frame": { "x": 0, "y": 5184, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 5952, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 172,7 181,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"thruster_off.png": {
- "frame": { "x": 0, "y": 5376, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 6144, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 181,7 190,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"cargo_on.png": {
- "frame": { "x": 0, "y": 5568, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 6336, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 190,7 199,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"cargo_off.png": {
- "frame": { "x": 0, "y": 5760, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 6528, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 199,7 208,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"hub_off.png": {
- "frame": { "x": 0, "y": 5952, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 6720, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
@@ 208,7 217,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 192, "h": 192 }
},
"powerhub_off.png": {
- "frame": { "x": 0, "y": 6144, "w": 192, "h": 192 },
+ "frame": { "x": 0, "y": 6912, "w": 192, "h": 192 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 192, "h": 192 },
M assets/dist/spritesheet-375.png => assets/dist/spritesheet-375.png +0 -0
M assets/dist/spritesheet-full.json => assets/dist/spritesheet-full.json +22 -13
@@ 9,7 9,7 @@
"pivot": { "x": 1024, "y": 1024 },
"9slicedFrame": { "x": 0, "y": 0, "w": 2048, "h": 2048 }
},
- "earth.png": {
+ "mars.png": {
"frame": { "x": 0, "y": 2048, "w": 2048, "h": 2048 },
"rotated": false,
"trimmed": false,
@@ 18,7 18,7 @@
"pivot": { "x": 1024, "y": 1024 },
"9slicedFrame": { "x": 0, "y": 0, "w": 2048, "h": 2048 }
},
- "moon.png": {
+ "earth.png": {
"frame": { "x": 0, "y": 4096, "w": 2048, "h": 2048 },
"rotated": false,
"trimmed": false,
@@ 27,6 27,15 @@
"pivot": { "x": 1024, "y": 1024 },
"9slicedFrame": { "x": 0, "y": 0, "w": 2048, "h": 2048 }
},
+ "moon.png": {
+ "frame": { "x": 2048, "y": 0, "w": 2048, "h": 2048 },
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": { "x": 0, "y": 0, "w": 2048, "h": 2048 },
+ "sourceSize": { "w": 2048, "h": 2048 },
+ "pivot": { "x": 1024, "y": 1024 },
+ "9slicedFrame": { "x": 0, "y": 0, "w": 2048, "h": 2048 }
+ },
"hearty_party.png": {
"frame": { "x": 0, "y": 6144, "w": 512, "h": 512 },
"rotated": false,
@@ 136,7 145,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
"powerhub_on.png": {
- "frame": { "x": 2048, "y": 0, "w": 512, "h": 512 },
+ "frame": { "x": 4096, "y": 0, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 145,7 154,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
"autoplr_on.png": {
- "frame": { "x": 2560, "y": 0, "w": 512, "h": 512 },
+ "frame": { "x": 4608, "y": 0, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 154,7 163,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
"superthruster_off.png": {
- "frame": { "x": 3072, "y": 0, "w": 512, "h": 512 },
+ "frame": { "x": 5120, "y": 0, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 163,7 172,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
"landingthruster_off.png": {
- "frame": { "x": 3584, "y": 0, "w": 512, "h": 512 },
+ "frame": { "x": 5632, "y": 0, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 172,7 181,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
"thruster_off.png": {
- "frame": { "x": 4096, "y": 0, "w": 512, "h": 512 },
+ "frame": { "x": 6144, "y": 0, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 181,7 190,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
"cargo_on.png": {
- "frame": { "x": 4608, "y": 0, "w": 512, "h": 512 },
+ "frame": { "x": 6656, "y": 0, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 190,7 199,7 @@
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
"cargo_off.png": {
- "frame": { "x": 5120, "y": 0, "w": 512, "h": 512 },
+ "frame": { "x": 7168, "y": 0, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 198,8 207,8 @@
"pivot": { "x": 256, "y": 256 },
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
- "hub_off.png": {
- "frame": { "x": 5632, "y": 0, "w": 512, "h": 512 },
+ "powerhub_off.png": {
+ "frame": { "x": 4096, "y": 512, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
@@ 207,8 216,8 @@
"pivot": { "x": 256, "y": 256 },
"9slicedFrame": { "x": 0, "y": 0, "w": 512, "h": 512 }
},
- "powerhub_off.png": {
- "frame": { "x": 6144, "y": 0, "w": 512, "h": 512 },
+ "hub_off.png": {
+ "frame": { "x": 4608, "y": 512, "w": 512, "h": 512 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 512, "h": 512 },
M assets/dist/spritesheet-full.png => assets/dist/spritesheet-full.png +0 -0
A assets/src/mars.svg => assets/src/mars.svg +116 -0
@@ 0,0 1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="2048"
+ height="2048"
+ viewBox="0 0 541.86664 541.86668"
+ version="1.1"
+ id="svg5"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ sodipodi:docname="mars.svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview7"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:zoom="0.38796647"
+ inkscape:cx="778.41778"
+ inkscape:cy="989.77625"
+ inkscape:window-width="1918"
+ inkscape:window-height="1057"
+ inkscape:window-x="0"
+ inkscape:window-y="21"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs2">
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1088">
+ <path
+ id="path1090"
+ style="fill:#da8555;stroke-width:0.0921874"
+ d="M 541.86663,270.93333 A 270.93333,270.93333 0 0 1 270.93333,541.86663 270.93333,270.93333 0 0 1 0,270.93333 270.93333,270.93333 0 0 1 270.93333,0 270.93333,270.93333 0 0 1 541.86663,270.93333 Z" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1092">
+ <path
+ id="path1094"
+ style="fill:#da8555;stroke-width:0.0921874"
+ d="M 541.86663,270.93333 A 270.93333,270.93333 0 0 1 270.93333,541.86663 270.93333,270.93333 0 0 1 0,270.93333 270.93333,270.93333 0 0 1 270.93333,0 270.93333,270.93333 0 0 1 541.86663,270.93333 Z" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1096">
+ <path
+ id="path1098"
+ style="fill:#da8555;stroke-width:0.0921874"
+ d="M 541.86663,270.93333 A 270.93333,270.93333 0 0 1 270.93333,541.86663 270.93333,270.93333 0 0 1 0,270.93333 270.93333,270.93333 0 0 1 270.93333,0 270.93333,270.93333 0 0 1 541.86663,270.93333 Z" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1100">
+ <path
+ id="path1102"
+ style="fill:#da8555;stroke-width:0.0921874"
+ d="M 541.86663,270.93333 A 270.93333,270.93333 0 0 1 270.93333,541.86663 270.93333,270.93333 0 0 1 0,270.93333 270.93333,270.93333 0 0 1 270.93333,0 270.93333,270.93333 0 0 1 541.86663,270.93333 Z" />
+ </clipPath>
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ id="path788"
+ style="fill:#da8555;stroke-width:0.0921874"
+ d="M 541.86664,270.93332 A 270.93332,270.93332 0 0 1 270.93332,541.86664 270.93332,270.93332 0 0 1 0,270.93332 270.93332,270.93332 0 0 1 270.93332,0 270.93332,270.93332 0 0 1 541.86664,270.93332 Z" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 150.27466,13.881843 c 35.72958,11.992447 73.4399,4.96055 73.4399,4.96055 0,0 29.59864,-7.188602 43.63356,5.224678 14.03493,12.413282 26.90074,5.535843 54.50303,-3.573312 27.60228,-9.109154 34.02573,-16.9096246 34.02573,-16.9096246 L 253.70247,-7.2584793 Z"
+ id="path1000"
+ clip-path="url(#clipPath1100)" />
+ <path
+ style="fill:#c4724b;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 290.74464,82.230319 c 40.92916,19.820031 42.26131,36.944871 42.26131,36.944871 0,0 8.58153,23.3741 5.10284,32.68735 -3.47869,9.31326 10.77857,38.26533 22.08763,41.19945 11.30906,2.93413 30.41634,41.50267 42.63379,32.01685 12.21743,-9.48581 33.62497,-28.44722 30.93135,-42.99275 -2.69359,-14.54554 -0.63502,-67.31568 -28.18307,-68.20141 C 378.03044,112.99896 392.72125,82.028254 371.28487,78.709225 349.84851,75.390197 340.64477,46.653706 318.18712,57.397628 295.7295,68.14155 275.47443,74.442076 290.74464,82.230319 Z"
+ id="path1004" />
+ <path
+ style="fill:#c4724b;fill-opacity:1;stroke:none;stroke-width:0.238163px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 204.90853,419.16259 c 73.33571,23.92056 133.85944,17.25742 133.85944,17.25742 l -88.31974,16.88834 c 0,0 73.71257,30.85138 63.70542,41.1298 -10.00716,10.27845 -89.56448,16.823 -98.81147,5.52201 -9.24699,-11.30097 1.35794,-21.1439 -24.82973,-23.56829 -26.18764,-2.42438 -92.058752,-7.47467 -80.5049,-18.22357 11.55383,-10.74892 84.6916,6.94821 83.99168,-8.04389 -0.69994,-14.99208 -15.89188,-21.17089 -8.06113,-27.32 7.83073,-6.14914 18.97043,-3.64182 18.97043,-3.64182 z"
+ id="path1006" />
+ <path
+ style="fill:#c4724b;fill-opacity:1;stroke:none;stroke-width:0.260459px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 218.88032,288.22208 c 62.66042,18.30099 72.3813,34.9639 70.78597,39.83545 -1.59533,4.87156 21.5758,28.36271 68.05737,27.30698 46.48162,-1.05575 116.3579,2.84383 111.4476,25.18047 -4.91028,22.33666 -33.14862,86.4198 -43.36723,85.66296 -10.21862,-0.75684 -70.16394,58.18309 -93.32451,57.10993 -23.16057,-1.07316 -7.36497,23.37388 -7.36497,23.37388 l 188.4428,-91.08357 65.76135,-120.32555 c 0,0 -34.43207,-20.2762 -43.7216,-13.19755 -9.2895,7.07861 -9.36013,-68.7778 -18.53767,-64.99857 -9.17756,3.77921 -18.04556,93.67885 -39.12149,93.54711 -21.07593,-0.13174 -141.24953,-28.44658 -141.24953,-28.44658 0,0 -34.34662,-7.80951 -12.38659,-87.93631 21.96004,-80.12681 -49.23158,53.45259 -49.23158,53.45259 z"
+ id="path1008"
+ clip-path="url(#clipPath1096)" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 160.88427,533.86862 c 52.36478,-16.63456 42.57143,-3.76547 80.89575,-8.99583 38.32432,-5.23036 75.06333,5.63404 75.06333,5.63404 0,0 24.33757,10.91726 34.97718,8.73268 10.63964,-2.18456 -42.85583,13.40416 -42.85583,13.40416 z"
+ id="path1002"
+ clip-path="url(#clipPath1092)" />
+ <path
+ style="fill:#c4724b;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 116.30533,94.068849 C 106.99078,149.35756 98.713053,145.54002 89.239957,158.36081 79.76686,171.18159 78.033286,183.47029 65.7813,176.776 53.529314,170.08171 38.622104,193.16637 34.308647,177.71794 29.995193,162.26951 17.27797,159.13746 17.27797,159.13746 L 41.378975,112.7075 62.182036,66.617889 122.5311,36.735467 137.26652,29.082648 c 0,0 4.30996,9.489217 -4.01468,19.34859 -8.32463,9.859369 -22.42483,13.084765 -22.84053,22.557485 -0.4157,9.472724 5.89402,23.080126 5.89402,23.080126 z"
+ id="path1064"
+ clip-path="url(#clipPath1088)" />
+ <path
+ style="fill:#a46748;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 300.17516,273.48989 c 0,0 -5.09789,23.3929 -13.42544,23.13498 -8.32754,-0.25789 -18.03794,-0.85711 -13.00204,2.58945 5.03589,3.4466 26.76075,22.30097 36.49384,26.09596 9.73307,3.79498 20.09556,22.82955 45.60697,22.0032 25.51142,-0.82632 100.65684,8.94218 85.80774,5.3616 -14.84911,-3.58055 -80.19884,-7.61606 -89.63181,-11.36383 -9.43298,-3.74779 -33.74943,-17.75211 -33.74943,-20.77992 0,-3.02782 -16.29849,-9.02327 -11.09562,-34.39343 5.2029,-25.37018 -7.00421,-12.64801 -7.00421,-12.64801 z"
+ id="path1066" />
+ <path
+ style="fill:#a46748;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 309.99157,78.247006 c 0,0 41.40814,26.653604 41.47225,37.189874 0.0641,10.53627 -7.38243,51.00181 7.90434,58.45479 15.28681,7.45298 33.74872,39.54567 34.89741,32.79277 1.14866,-6.7529 -26.19896,-41.5386 -31.3154,-44.70177 -5.11643,-3.16316 -5.61239,-45.33077 4.29985,-46.71905 9.91222,-1.38828 -57.25845,-37.016614 -57.25845,-37.016614 z"
+ id="path1068" />
+ </g>
+</svg>
M client/index.html => client/index.html +0 -4
@@ 115,9 115,5 @@
width: 100%;
}
- .w-90 {
- width: 90%;
- }
-
</style>
</html>
M client/src/gateway.ts => client/src/gateway.ts +3 -2
@@ 90,7 90,7 @@ export async function gateway_connect(gateway_url: string, username: string): Pr
let handshake_start_msg;
if (global.can_beam_out) {
handshake_start_msg = MessageC2SHello.encode({
- version: 5,
+ version: 6,
requestedUsername: username,
nextState: State.Play,
user: window.localStorage.getItem("user")!,
@@ 98,7 98,7 @@ export async function gateway_connect(gateway_url: string, username: string): Pr
}).finish();
} else {
handshake_start_msg = MessageC2SHello.encode({
- version: 5,
+ version: 6,
requestedUsername: username,
nextState: State.Play,
// @ts-ignore
@@ 196,6 196,7 @@ export async function gateway_connect(gateway_url: string, username: string): Pr
children: pkt.module!.children,
};
global.tree.set(pkt.module!.id, module);
+ global.clicked = null;
} else if (pkt_id == MessageS2CModuleRemove_packetInfo.type) {
let pkt = MessageS2CModuleRemove.decode(pkt_data);
global.clicked = pkt.module!.id;
M client/src/index.ts => client/src/index.ts +39 -9
@@ 1,5 1,5 @@
import {Logger, logSetup} from "./logger";
-import {gateway_connect, GatewayClient, AttachedModule} from "./gateway";
+import {AttachedModule, gateway_connect, GatewayClient} from "./gateway";
import {Player} from "./protocol/player";
import {Planet, PlanetType} from "./protocol/planet";
import {Module, ModuleType} from "./protocol/module";
@@ 7,7 7,15 @@ import {
MessageC2SAuthenticateAndBeamOut,
MessageC2SAuthenticateAndBeamOut_packetInfo,
MessageC2SInput,
- MessageC2SInput_packetInfo, MessageC2SModuleDetach, MessageC2SModuleDetach_packetInfo, MessageC2SModuleGrabBegin, MessageC2SModuleGrabBegin_packetInfo, MessageC2SModuleGrabEnd, MessageC2SModuleGrabEnd_packetInfo, MessageC2SMouseInput, MessageC2SMouseInput_packetInfo
+ MessageC2SInput_packetInfo,
+ MessageC2SModuleDetach,
+ MessageC2SModuleDetach_packetInfo,
+ MessageC2SModuleGrabBegin,
+ MessageC2SModuleGrabBegin_packetInfo,
+ MessageC2SModuleGrabEnd,
+ MessageC2SModuleGrabEnd_packetInfo,
+ MessageC2SMouseInput,
+ MessageC2SMouseInput_packetInfo
} from "./protocol/message_c2s";
import {encode} from "./serde";
import {InputType} from "./protocol/input";
@@ 148,8 156,12 @@ async function client_main(server: string, username: string, texture_quality: st
let rot = -global.modules[i].rotation;
relativeX = relativeX*Math.cos(rot) - relativeY*Math.sin(rot);
relativeY = relativeX*Math.sin(rot) + relativeY*Math.cos(rot);
- if (-25 < relativeX && relativeX < 25) {
- if (-25 < relativeY && relativeY < 25) {
+ let bound = [-25, 25, -25, 25];
+ if (global.modules[i].moduleType == ModuleType.Cargo) {
+ bound = [-18.75, 18.75, -25, 21.875];
+ }
+ if (bound[0] < relativeX && relativeX < bound[1]) {
+ if (bound[2] < relativeY && relativeY < bound[3]) {
let msg = MessageC2SModuleGrabBegin.encode({
moduleId: global.modules[i].id,
worldposX: worldX,
@@ 164,10 176,16 @@ async function client_main(server: string, username: string, texture_quality: st
let relativeX = value.x - worldX;
let relativeY = value.y - worldY;
let rot = -value.rotation;
- relativeX = relativeX*Math.cos(rot) - relativeY*Math.sin(rot);
- relativeY = relativeX*Math.sin(rot) + relativeY*Math.cos(rot);
- if (-25 < relativeX && relativeX < 25) {
- if (-25 < relativeY && relativeY < 25) {
+ let adjustedX = relativeX*Math.cos(rot) - relativeY*Math.sin(rot);
+ let adjustedY = relativeX*Math.sin(rot) + relativeY*Math.cos(rot);
+ let bound = [-25, 25, -25, 25];
+ if (value.module_type == ModuleType.Cargo) {
+ bound = [-18.75, 18.75, -25, 21.875];
+ }
+ if (bound[0] < adjustedX && adjustedX < bound[1]) {
+ if (bound[2] < adjustedY && adjustedY < bound[3]) {
+ console.log("relative: " + relativeX + ", " + relativeY);
+ console.log("adjusted: " + adjustedX + ", " + adjustedY);
let msg = MessageC2SModuleDetach.encode({
moduleId: key,
}).finish();
@@ 211,7 229,6 @@ async function client_main(server: string, username: string, texture_quality: st
for (let i = 0; i < global.modules.length; i++) {
if(global.clicked === global.modules[i].id) {
- global.clicked = null;
let msg = MessageC2SModuleGrabEnd.encode({
moduleId: global.modules[i].id,
worldposX: worldX,
@@ 220,6 237,7 @@ async function client_main(server: string, username: string, texture_quality: st
global.client?.socket.send(encode(MessageC2SModuleGrabEnd_packetInfo.type, msg))
}
}
+ global.clicked = null;
global.client?.socket.send(encode(MessageC2SMouseInput_packetInfo.type, msg))
}
@@ 331,6 349,7 @@ async function client_main(server: string, username: string, texture_quality: st
global.context.moveTo(global.me!.x - global.me!.x, global.me!.y - global.me!.y);
global.context.lineTo(planet.x - global.me!.x, planet.y - global.me!.y);
global.context.stroke();
+ console.log("moon: " + planet.x + ", " + planet.y);
document.getElementById("pos-moon")!.innerText = `Relative to Moon: ${Math.trunc(global.me!.x - planet.x)}, ${Math.trunc(global.me!.y - planet.y)}`
}
@@ 343,6 362,15 @@ async function client_main(server: string, username: string, texture_quality: st
global.context.lineTo(planet.x - global.me!.x, planet.y - global.me!.y);
global.context.stroke();
}
+ } else if (planet.planetType == PlanetType.Mars) {
+ if (global.me !== null) {
+ global.context.beginPath();
+ global.context.strokeStyle = "orange";
+ global.context.lineWidth = 5;
+ global.context.moveTo(global.me!.x - global.me!.x, global.me!.y - global.me!.y);
+ global.context.lineTo(planet.x - global.me!.x, planet.y - global.me!.y);
+ global.context.stroke();
+ }
}
}
@@ 484,6 512,8 @@ function planet_type_to_tex_id(ty: PlanetType): string {
return "earth.png"
} else if (ty == PlanetType.Moon) {
return "moon.png"
+ } else if (ty == PlanetType.Mars) {
+ return "mars.png"
}
return "unknown.png"
}
M client/src/protocol/planet.ts => client/src/protocol/planet.ts +6 -0
@@ 7,6 7,7 @@ export enum PlanetType {
UNKNOWN = 0,
Earth = 1,
Moon = 2,
+ Mars = 3,
UNRECOGNIZED = -1,
}
@@ 21,6 22,9 @@ export function planetTypeFromJSON(object: any): PlanetType {
case 2:
case "Moon":
return PlanetType.Moon;
+ case 3:
+ case "Mars":
+ return PlanetType.Mars;
case -1:
case "UNRECOGNIZED":
default:
@@ 36,6 40,8 @@ export function planetTypeToJSON(object: PlanetType): string {
return "Earth";
case PlanetType.Moon:
return "Moon";
+ case PlanetType.Mars:
+ return "Mars";
case PlanetType.UNRECOGNIZED:
default:
return "UNRECOGNIZED";
M protocol/src/lib.rs => protocol/src/lib.rs +20 -16
@@ 1,11 1,11 @@
use crate::message_c2s::{
MessageC2SAuthenticateAndBeamOut, MessageC2SChat, MessageC2SGoodbye, MessageC2SHello,
MessageC2SInput, MessageC2SModuleDetach, MessageC2SModuleGrabBegin, MessageC2SModuleGrabEnd,
- MessageC2SMouseInput, MessageC2SPing
+ MessageC2SMouseInput, MessageC2SPing,
};
use crate::message_s2c::{
- MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CModulesUpdate,
- MessageS2CModuleAdd, MessageS2CModuleRemove, MessageS2CModuleTreeUpdate,
+ MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CModuleAdd,
+ MessageS2CModuleRemove, MessageS2CModuleTreeUpdate, MessageS2CModulesUpdate,
MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong,
};
use crate::planet::PlanetType;
@@ 14,7 14,7 @@ use protobuf::{Enum, Message};
use std::error::Error;
include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));
-pub const PROTOCOL_VERSION: u32 = 5;
+pub const PROTOCOL_VERSION: u32 = 6;
pub mod api;
@@ 50,7 50,7 @@ impl TryFrom<&[u8]> for MessageC2S {
type Error = Box<dyn Error>;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
- let pkt = starkingdoms_protocol::PacketWrapper::parse_from_bytes(value)?;
+ let pkt = PacketWrapper::parse_from_bytes(value)?;
let deser_pkt = match pkt.packet_id {
_id if _id == message_c2s::message_c2shello::Packet_info::type_.value() as i64 => {
@@ 84,17 84,23 @@ impl TryFrom<&[u8]> for MessageC2S {
_id if _id
== message_c2s::message_c2smodule_grab_begin::Packet_info::type_.value() as i64 =>
{
- MessageC2S::ModuleGrabBegin(MessageC2SModuleGrabBegin::parse_from_bytes(&pkt.packet_data)?)
+ MessageC2S::ModuleGrabBegin(MessageC2SModuleGrabBegin::parse_from_bytes(
+ &pkt.packet_data,
+ )?)
}
_id if _id
== message_c2s::message_c2smodule_grab_end::Packet_info::type_.value() as i64 =>
{
- MessageC2S::ModuleGrabEnd(MessageC2SModuleGrabEnd::parse_from_bytes(&pkt.packet_data)?)
+ MessageC2S::ModuleGrabEnd(MessageC2SModuleGrabEnd::parse_from_bytes(
+ &pkt.packet_data,
+ )?)
}
_id if _id
== message_c2s::message_c2smodule_detach::Packet_info::type_.value() as i64 =>
{
- MessageC2S::ModuleDetach(MessageC2SModuleDetach::parse_from_bytes(&pkt.packet_data)?)
+ MessageC2S::ModuleDetach(MessageC2SModuleDetach::parse_from_bytes(
+ &pkt.packet_data,
+ )?)
}
_id => {
return Err(format!("Unrecognized C2S packet {}", _id).into());
@@ 201,18 207,15 @@ impl TryFrom<&[u8]> for MessageS2C {
)?)
}
_id if _id
- == message_s2c::message_s2cmodule_tree_update::Packet_info::type_.value() as i64 =>
+ == message_s2c::message_s2cmodule_tree_update::Packet_info::type_.value()
+ as i64 =>
{
MessageS2C::ModuleTreeUpdate(MessageS2CModuleTreeUpdate::parse_from_bytes(
&pkt.packet_data,
)?)
}
- _id if _id
- == message_s2c::message_s2cmodule_add::Packet_info::type_.value() as i64 =>
- {
- MessageS2C::ModuleAdd(MessageS2CModuleAdd::parse_from_bytes(
- &pkt.packet_data,
- )?)
+ _id if _id == message_s2c::message_s2cmodule_add::Packet_info::type_.value() as i64 => {
+ MessageS2C::ModuleAdd(MessageS2CModuleAdd::parse_from_bytes(&pkt.packet_data)?)
}
_id if _id
== message_s2c::message_s2cmodule_remove::Packet_info::type_.value() as i64 =>
@@ 287,11 290,12 @@ impl TryInto<Vec<u8>> for MessageS2C {
}
}
-impl planet::PlanetType {
+impl PlanetType {
pub fn as_texture_id(&self) -> String {
match self {
PlanetType::Earth => "earth".to_string(),
PlanetType::Moon => "moon".to_string(),
+ PlanetType::Mars => "mars".to_string(),
PlanetType::UNKNOWN => "missing".to_string(),
}
}
M protocol/src/pbuf/planet.proto => protocol/src/pbuf/planet.proto +1 -0
@@ 12,4 12,5 @@ enum PlanetType {
UNKNOWN = 0;
Earth = 1;
Moon = 2;
+ Mars = 3;
}=
\ No newline at end of file
M server/Cargo.toml => server/Cargo.toml +3 -1
@@ 17,7 17,7 @@ serde_json = "1"
futures = { version = "0.3", default-features = false }
tungstenite = { version = "0.19.0", default-features = false }
-async-tungstenite = "0.21.0"
+async-tungstenite = "0.22.1"
log = "0.4"
simple_logger = "4.1"
@@ 28,6 28,8 @@ nalgebra = "0.32.2"
rand = "0.8.5"
reqwest = "0.11.16"
+protobuf = "3.2.0"
+
parking_lot = { version = "0.12.1", features = ["deadlock_detection"] }
[build-dependencies]
M server/src/api.rs => server/src/api.rs +3 -3
@@ 31,7 31,7 @@ pub async fn load_player_data_from_api(
};
let res = client
- .post(format!("{}/beamin", std::env::var("STK_API_URL").unwrap()))
+ .post(format!("{}/beamin", std::env::var("STK_API_URL")?))
.header("Content-Type", "application/json")
.body(serde_json::to_string(&req_body)?)
.send()
@@ 75,11 75,11 @@ pub async fn save_player_data_to_api(
api_token: internal_token.to_owned(),
user_auth_realm_id: user_id.to_owned(),
user_auth_token: token.to_owned(),
- data: data.to_owned(),
+ data: data.clone(),
};
let res = client
- .post(format!("{}/beamout", std::env::var("STK_API_URL").unwrap()))
+ .post(format!("{}/beamout", std::env::var("STK_API_URL")?))
.header("Content-Type", "application/json")
.body(serde_json::to_string(&req_body)?)
.send()
M server/src/entity.rs => server/src/entity.rs +32 -26
@@ 1,12 1,13 @@
use std::{collections::HashMap, net::SocketAddr, sync::atomic::AtomicU32};
-
use nalgebra::Vector2;
+use protobuf::SpecialFields;
use starkingdoms_protocol::planet::PlanetType;
use crate::{
manager::{ClientHandlerMessage, Player},
+ module::{AttachedModule, Module},
planet::Planet,
- SCALE, module::{Module, AttachedModule},
+ SCALE,
};
pub type EntityId = u32;
@@ 15,9 16,7 @@ static mut ENTITY_ID_COUNT: AtomicU32 = AtomicU32::new(0);
pub fn get_entity_id() -> EntityId {
let last_entity_id = unsafe { &ENTITY_ID_COUNT };
let id = last_entity_id.fetch_add(1, std::sync::atomic::Ordering::AcqRel);
- if id > 4_147_483_600 {
- panic!("No remaining entity ids")
- };
+ assert!(id <= 4_147_483_600, "No remaining entity ids");
id
}
@@ 27,8 26,8 @@ pub struct EntityHandler {
}
impl EntityHandler {
- pub fn new() -> EntityHandler {
- EntityHandler {
+ pub fn new() -> Self {
+ Self {
entities: Entities::new(),
}
}
@@ 42,16 41,17 @@ impl EntityHandler {
ids
}
pub fn get_planet(&self, planet_type: PlanetType) -> Option<Planet> {
- let mut planets = self.get_planets();
- for i in 0..planets.len() {
- if planets[i].planet_type == planet_type {
- planets.remove(i);
+ self.get_planets().iter().find(|u| u.planet_type == planet_type).cloned()
+ }
+ pub fn get_planet_id(&self, planet_type: PlanetType) -> Option<EntityId> {
+ for (id, entity) in &self.entities {
+ if let Entity::Planet(planet) = entity {
+ if planet.planet_type == planet_type {
+ return Some(*id);
+ }
}
}
- if planets.is_empty() {
- return None;
- }
- Some(planets[0].clone())
+ None
}
pub fn get_players(&self) -> Vec<(SocketAddr, Player)> {
@@ 71,7 71,7 @@ impl EntityHandler {
}
}
pub fn get_player_id(&self, addr: SocketAddr) -> Option<EntityId> {
- for (id, entity) in self.entities.iter() {
+ for (id, entity) in &self.entities {
if let Entity::Player(player) = entity {
if player.addr == addr {
return Some(*id);
@@ 83,10 83,7 @@ impl EntityHandler {
pub fn get_player(&self, addr: SocketAddr) -> Option<Player> {
let players = self.get_players();
let player = players.iter().find(|p| p.0 == addr);
- match player {
- Some(p) => Some(p.1.clone()),
- None => None,
- }
+ player.map(|p| p.1.clone())
}
pub fn get_modules(&self) -> Vec<Module> {
let mut modules = Vec::new();
@@ 99,9 96,9 @@ impl EntityHandler {
}
pub fn get_modules_id(&self) -> Vec<(EntityId, Module)> {
let mut modules = Vec::new();
- for (id, entity) in self.entities.clone().into_iter() {
+ for (id, entity) in self.entities.clone() {
if let Entity::Module(module) = entity {
- modules.push((id as u32, module.clone()));
+ modules.push((id, module.clone()));
}
}
modules
@@ 122,7 119,7 @@ impl EntityHandler {
None
}
pub fn get_from_module(&self, p_module: &Module) -> Option<EntityId> {
- for (id, entity) in self.entities.iter() {
+ for (id, entity) in &self.entities {
if let Entity::Module(module) = entity {
if module.handle == p_module.handle {
return Some(*id);
@@ 140,14 137,23 @@ impl EntityHandler {
}
modules
}
+ pub fn get_all_attached_id(&self) -> Vec<(EntityId, AttachedModule)> {
+ let mut modules = Vec::new();
+ for (id, entity) in self.entities.clone() {
+ if let Entity::AttachedModule(module) = entity {
+ modules.push((id, module.clone()));
+ }
+ }
+ modules
+ }
pub fn get_attached_from_id(&self, id: EntityId) -> Option<AttachedModule> {
if let Some(Entity::AttachedModule(module)) = self.entities.get(&id) {
return Some(module.clone());
}
None
}
- pub fn get_id_from_attached(&self, p_module: AttachedModule) -> Option<EntityId> {
- for (id, entity) in self.entities.iter() {
+ pub fn get_id_from_attached(&self, p_module: &AttachedModule) -> Option<EntityId> {
+ for (id, entity) in &self.entities {
if let Entity::AttachedModule(module) = entity {
if module.handle == p_module.handle {
return Some(*id);
@@ 177,7 183,7 @@ impl EntityHandler {
x: planet.position.0 * SCALE,
y: planet.position.1 * SCALE,
radius: planet.radius * SCALE, // DO NOT * SCALE. THIS VALUE IS NOT SCALED! YES IT IS
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
});
}
M server/src/handler.rs => server/src/handler.rs +205 -131
@@ 1,27 1,27 @@
use crate::api::{load_player_data_from_api, save_player_data_to_api};
use crate::entity::{get_entity_id, Entity, EntityHandler};
-use crate::manager::{
- ClientHandlerMessage, ClientManager, Player, PhysicsData,
-};
-use crate::module::{AttachedModule, ModuleTemplate, Module, Attachment};
+use crate::manager::{ClientHandlerMessage, ClientManager, PhysicsData, Player, PlayerInput};
+use crate::module::{AttachedModule, Module};
use crate::{recv, send, SCALE};
use async_std::net::TcpStream;
use async_std::{channel::Receiver, sync::RwLock};
use async_tungstenite::WebSocketStream;
use futures::stream::{SplitSink, SplitStream};
use futures::{FutureExt, SinkExt, StreamExt};
-use log::{debug, error, info, warn, trace};
-use nalgebra::{point, vector, Matrix, Vector2};
+use log::{error, info, warn};
+use nalgebra::{point, vector, Vector2};
use rand::Rng;
use rapier2d_f64::prelude::{
- Collider, ColliderBuilder, MassProperties, RigidBodyBuilder, RigidBodyType, Isometry,
+ Collider, ColliderBuilder, Isometry, MassProperties, RigidBodyBuilder, RigidBodyType,
};
use starkingdoms_protocol::goodbye_reason::GoodbyeReason;
use starkingdoms_protocol::message_s2c::{
- MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CModulesUpdate,
- MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong, MessageS2CModuleAdd, MessageS2CModuleTreeUpdate, MessageS2CModuleRemove,
+ MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CModuleAdd,
+ MessageS2CModuleRemove, MessageS2CModuleTreeUpdate, MessageS2CModulesUpdate,
+ MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong,
};
-use starkingdoms_protocol::module::ModuleType;
+
+use protobuf::SpecialFields;
use starkingdoms_protocol::state::State;
use starkingdoms_protocol::{MessageC2S, MessageS2C, PROTOCOL_VERSION};
use std::error::Error;
@@ 53,7 53,7 @@ pub async fn handle_client(
let msg = MessageS2C::Chat(MessageS2CChat {
from,
message,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 63,7 63,7 @@ pub async fn handle_client(
if matches!(state, State::Play) {
let msg = MessageS2C::PlayersUpdate(MessageS2CPlayersUpdate {
players,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 73,7 73,7 @@ pub async fn handle_client(
if matches!(state, State::Play) {
let msg = MessageS2C::PlanetData(MessageS2CPlanetData {
planets,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 83,7 83,7 @@ pub async fn handle_client(
if matches!(state, State::Play) {
let msg = MessageS2C::ModulesUpdate(MessageS2CModulesUpdate {
modules,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 93,7 93,7 @@ pub async fn handle_client(
if matches!(state, State::Play) {
let msg = MessageS2C::ModuleTreeUpdate(MessageS2CModuleTreeUpdate {
tree: modules,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 109,7 109,7 @@ pub async fn handle_client(
error!("[{}] ping timeout", remote_addr);
let msg = MessageS2C::Goodbye(MessageS2CGoodbye {
reason: GoodbyeReason::PingPongTimeout.into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 123,6 123,8 @@ pub async fn handle_client(
match pkt {
MessageC2S::Hello(pkt) => {
info!("client sent hello");
+ // there is no way to not use unwrap here :/
+ #[allow(clippy::unwrap_used)]
if !matches!(pkt.next_state.unwrap(), State::Play) {
error!(
"client sent unexpected state {:?} (expected: Play)",
@@ 130,7 132,7 @@ pub async fn handle_client(
);
let msg = MessageS2C::Goodbye(MessageS2CGoodbye {
reason: GoodbyeReason::UnexpectedNextState.into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 145,7 147,7 @@ pub async fn handle_client(
);
let msg = MessageS2C::Goodbye(MessageS2CGoodbye {
reason: GoodbyeReason::UnsupportedProtocol.into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 167,7 169,7 @@ pub async fn handle_client(
);
let msg: Vec<u8> = MessageS2C::Goodbye(MessageS2CGoodbye {
reason: GoodbyeReason::UsernameTaken.into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 186,7 188,7 @@ pub async fn handle_client(
let msg = MessageS2C::Hello(MessageS2CHello {
version: pkt.version,
given_username: pkt.requested_username.clone(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
next_state: pkt.next_state,
})
.try_into()?;
@@ 232,7 234,7 @@ pub async fn handle_client(
let mut player = Player {
handle: player_handle,
- input: Default::default(),
+ input: PlayerInput::default(),
addr: remote_addr,
auth_token: None,
auth_user: None,
@@ 252,7 254,7 @@ pub async fn handle_client(
let player_data = match load_player_data_from_api(
&pkt.token,
&pkt.user,
- &std::env::var("STK_API_KEY").unwrap(),
+ &std::env::var("STK_API_KEY")?,
)
.await
{
@@ 284,40 286,6 @@ pub async fn handle_client(
data_handle.rigid_body_set = rigid_body_set;
data_handle.collider_set = collider_set;
-
- /*let module_id = AttachedModule::attach_new(
- &mut data_handle,
- &mut e_write_handle,
- player_id,
- player_id,
- ModuleTemplate {
- translation: vector![0.0, 50.0],
- mass_properties: MassProperties::new(
- point![0.0, 0.0],
- 0.0001,
- 0.005,
- ),
- module_type: ModuleType::Cargo,
- },
- 1,
- );
- let module_id = AttachedModule::attach_new(
- &mut data_handle,
- &mut e_write_handle,
- module_id,
- player_id,
- ModuleTemplate {
- translation: vector![0.0, 50.0],
- mass_properties: MassProperties::new(
- point![0.0, 0.0],
- 0.0001,
- 0.005,
- ),
- module_type: ModuleType::Cargo,
- },
- 2,
- );*/
-
}
}
MessageC2S::Goodbye(pkt) => {
@@ 331,7 299,7 @@ pub async fn handle_client(
);
let msg = MessageS2C::Goodbye(MessageS2CGoodbye {
reason: GoodbyeReason::UnexpectedPacket.into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 347,7 315,7 @@ pub async fn handle_client(
);
let msg = MessageS2C::Goodbye(MessageS2CGoodbye {
reason: GoodbyeReason::UnexpectedPacket.into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 360,7 328,10 @@ pub async fn handle_client(
MessageC2S::Chat(pkt) => {
info!("[{}] CHAT: [{}] {}", remote_addr, username, pkt.message);
- for (_addr, client_thread) in mgr.handlers.read().await.iter() {
+ let read_handle = mgr.handlers.read().await;
+
+ #[allow(clippy::significant_drop_in_scrutinee)] // i know
+ for (_addr, client_thread) in read_handle.iter() {
match client_thread
.tx
.send(ClientHandlerMessage::ChatMessage {
@@ 378,21 349,24 @@ pub async fn handle_client(
}
MessageC2S::Ping(_) => {
let msg = MessageS2C::Pong(MessageS2CPong {
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
ping_timeout = SystemTime::now() + Duration::from_secs(10);
}
+ #[allow(clippy::significant_drop_tightening)]
+ // TODO: Remove when this lint is developed more
MessageC2S::Input(p) => {
let mut handle = entities.write().await;
let id = handle
.get_player_id(remote_addr)
- .expect("could not get player id");
+ .ok_or("could not get player id")?;
+
if let Entity::Player(ref mut me) = handle
.entities
.get_mut(&id)
- .expect("player disconnected but continued to send packets")
+ .ok_or("player disconnected but continued to send packets")?
{
me.input.up = p.up_pressed;
me.input.down = p.down_pressed;
@@ 410,7 384,7 @@ pub async fn handle_client(
.read()
.await
.get_player(remote_addr)
- .expect("Player sending messages after disconnect");
+ .ok_or("Player sending messages after disconnect")?;
if Some(p.token) != player.auth_token || Some(p.user_id) != player.auth_user
{
@@ 420,9 394,13 @@ pub async fn handle_client(
match save_player_data_to_api(
&player.as_api_data(),
- &player.auth_token.unwrap(),
- &player.auth_user.unwrap(),
- &std::env::var("STK_API_KEY").unwrap(),
+ &player
+ .auth_token
+ .ok_or("Tried to beamout without an auth token")?,
+ &player
+ .auth_user
+ .ok_or("Tried to beamout without setting a user")?,
+ &std::env::var("STK_API_KEY")?,
)
.await
{
@@ 430,7 408,7 @@ pub async fn handle_client(
info!("[{}] * Beamed out successfully", remote_addr);
let msg = MessageS2C::Goodbye(MessageS2CGoodbye {
reason: GoodbyeReason::Done.into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
@@ 441,35 419,44 @@ pub async fn handle_client(
}
}
}
- MessageC2S::MouseInput(p) => {
+ MessageC2S::MouseInput(_p) => {
//debug!("[{}] player input: {:?}", remote_addr, p);
}
+ #[allow(clippy::significant_drop_tightening)]
+ // TODO: Remove when this lint is developed more
MessageC2S::ModuleDetach(p) => {
let mut entities = entities.write().await;
let mut data_handle = data.write().await;
- let mut module: Option<AttachedModule> = None;
- debug!("[{}] detach: {:?}", remote_addr, p);
- debug!("[{}] {:?}", remote_addr, entities.entities);
-
+ let module: Option<AttachedModule>;
+ //debug!("[{}] detach: {:?}", remote_addr, p);
+ //debug!("[{}] {:?}", remote_addr, entities.entities);
-
- // START: MY CHANGES
- if let Some(Entity::AttachedModule(p_module)) = entities.entities.get_mut(&p.module_id) {
+ if let Some(Entity::AttachedModule(p_module)) =
+ entities.entities.get_mut(&p.module_id)
+ {
module = Some(p_module.clone());
} else {
warn!("[{}] attempted to detach nonexistent module", remote_addr);
continue;
}
- // END: MY CHANGES
-
-
- let player_id = entities.get_player_id(remote_addr).unwrap();
- let module_id = AttachedModule::detach(&mut data_handle, &mut entities,
- player_id,
- module.unwrap());
- let module = entities.get_module_from_id(module_id).unwrap();
- let body = data_handle.rigid_body_set.get(module.handle).unwrap();
+ let player_id = entities
+ .get_player_id(remote_addr)
+ .ok_or("player does not exist")?;
+ let module_id = AttachedModule::detach(
+ &mut data_handle,
+ &mut entities,
+ player_id,
+ &module.ok_or("cannot detach module that doesn't exist")?,
+ )
+ .ok_or("detach failed")?;
+ let module = entities
+ .get_module_from_id(module_id)
+ .ok_or("player does not exist")?;
+ let body = data_handle
+ .rigid_body_set
+ .get(module.handle)
+ .ok_or("module rigidbody does not exist")?;
let prot_module = starkingdoms_protocol::module::Module {
module_type: module.module_type.into(),
rotation: body.rotation().angle(),
@@ 477,94 464,181 @@ pub async fn handle_client(
y: body.translation().y * SCALE,
id: module_id,
flags: module.flags,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
};
let msg = MessageS2C::ModuleRemove(MessageS2CModuleRemove {
module: Some(prot_module).into(),
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
})
.try_into()?;
send!(client_tx, msg).await?;
}
MessageC2S::ModuleGrabBegin(p) => {
- if let Entity::Module(module) = entities.write().await.entities.get_mut(&p.module_id).unwrap() {
+ if let Entity::Module(_module) = entities
+ .write()
+ .await
+ .entities
+ .get_mut(&p.module_id)
+ .ok_or("module does not exist")?
+ {
//debug!("[{}] grab begin: {:?}, flags: {}", remote_addr, p, module.flags);
}
}
+ #[allow(clippy::significant_drop_tightening)]
+ // TODO: Remove when this lint is developed more
MessageC2S::ModuleGrabEnd(p) => {
let mut entities = entities.write().await;
let mut module: Option<Module> = None;
let mut did_attach = false;
let mut attached_id = None;
- if let Entity::Module(p_module) = entities.entities.get_mut(&p.module_id).unwrap() {
+ if let Entity::Module(p_module) = entities
+ .entities
+ .get_mut(&p.module_id)
+ .ok_or("module does not exist")?
+ {
module = Some(p_module.clone());
- debug!("[{}] grab end: {:?}", remote_addr, p);
+ //debug!("[{}] grab end: {:?}", remote_addr, p);
}
let mut data_handle = data.write().await;
- let player_id = entities.get_player_id(remote_addr).unwrap();
- let player = entities.get_player(remote_addr).unwrap();
- let body = data_handle.rigid_body_set.get(player.handle).unwrap();
- let (x, y) = (body.translation().x - p.worldpos_x/SCALE, body.translation().y - p.worldpos_y/SCALE);
+ let player_id = entities
+ .get_player_id(remote_addr)
+ .ok_or("player entity does not exist")?;
+ let player = entities
+ .get_player(remote_addr)
+ .ok_or("player does not exist")?;
+ let body = data_handle
+ .rigid_body_set
+ .get(player.handle)
+ .ok_or("player rigidbody does not exist")?;
+ let (x, y) = (
+ body.translation().x - p.worldpos_x / SCALE,
+ body.translation().y - p.worldpos_y / SCALE,
+ );
let angle = -body.rotation().angle();
- let (x, y) = (x*angle.cos() - y*angle.sin(), x*angle.sin() + y*angle.cos());
+ let (x, y) = (
+ x.mul_add(angle.cos(), -y * angle.sin()),
+ x.mul_add(angle.sin(), y * angle.cos()),
+ );
if 1.5 < y && y < 3. && -2. < x && x < 2. {
- attached_id = Some(AttachedModule::attach(&mut data_handle, &mut entities,
- player_id,
- player_id, module.clone().unwrap(), 2));
+ attached_id = Some(AttachedModule::attach(
+ &mut data_handle,
+ &mut entities,
+ player_id,
+ player_id,
+ &module.clone().ok_or("module is None")?,
+ 2,
+ ));
did_attach = true;
} else if -3. < y && y < -1.5 && -2. < x && x < 2. {
- attached_id = Some(AttachedModule::attach(&mut data_handle, &mut entities,
- player_id,
- player_id, module.clone().unwrap(), 0));
+ attached_id = Some(AttachedModule::attach(
+ &mut data_handle,
+ &mut entities,
+ player_id,
+ player_id,
+ &module.clone().ok_or("module is None")?,
+ 0,
+ ));
did_attach = true;
} else if -3. < x && x < -1.5 && -2. < y && y < 2. {
- attached_id = Some(AttachedModule::attach(&mut data_handle, &mut entities,
- player_id,
- player_id, module.clone().unwrap(), 3));
+ attached_id = Some(AttachedModule::attach(
+ &mut data_handle,
+ &mut entities,
+ player_id,
+ player_id,
+ &module.clone().ok_or("module is None")?,
+ 3,
+ ));
did_attach = true;
} else if 1.5 < x && x < 3. && -2. < y && y < 2. {
- attached_id = Some(AttachedModule::attach(&mut data_handle, &mut entities,
- player_id,
- player_id, module.clone().unwrap(), 1));
+ attached_id = Some(AttachedModule::attach(
+ &mut data_handle,
+ &mut entities,
+ player_id,
+ player_id,
+ &module.clone().ok_or("module is None")?,
+ 1,
+ ));
did_attach = true;
}
let modules = player.search_modules(&entities);
for attached in modules {
- let body = data_handle.rigid_body_set.get(attached.handle).unwrap();
- let (x, y) = (body.translation().x - p.worldpos_x/SCALE, body.translation().y - p.worldpos_y/SCALE);
+ let body = data_handle
+ .rigid_body_set
+ .get(attached.handle)
+ .ok_or("attached module rigidbody does not exist")?;
+ let (x, y) = (
+ body.translation().x - p.worldpos_x / SCALE,
+ body.translation().y - p.worldpos_y / SCALE,
+ );
let angle = -body.rotation().angle();
- let (x, y) = (x*angle.cos() - y*angle.sin(), x*angle.sin() + y*angle.cos());
- let parent_id = entities.get_id_from_attached(attached).unwrap();
+ let (x, y) = (
+ x.mul_add(angle.cos(), -y * angle.sin()),
+ x.mul_add(angle.sin(), y * angle.cos()),
+ );
+ let parent_id = entities
+ .get_id_from_attached(&attached)
+ .ok_or("attached module does not exist")?;
+
+ // ghostly: this is cursed as hell
+ // please find a better way in the future lmao
if 1.5 < y && y < 3. && -2. < x && x < 2. {
- attached_id = Some(AttachedModule::attach(&mut data_handle, &mut entities,
- parent_id,
- player_id, module.clone().unwrap(), 2));
+ attached_id = Some(AttachedModule::attach(
+ &mut data_handle,
+ &mut entities,
+ parent_id,
+ player_id,
+ &module.clone().ok_or("module does not exist")?,
+ 2,
+ ));
did_attach = true;
} else if -3. < x && x < -1.5 && -2. < y && y < 2. {
- attached_id = Some(AttachedModule::attach(&mut data_handle, &mut entities,
- parent_id,
- player_id, module.clone().unwrap(), 3));
+ attached_id = Some(AttachedModule::attach(
+ &mut data_handle,
+ &mut entities,
+ parent_id,
+ player_id,
+ &module.clone().ok_or("module does not exist")?,
+ 3,
+ ));
did_attach = true;
} else if 1.5 < x && x < 3. && -2. < y && y < 2. {
- attached_id = Some(AttachedModule::attach(&mut data_handle, &mut entities,
- parent_id,
- player_id, module.clone().unwrap(), 1));
+ attached_id = Some(AttachedModule::attach(
+ &mut data_handle,
+ &mut entities,
+ parent_id,
+ player_id,
+ &module.clone().ok_or("module does not exist")?,
+ 1,
+ ));
did_attach = true;
}
}
- if did_attach == false {
- let body = data_handle.rigid_body_set.get_mut(module.unwrap().handle).unwrap();
- body.set_position(Isometry::new(Vector2::new(p.worldpos_x/SCALE, p.worldpos_y/SCALE),body.rotation().angle()), true);
+ if !did_attach {
+ let body = data_handle
+ .rigid_body_set
+ .get_mut(module.ok_or("module does not exist")?.handle)
+ .ok_or("module rigidbody does not exist")?;
+ body.set_position(
+ Isometry::new(
+ Vector2::new(p.worldpos_x / SCALE, p.worldpos_y / SCALE),
+ body.rotation().angle(),
+ ),
+ true,
+ );
+ } else if let Some(Ok(id)) = attached_id {
+ let prot_module = entities
+ .get_attached_from_id(id)
+ .ok_or("attached module does not exist")?
+ .to_protocol(&entities, &data_handle.rigid_body_set);
+ let msg = MessageS2C::ModuleAdd(MessageS2CModuleAdd {
+ module: Some(prot_module.ok_or("attached module does not exist")?)
+ .into(),
+ special_fields: SpecialFields::default(),
+ })
+ .try_into()?;
+ send!(client_tx, msg).await?;
} else {
- if let Some(Ok(id)) = attached_id {
- let prot_module = entities.get_attached_from_id(id).unwrap().to_protocol(&entities, &mut data_handle.rigid_body_set);
- let msg = MessageS2C::ModuleAdd(MessageS2CModuleAdd {
- module: Some(prot_module).into(),
- special_fields: Default::default(),
- })
- .try_into()?;
- send!(client_tx, msg).await?;
- }
+ warn!("attached ID does not exist");
}
}
},
M server/src/main.rs => server/src/main.rs +60 -198
@@ 1,28 1,40 @@
-use crate::entity::Entity;
-use crate::handler::handle_client;
-use crate::manager::{ClientHandler, ClientManager};
+// 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 async_std::io::WriteExt;
-use async_std::net::{TcpListener, TcpStream};
+use async_std::net::{TcpListener};
use async_std::sync::Arc;
use async_std::sync::RwLock;
use entity::EntityHandler;
-use futures::StreamExt;
use lazy_static::lazy_static;
-use log::{error, info, warn, Level, debug};
+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, Real,
+ MultibodyJointSet, NarrowPhase, RigidBodySet,
};
use serde::{Deserialize, Serialize};
-use starkingdoms_protocol::PROTOCOL_VERSION;
-use std::error::Error;
+use std::collections::HashMap;
use std::net::SocketAddr;
use std::thread;
use std::time::Duration;
-use parking_lot::deadlock::check_deadlock;
+use crate::tcp_handler::handle_request;
pub mod handler;
pub mod manager;
@@ 31,175 43,17 @@ pub mod timer;
pub mod macros;
pub mod api;
pub mod entity;
+pub mod module;
pub mod orbit;
pub mod planet;
-pub mod module;
+pub mod tcp_handler;
const SCALE: f64 = 10.0;
-async fn handle_request(
- conn: TcpStream,
- remote_addr: SocketAddr,
- mgr: ClientManager,
- entities: Arc<RwLock<EntityHandler>>,
- physics_data: Arc<RwLock<PhysicsData>>,
-) {
- match _handle_request(conn, remote_addr, mgr, entities, physics_data).await {
- Ok(_) => (),
- Err(e) => {
- error!("[{}] error in handler thread: {}", remote_addr, e);
- }
- }
-}
-
-async fn _handle_request(
- mut conn: TcpStream,
- remote_addr: SocketAddr,
- mgr: ClientManager,
- entities: Arc<RwLock<EntityHandler>>,
- physics_data: Arc<RwLock<PhysicsData>>,
-) -> Result<(), Box<dyn Error>> {
- let mut peek_buf = [0u8; 9];
-
- loop {
- let read = conn.peek(&mut peek_buf).await?;
- if read == 9 {
- break;
- }
- }
-
- if peek_buf == *b"GET /ping" {
- info!("[{}] incoming http connection", remote_addr);
- let ping_resp = serde_json::to_string(&ServerPingResponse {
- version: ServerPingResponseVersion {
- name: env!("STK_VERSION_NAME").to_string(), // Set by build.rs
- number: env!("STK_VERSION").to_string(), // Set by build.rs
- protocol: PROTOCOL_VERSION,
- channel: env!("STK_CHANNEL").to_string(),
- build: env!("STK_BUILD").to_string(),
- },
- players: CMGR.usernames.read().await.len() as u32,
- description: env!("STK_SLP_DESCRIPTION").to_string(),
- })
- .unwrap();
-
- let resp_str = format!(
- "HTTP/1.0 200 OK\nAccess-Control-Allow-Origin: *\nContent-Length: {}\n\n{}",
- ping_resp.len(),
- ping_resp
- );
- let http_resp = resp_str.as_bytes();
-
- conn.write_all(http_resp).await?;
- info!(
- "[{}] sent ping response (200 OK {} bytes)",
- remote_addr,
- ping_resp.len()
- );
- return Ok(());
- }
- info!("[{}] incoming websocket connection", remote_addr);
-
- // if its not GET /ping, assume its websocket and attempt to handshake with them
- let ws_stream = async_tungstenite::accept_async(conn).await?;
-
- let (ws_write, ws_read) = ws_stream.split();
-
- let (tx, rx) = async_std::channel::unbounded();
-
- let client = ClientHandler { tx };
-
- // Acquire the write lock in a small scope, so it's dropped as quickly as possible
- {
- mgr.handlers.write().await.insert(remote_addr, client);
- }
-
- info!("[{}] passing to client handler", remote_addr);
-
- //forward the stream to the sink to achieve echo
- match handle_client(
- mgr.clone(),
- entities.clone(),
- physics_data.clone(),
- remote_addr,
- rx,
- ws_write,
- ws_read,
- )
- .await
- {
- Ok(_) => (),
- Err(e) if e.is::<async_tungstenite::tungstenite::error::Error>() => {
- let e = e
- .downcast::<async_tungstenite::tungstenite::error::Error>()
- .unwrap();
- if matches!(*e, async_tungstenite::tungstenite::Error::ConnectionClosed) {
- info!("[{}] connection closed normally", remote_addr);
- } else {
- error!("[{}] error in client thread: {}", remote_addr, e);
- }
- }
- Err(e) => {
- error!("[{}] error in client thread: {}", remote_addr, e);
- }
- }
-
- // clean up values left over
- {
- mgr.handlers.write().await.remove(&remote_addr);
- mgr.usernames.write().await.remove(&remote_addr);
- // remove player physics body
- let mut entity_write = entities.write().await;
- let mut data = physics_data.write().await;
- let mut rigid_body_set = data.rigid_body_set.clone();
- let mut island_manager = data.island_manager.clone();
- let mut collider_set = data.collider_set.clone();
- let mut impulse_joint_set = data.impulse_joint_set.clone();
- let mut multibody_joint_set = data.multibody_joint_set.clone();
- let player_id = match entity_write.get_player_id(remote_addr) {
- Some(s) => s,
- None => {
- warn!("[{}] player missing from entities.players", remote_addr);
- return Err("Player missing from entities.players".into());
- }
- };
- if let Entity::Player(player) = entity_write.entities.get(&player_id).unwrap() {
- rigid_body_set.remove(
- player.handle,
- &mut island_manager,
- &mut collider_set,
- &mut impulse_joint_set,
- &mut multibody_joint_set,
- true,
- );
- for module in player.search_modules(&entity_write) {
- rigid_body_set.remove(
- module.handle,
- &mut island_manager,
- &mut collider_set,
- &mut impulse_joint_set,
- &mut multibody_joint_set,
- true,
- );
- let module_id = entity_write.get_id_from_attached(module).unwrap();
- entity_write.entities.remove(&module_id);
- }
- }
- data.rigid_body_set = rigid_body_set;
- data.collider_set = collider_set;
- data.island_manager = island_manager;
- data.impulse_joint_set = impulse_joint_set;
- data.multibody_joint_set = multibody_joint_set;
- entity_write.entities.remove(&player_id);
- }
-
- Ok(())
-}
-
lazy_static! {
static ref CMGR: ClientManager = ClientManager {
- handlers: Arc::new(RwLock::new(Default::default())),
- usernames: Arc::new(RwLock::new(Default::default())),
+ handlers: Arc::new(RwLock::new(HashMap::default())),
+ usernames: Arc::new(RwLock::new(HashMap::default())),
};
static ref DATA: Arc<RwLock<PhysicsData>> = Arc::new(RwLock::new(PhysicsData {
gravity: vector![0.0, 0.0],
@@ 207,7 61,7 @@ lazy_static! {
dt: 1.0 / 20.0,
joint_erp: 0.2,
erp: 0.5,
- max_stabilization_iterations: 8,
+ max_stabilization_iterations: 16,
..Default::default()
},
island_manager: IslandManager::new(),
@@ 224,9 78,13 @@ lazy_static! {
pub const PANIC_ON_DEADLOCK: bool = true;
+//noinspection ALL
#[async_std::main]
async fn main() {
- simple_logger::init_with_level(Level::Debug).expect("Unable to start logging service");
+ #[allow(clippy::expect_used)]
+ {
+ simple_logger::init_with_level(Level::Debug).expect("Unable to start logging service");
+ }
info!(
"StarKingdoms server (v: {}, build {}) - initializing",
@@ 247,31 105,29 @@ async fn main() {
info!("Starting deadlock detector...");
- thread::spawn(move || {
- loop {
- thread::sleep(Duration::from_secs(10));
- let deadlocks = check_deadlock();
- if deadlocks.is_empty() {
- continue;
- }
+ 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.");
+ 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.");
+ }
});
let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
@@ 282,7 138,13 @@ async fn main() {
let physics_data = DATA.clone();
let entities_timer = ENTITIES.clone();
let _timer_thread = async_std::task::spawn(async move {
- timer_main(mgr_timer, physics_data, entities_timer).await;
+ 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;
M server/src/manager.rs => server/src/manager.rs +25 -21
@@ 1,24 1,21 @@
use async_std::channel::Sender;
use async_std::sync::RwLock;
-use log::debug;
-use nalgebra::{point, vector};
+
use rapier2d_f64::na::Vector2;
use rapier2d_f64::prelude::{
- BroadPhase, CCDSolver, ColliderBuilder, ColliderSet, FixedJointBuilder, ImpulseJointHandle,
- ImpulseJointSet, IntegrationParameters, IslandManager, Isometry, MassProperties,
- MultibodyJointSet, NarrowPhase, PhysicsPipeline, Real, RigidBodyBuilder, RigidBodyHandle,
- RigidBodySet,
+ BroadPhase, CCDSolver, ColliderSet, ImpulseJointSet, IntegrationParameters, IslandManager,
+ MultibodyJointSet, NarrowPhase, PhysicsPipeline, RigidBodyHandle, RigidBodySet,
};
use starkingdoms_protocol::api::APISavedPlayerData;
-use starkingdoms_protocol::module::ModuleType;
+
use std::collections::HashMap;
-use std::f64::consts::PI;
+
use std::net::SocketAddr;
use std::sync::Arc;
-use crate::entity::{get_entity_id, Entity, EntityHandler, EntityId};
-use crate::SCALE;
-use crate::module::{Attachment, AttachedModule};
+use crate::entity::{Entity, EntityHandler, EntityId};
+
+use crate::module::{AttachedModule, Attachment};
#[derive(Clone)]
pub struct ClientManager {
@@ 37,6 34,7 @@ pub struct Player {
}
impl Player {
+ #[allow(clippy::missing_const_for_fn)] // This will eventually do something, but for now it doesn't
pub fn as_api_data(&self) -> APISavedPlayerData {
APISavedPlayerData {}
}
@@ 45,27 43,32 @@ impl Player {
pub fn search_modules(&self, entities: &EntityHandler) -> Vec<AttachedModule> {
let mut modules = Vec::new();
for attachment in self.children.iter().flatten() {
- if let Entity::AttachedModule(child_module) =
- entities.entities.get(&attachment.child).unwrap()
+ if let Some(Entity::AttachedModule(child_module)) =
+ entities.entities.get(&attachment.child)
{
modules.append(&mut child_module.search_modules(entities));
}
}
modules
}
- pub fn find_parent(&self, module: AttachedModule, entities: &EntityHandler) -> Option<(u8, EntityId)> {
+ pub fn find_parent(
+ &self,
+ module: &AttachedModule,
+ entities: &EntityHandler,
+ ) -> Option<(u8, EntityId)> {
for (slot, attachment) in self.children.iter().enumerate() {
if let Some(attachment) = attachment {
if let Entity::AttachedModule(child_module) =
- entities.entities.get(&attachment.child).unwrap()
+ entities.entities.get(&attachment.child)?
{
- debug!("player child: {:?}", *child_module);
- debug!("player target: {:?}", module);
- if *child_module == module {
- return Some((slot as u8, entities.get_player_id(self.addr).unwrap()));
+ if *child_module == *module {
+ return Some((
+ u8::try_from(slot).ok()?,
+ entities.get_player_id(self.addr)?,
+ ));
}
- let parent = child_module.find_parent(module.clone(), entities);
- if let Some(_) = parent {
+ let parent = child_module.find_parent(module, entities);
+ if parent.is_some() {
return parent;
}
}
@@ 76,6 79,7 @@ impl Player {
}
#[derive(Default, Clone, Debug)]
+#[allow(clippy::struct_excessive_bools)]
pub struct PlayerInput {
pub up: bool,
pub left: bool,
M server/src/module.rs => server/src/module.rs +169 -192
@@ 1,11 1,19 @@
+use std::error::Error;
use std::f64::consts::PI;
-use log::debug;
-use nalgebra::{Vector2, point, vector, Isometry, Isometry2, Complex, Unit};
-use rapier2d_f64::prelude::{RigidBodyHandle, Real, MassProperties, ColliderBuilder, RigidBodyBuilder, FixedJointBuilder, ImpulseJointHandle, RigidBodySet};
+use nalgebra::{point, vector, Isometry2, Unit, Vector2};
+use protobuf::SpecialFields;
+use rapier2d_f64::prelude::{
+ ColliderBuilder, FixedJointBuilder, ImpulseJointHandle, MassProperties, Real, RigidBodyBuilder,
+ RigidBodyHandle, RigidBodySet,
+};
use starkingdoms_protocol::module::ModuleType;
-use crate::{entity::{EntityId, EntityHandler, Entity, get_entity_id}, manager::PhysicsData, SCALE};
+use crate::{
+ entity::{get_entity_id, Entity, EntityHandler, EntityId},
+ manager::PhysicsData,
+ SCALE,
+};
#[derive(Debug, Clone)]
pub struct Module {
@@ 22,7 30,7 @@ pub struct ModuleTemplate {
pub module_type: ModuleType,
}
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AttachedModule {
pub handle: RigidBodyHandle,
pub module_type: ModuleType,
@@ 35,137 43,122 @@ impl AttachedModule {
entities: &mut EntityHandler,
parent: EntityId,
player_id: EntityId,
- module: Module,
+ module: &Module,
attachment_slot: usize,
- ) -> Result<EntityId, ()> {
+ ) -> Result<EntityId, Box<dyn Error + Send + Sync>> {
let mut entity_map = entities.entities.clone();
let parent_entity = entity_map
.get_mut(&parent)
- .expect("parent id does not exist");
+ .ok_or("parent id does not exist")?;
let parent_handle = match parent_entity {
Entity::Player(player) => {
- if let Some(_child) = &player.children[attachment_slot] {
- return Err(());
- } else {
- player.handle
+ if player.children[attachment_slot].is_some() {
+ return Err("already attached".into());
}
- },
+ player.handle
+ }
Entity::AttachedModule(module) => {
- if let Some(_child) = &module.children[attachment_slot] {
- return Err(());
- } else {
- module.handle
+ if module.children[attachment_slot].is_some() {
+ return Err("already attached".into());
}
- },
+ module.handle
+ }
_ => {
panic!("unexpected parent");
}
};
- let parent_body = data.rigid_body_set.get(parent_handle).expect("Parent body does not exist");
+ let parent_body = data
+ .rigid_body_set
+ .get(parent_handle)
+ .ok_or("parent body does not exist")?;
let parent_pos = vector![parent_body.translation().x, parent_body.translation().y];
let parent_angle = parent_body.rotation().angle();
- let parent_linvel = parent_body.linvel().clone();
+ let parent_linvel = *parent_body.linvel();
let parent_angvel = parent_body.angvel();
let (anchor, rotation) = match attachment_slot {
- 0 => {
- (point![
- 0. / SCALE,
- 53. / SCALE
- ], PI)
- }
- 1 => {
- (point![
- -53. / SCALE,
- 0. / SCALE
- ], -PI/2.)
- }
- 2 => {
- (point![
- 0. / SCALE,
- -53. / SCALE
- ], 0.)
- }
- 3 => {
- (point![
- 53. / SCALE,
- 0. / SCALE
- ], PI/2.)
- }
- _ => {
- (point![
- 0. / SCALE,
- 53. / SCALE
- ], 0.)
- }
+ 0 => (point![0. / SCALE, 53. / SCALE], PI),
+ 1 => (point![-53. / SCALE, 0. / SCALE], -PI / 2.),
+ 2 => (point![0. / SCALE, -53. / SCALE], 0.),
+ 3 => (point![53. / SCALE, 0. / SCALE], PI / 2.),
+ _ => (point![0. / SCALE, 53. / SCALE], 0.),
};
- let relative_pos =
- vector![anchor.x * (parent_body.rotation().angle()).cos() +
- anchor.y * -(parent_body.rotation().angle()).sin(),
- anchor.x * (parent_body.rotation().angle()).sin() +
- anchor.y * (parent_body.rotation().angle()).cos()];
- let module_pos = parent_pos + relative_pos;
- let module_body = data.rigid_body_set.get_mut(module.handle).unwrap();
- module_body.set_translation(module_pos, true);
- module_body.set_rotation(Unit::from_angle(parent_angle + rotation), true);
- module_body.set_linvel(parent_linvel, true);
- module_body.set_angvel(parent_angvel, true);
+ if let Some(id) = entities.get_from_module(module) {
+ let relative_pos = vector![
+ anchor.x.mul_add(
+ (parent_body.rotation().angle()).cos(),
+ anchor.y * -(parent_body.rotation().angle()).sin()
+ ),
+ anchor.x.mul_add(
+ (parent_body.rotation().angle()).sin(),
+ anchor.y * (parent_body.rotation().angle()).cos()
+ )
+ ];
+ let module_pos = parent_pos + relative_pos;
+ let module_body = data
+ .rigid_body_set
+ .get_mut(module.handle)
+ .ok_or("module body does not exist")?;
+ module_body.set_translation(module_pos, true);
+ module_body.set_rotation(Unit::from_angle(parent_angle + rotation), true);
+ module_body.set_linvel(parent_linvel, true);
+ module_body.set_angvel(parent_angvel, true);
- let attach_joint = FixedJointBuilder::new()
- .local_anchor1(anchor)
- .local_anchor2(point![0.0, 0.0 / SCALE])
- .local_frame2(Isometry2::rotation(rotation))
- .build();
- let attach_joint_handle =
- data.impulse_joint_set
- .insert(parent_handle, module.handle, attach_joint, true);
- let attached_module = AttachedModule {
- handle: module.handle,
- module_type: module.module_type,
- player_id,
- children: [None, None, None, None],
- };
- let attached_id = get_entity_id();
- match parent_entity {
- Entity::Player(ref mut player) => {
- player.children[attachment_slot] = Some(Attachment {
- child: attached_id,
- connection: attach_joint_handle,
- });
- }
- Entity::AttachedModule(ref mut module) => {
- module.children[attachment_slot] = Some(Attachment {
- child: attached_id,
- connection: attach_joint_handle,
- });
- }
- _ => {
- panic!("unexpected parent");
- }
- };
- entity_map.remove(&entities.get_from_module(&module).unwrap());
- entity_map.insert(attached_id, Entity::AttachedModule(attached_module));
- entities.entities = entity_map;
- Ok(attached_id)
+ let attach_joint = FixedJointBuilder::new()
+ .local_anchor1(anchor)
+ .local_anchor2(point![0.0, 0.0 / SCALE])
+ .local_frame2(Isometry2::rotation(rotation))
+ .build();
+ let attach_joint_handle =
+ data.impulse_joint_set
+ .insert(parent_handle, module.handle, attach_joint, true);
+ let attached_module = Self {
+ handle: module.handle,
+ module_type: module.module_type,
+ player_id,
+ children: [None, None, None, None],
+ };
+ let attached_id = get_entity_id();
+ match parent_entity {
+ Entity::Player(ref mut player) => {
+ player.children[attachment_slot] = Some(Attachment {
+ child: attached_id,
+ connection: attach_joint_handle,
+ });
+ }
+ Entity::AttachedModule(ref mut module) => {
+ module.children[attachment_slot] = Some(Attachment {
+ child: attached_id,
+ connection: attach_joint_handle,
+ });
+ }
+ _ => {
+ panic!("unexpected parent");
+ }
+ };
+ entity_map.remove(&id);
+ entity_map.insert(attached_id, Entity::AttachedModule(attached_module));
+ entities.entities = entity_map;
+ return Ok(attached_id);
+ }
+ Err("entity does not exist".into())
}
pub fn detach(
data: &mut PhysicsData,
entities: &mut EntityHandler,
player_id: EntityId,
- module: AttachedModule,
- ) -> EntityId {
+ module: &Self,
+ ) -> Option<EntityId> {
let mut entity_map = entities.entities.clone();
// player not in parent search
// also no parents included in parent search
- let player = entities.get_player_from_id(player_id).unwrap();
- let (slot, parent_id) = player.find_parent(module.clone(), entities).unwrap();
- let parent_entity = entity_map
- .get_mut(&parent_id)
- .expect("parent id does not exist");
+ let player = entities.get_player_from_id(player_id)?;
+ let (slot, parent_id) = player.find_parent(module, entities)?;
+ let parent_entity = entity_map.get_mut(&parent_id)?;
match parent_entity {
Entity::Player(ref mut player) => {
@@ 192,43 185,38 @@ impl AttachedModule {
lifetime: 0.,
flags: 0,
};
- entity_map.remove(&entities.get_id_from_attached(module.clone()).unwrap());
+ entity_map.remove(&entities.get_id_from_attached(module)?);
let id = get_entity_id();
entity_map.insert(id, Entity::Module(new_module));
for element in tree {
- for child in element.clone().children {
- if let Some(child) = child {
- debug!("child: {:?}", child);
- data.impulse_joint_set.remove(child.connection, true);
- let child_body = entities.get_attached_from_id(child.child).unwrap();
- let new_module = Module {
- handle: child_body.handle,
- module_type: child_body.module_type,
- lifetime: 0.,
- flags: 0,
- };
- entity_map.remove(&entities.get_id_from_attached(child_body.clone()).unwrap());
- let attached_id = get_entity_id();
- entity_map.insert(attached_id, Entity::Module(new_module));
- }
+ for child in element.clone().children.into_iter().flatten() {
+ data.impulse_joint_set.remove(child.connection, true);
+ let child_body = entities.get_attached_from_id(child.child)?;
+ let new_module = Module {
+ handle: child_body.handle,
+ module_type: child_body.module_type,
+ lifetime: 0.,
+ flags: 0,
+ };
+ entity_map.remove(&entities.get_id_from_attached(&child_body)?);
+ let attached_id = get_entity_id();
+ entity_map.insert(attached_id, Entity::Module(new_module));
}
}
entities.entities = entity_map;
- id
+ Some(id)
}
pub fn attach_new(
data: &mut PhysicsData,
entities: &mut EntityHandler,
parent: EntityId,
player_id: EntityId,
- module: ModuleTemplate,
+ module: &ModuleTemplate,
attachment_slot: usize,
- ) -> EntityId {
+ ) -> Option<EntityId> {
let mut entity_map = entities.entities.clone();
- let parent_entity = entity_map
- .get_mut(&parent)
- .expect("parent id does not exist");
+ let parent_entity = entity_map.get_mut(&parent)?;
let parent_handle = match parent_entity {
Entity::Player(player) => player.handle,
Entity::AttachedModule(module) => module.handle,
@@ 237,47 225,27 @@ impl AttachedModule {
}
};
- let parent_body = data.rigid_body_set.get(parent_handle).expect("Parent body does not exist");
+ let parent_body = data.rigid_body_set.get(parent_handle)?;
let parent_pos = vector![parent_body.translation().x, parent_body.translation().y];
let (anchor, rotation) = match attachment_slot {
- 0 => {
- (point![
- 0. / SCALE,
- 53. / SCALE
- ], PI)
- }
- 1 => {
- (point![
- -53. / SCALE,
- 0. / SCALE
- ], -PI/2.)
- }
- 2 => {
- (point![
- 0. / SCALE,
- -53. / SCALE
- ], 0.)
- }
- 3 => {
- (point![
- 53. / SCALE,
- 0. / SCALE
- ], PI/2.)
- }
- _ => {
- (point![
- 0. / SCALE,
- 53. / SCALE
- ], 0.)
- }
+ 0 => (point![0. / SCALE, 53. / SCALE], PI),
+ 1 => (point![-53. / SCALE, 0. / SCALE], -PI / 2.),
+ 2 => (point![0. / SCALE, -53. / SCALE], 0.),
+ 3 => (point![53. / SCALE, 0. / SCALE], PI / 2.),
+ _ => (point![0. / SCALE, 53. / SCALE], 0.),
};
- let relative_pos =
- vector![anchor.x * (parent_body.rotation().angle()).cos() +
- anchor.y * -(parent_body.rotation().angle()).sin(),
- anchor.x * (parent_body.rotation().angle()).sin() +
- anchor.y * (parent_body.rotation().angle()).cos()];
+ let relative_pos = vector![
+ anchor.x.mul_add(
+ (parent_body.rotation().angle()).cos(),
+ anchor.y * -(parent_body.rotation().angle()).sin()
+ ),
+ anchor.x.mul_add(
+ (parent_body.rotation().angle()).sin(),
+ anchor.y * (parent_body.rotation().angle()).cos()
+ )
+ ];
let module_pos = parent_pos + relative_pos;
// create attachment module
@@ 303,7 271,7 @@ impl AttachedModule {
let attach_joint_handle =
data.impulse_joint_set
.insert(parent_handle, attached_handle, attach_joint, true);
- let attached_module = AttachedModule {
+ let attached_module = Self {
handle: attached_handle,
module_type: module.module_type,
player_id,
@@ 329,10 297,10 @@ impl AttachedModule {
};
entity_map.insert(attached_id, Entity::AttachedModule(attached_module));
entities.entities = entity_map;
- attached_id
+ Some(attached_id)
}
// TODO: remove this function
- pub fn to_module(&self) -> Module {
+ pub const fn to_module(&self) -> Module {
Module {
handle: self.handle,
module_type: self.module_type,
@@ 340,45 308,53 @@ impl AttachedModule {
flags: 0,
}
}
+
// TODO: this one too
- pub fn to_module_id(&self, entities: &EntityHandler) -> (EntityId, Module) {
- (entities.get_id_from_attached(self.clone()).unwrap(), Module {
- handle: self.handle,
- module_type: self.module_type,
- lifetime: 10.,
- flags: 1,
- })
+ pub fn to_module_id(&self, entities: &EntityHandler) -> Option<(EntityId, Module)> {
+ Some((
+ entities.get_id_from_attached(self)?,
+ Module {
+ handle: self.handle,
+ module_type: self.module_type,
+ lifetime: 10.,
+ flags: 1,
+ },
+ ))
}
- pub fn to_protocol(&self, entities: &EntityHandler, data: &RigidBodySet) -> starkingdoms_protocol::module::AttachedModule {
- let body = data.get(self.handle).unwrap();
+ pub fn to_protocol(
+ &self,
+ entities: &EntityHandler,
+ data: &RigidBodySet,
+ ) -> Option<starkingdoms_protocol::module::AttachedModule> {
+ let body = data.get(self.handle)?;
let children = self.children.to_vec();
let mut prot_children = Vec::new();
for i in 1..children.len() {
if let Some(Some(child)) = children.get(i) {
prot_children.push(starkingdoms_protocol::module::Attachment {
id: child.child,
- slot: i as u32,
- special_fields: Default::default(),
+ slot: u32::try_from(i).ok()?,
+ special_fields: SpecialFields::default(),
});
}
}
- starkingdoms_protocol::module::AttachedModule {
+ Some(starkingdoms_protocol::module::AttachedModule {
module_type: self.module_type.into(),
rotation: body.rotation().angle(),
x: body.translation().x * SCALE,
y: body.translation().y * SCALE,
- id: entities.get_id_from_attached(self.clone()).unwrap(),
+ id: entities.get_id_from_attached(self)?,
children: prot_children,
- special_fields: Default::default(),
- }
+ special_fields: SpecialFields::default(),
+ })
}
- pub fn search_modules(&self, entities: &EntityHandler) -> Vec<AttachedModule> {
+ pub fn search_modules(&self, entities: &EntityHandler) -> Vec<Self> {
let mut modules = vec![self.clone()];
for attachment in self.children.iter().flatten() {
- if let Entity::AttachedModule(child_module) =
- entities.entities.get(&attachment.child).unwrap()
+ if let Some(Entity::AttachedModule(child_module)) =
+ entities.entities.get(&attachment.child)
{
modules.append(&mut child_module.search_modules(entities));
}
@@ 386,19 362,20 @@ impl AttachedModule {
modules
}
- pub fn find_parent(&self, module: AttachedModule, entities: &EntityHandler) -> Option<(u8, EntityId)> {
+ pub fn find_parent(&self, module: &Self, entities: &EntityHandler) -> Option<(u8, EntityId)> {
for (slot, attachment) in self.children.iter().enumerate() {
if let Some(attachment) = attachment {
if let Entity::AttachedModule(child_module) =
- entities.entities.get(&attachment.child).unwrap()
+ entities.entities.get(&attachment.child)?
{
- debug!("child: {:?}", *child_module);
- debug!("target: {:?}", module);
- if *child_module == module {
- return Some((slot as u8, entities.get_id_from_attached(self.clone()).unwrap()));
+ if *child_module == *module {
+ return Some((
+ u8::try_from(slot).ok()?,
+ entities.get_id_from_attached(self)?,
+ ));
}
- let parent = child_module.find_parent(module.clone(), entities);
- if let Some(_) = parent {
+ let parent = child_module.find_parent(module, entities);
+ if parent.is_some() {
return parent;
}
}
@@ 408,7 385,7 @@ impl AttachedModule {
}
}
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Attachment {
pub child: EntityId,
pub connection: ImpulseJointHandle,
M server/src/orbit/constants.rs => server/src/orbit/constants.rs +24 -9
@@ 1,6 1,6 @@
-pub const GAME_SCALE_DISTANCE: f64 = 0.0001567865; // 1000 / EARTH_RADIUS_RL
-pub const GAME_SCALE_MASS: f64 = 0.0000000000000000000006697923643670463; // 4000 / EARTH_MASS_RL
-pub const GAME_SCALE_TIME: f64 = 0.00051440329218107; // 1200 / MOON_ORBIT_TIME_RL
+pub const GAME_SCALE_DISTANCE: f64 = 0.000_156_786_5; // 1000 / EARTH_RADIUS_RL
+pub const GAME_SCALE_MASS: f64 = 0.000_000_000_000_000_000_000_669_792_364_367_046_3; // 4000 / EARTH_MASS_RL
+pub const GAME_SCALE_TIME: f64 = 0.000_514_403_292_181_07; // 1200 / MOON_ORBIT_TIME_RL
pub const GAME_ORBITS_ENABLED: bool = false;
pub const EARTH_RADIUS_BIAS: f64 = 1.0;
@@ 8,20 8,35 @@ pub const EARTH_MASS_BIAS: f64 = 1.0;
pub const EARTH_RADIUS_RL: f64 = 6_378_100.0;
pub const EARTH_RADIUS: f64 = EARTH_RADIUS_RL * GAME_SCALE_DISTANCE * EARTH_RADIUS_BIAS;
-pub const EARTH_MASS_RL: f64 = 5972000000000000000000000.0;
+pub const EARTH_MASS_RL: f64 = 5_972_000_000_000_000_000_000_000.0;
pub const EARTH_MASS: f64 = EARTH_MASS_RL * GAME_SCALE_MASS * EARTH_MASS_BIAS;
pub const MOON_RADIUS_BIAS: f64 = 1.0;
-pub const MOON_MASS_BIAS: f64 = 10.0;
+pub const MOON_MASS_BIAS: f64 = 2.0;
pub const MOON_PERIAPSIS_BIAS: f64 = 0.1;
pub const MOON_APOAPSIS_BIAS: f64 = 0.1;
pub const MOON_ORBIT_TIME_BIAS: f64 = 1.0;
pub const MOON_RADIUS_RL: f64 = 1_737_400.0;
pub const MOON_RADIUS: f64 = MOON_RADIUS_RL * GAME_SCALE_DISTANCE * MOON_RADIUS_BIAS;
-pub const MOON_MASS_RL: f64 = 73476730900000000000000.0;
+pub const MOON_MASS_RL: f64 = 73_476_730_900_000_000_000_000.0;
pub const MOON_MASS: f64 = MOON_MASS_RL * GAME_SCALE_MASS * MOON_MASS_BIAS;
-pub const MOON_PERIAPSIS: f64 = 363228900.0 * GAME_SCALE_DISTANCE * MOON_PERIAPSIS_BIAS;
-pub const MOON_APOAPSIS: f64 = 405400000.0 * GAME_SCALE_DISTANCE * MOON_APOAPSIS_BIAS;
-pub const MOON_ORBIT_TIME_RL: f64 = 2332800.0;
+pub const MOON_PERIAPSIS: f64 = 363_228_900.0 * GAME_SCALE_DISTANCE * MOON_PERIAPSIS_BIAS;
+pub const MOON_APOAPSIS: f64 = 405_400_000.0 * GAME_SCALE_DISTANCE * MOON_APOAPSIS_BIAS;
+pub const MOON_ORBIT_TIME_RL: f64 = 2_332_800.0;
pub const MOON_ORBIT_TIME: f64 = MOON_ORBIT_TIME_RL * GAME_SCALE_TIME * MOON_ORBIT_TIME_BIAS;
+
+pub const MARS_RADIUS_BIAS: f64 = 1.0;
+pub const MARS_MASS_BIAS: f64 = 10.0;
+pub const MARS_PERIHELION_BIAS: f64 = 0.5;
+pub const MARS_APHELION_BIAS: f64 = 0.5;
+pub const MARS_ORBIT_TIME_BIAS: f64 = 0.2;
+
+pub const MARS_RADIUS_RL: f64 = 3_390_000.0;
+pub const MARS_RADIUS: f64 = MARS_RADIUS_RL * GAME_SCALE_DISTANCE * MARS_RADIUS_BIAS;
+pub const MARS_MASS_RL: f64 = 63_900_000_000_000_000_000_000.0;
+pub const MARS_MASS: f64 = MARS_MASS_RL * GAME_SCALE_MASS * MARS_MASS_BIAS;
+pub const MARS_PERIHELION: f64 = 206_700_000.0 * GAME_SCALE_DISTANCE * MARS_PERIHELION_BIAS;
+pub const MARS_APHELION: f64 = 249_200_000.0 * GAME_SCALE_DISTANCE * MARS_APHELION_BIAS;
+pub const MARS_ORBIT_TIME_RL: f64 = 59_360_000.0;
+pub const MARS_ORBIT_TIME: f64 = MARS_ORBIT_TIME_RL * GAME_SCALE_TIME * MARS_ORBIT_TIME_BIAS;
M server/src/orbit/kepler.rs => server/src/orbit/kepler.rs +1 -1
@@ 3,5 3,5 @@
/// E is the Eccentric Anomaly (angle to where the body is on the ellipse)
/// e is the eccentricity of the orbit (0 = perfect circle, and up to 1 is increasingly elliptical)
pub fn kepler_equation(eccentric_anomaly: f64, mean_anomaly: f64, eccentricity: f64) -> f64 {
- mean_anomaly - eccentric_anomaly + eccentricity * eccentric_anomaly.sin()
+ eccentricity.mul_add(eccentric_anomaly.sin(), mean_anomaly - eccentric_anomaly)
}
M server/src/orbit/newtonian.rs => server/src/orbit/newtonian.rs +1 -1
@@ 1,7 1,7 @@
use crate::orbit::kepler::kepler_equation;
pub const NEWTONIAN_STEP_SIZE: f64 = 0.0001;
-pub const NEWTONIAN_ACCEPTABLE_ERROR: f64 = 0.00000001;
+pub const NEWTONIAN_ACCEPTABLE_ERROR: f64 = 0.000_000_01;
pub fn solve_kepler_with_newtonian(
mean_anomaly: f64,
M server/src/orbit/orbit.rs => server/src/orbit/orbit.rs +12 -5
@@ 16,8 16,9 @@ pub fn calculate_vector_of_orbit(
mass: f64,
step: f64,
) -> Vector2<f64> {
- let semi_major_length = (apoapsis + periapsis) / 2.0;
- let _linear_eccentricity = semi_major_length - periapsis; // distance between center and focus
+ // this doesnt actually do anything
+ //let semi_major_length = (apoapsis + periapsis) / 2.0;
+ //let linear_eccentricity = semi_major_length - periapsis; // distance between center and focus
let target = calculate_world_position_of_orbit(
calculate_point_on_orbit(periapsis, apoapsis, t),
@@ 45,14 46,20 @@ pub fn calculate_point_on_orbit(periapsis: f64, apoapsis: f64, t: f64) -> Vector
let semi_major_length = (apoapsis + periapsis) / 2.0;
let linear_eccentricity = semi_major_length - periapsis; // distance between center and focus
let eccentricity = linear_eccentricity / semi_major_length; // 0: circle. 1: parabola. in between: ellipse
- let semi_minor_length =
- (semi_major_length * semi_major_length - linear_eccentricity * linear_eccentricity).sqrt();
+ let semi_minor_length = semi_major_length
+ .mul_add(
+ semi_major_length,
+ -linear_eccentricity * linear_eccentricity,
+ )
+ .sqrt();
let mean_anomaly = t * std::f64::consts::PI * 2.0;
let eccentric_anomaly = solve_kepler_with_newtonian(mean_anomaly, eccentricity, 100);
let ellipse_center_x = -linear_eccentricity;
- let point_x = eccentric_anomaly.cos() * semi_major_length + ellipse_center_x;
+ let point_x = eccentric_anomaly
+ .cos()
+ .mul_add(semi_major_length, ellipse_center_x);
let point_y = eccentric_anomaly.sin() * semi_minor_length;
vector![point_x, point_y]
M server/src/planet.rs => server/src/planet.rs +36 -17
@@ 1,5 1,5 @@
-use log::debug;
use nalgebra::{vector, Vector2};
+use protobuf::SpecialFields;
use rapier2d_f64::prelude::{
ColliderBuilder, ColliderSet, RigidBodyBuilder, RigidBodyHandle, RigidBodySet,
};
@@ 7,9 7,7 @@ use starkingdoms_protocol::planet::PlanetType;
use std::collections::HashMap;
use crate::entity::{get_entity_id, Entities, Entity, EntityId};
-use crate::orbit::constants::{
- EARTH_MASS, EARTH_RADIUS, MOON_APOAPSIS, MOON_MASS, MOON_PERIAPSIS, MOON_RADIUS,
-};
+use crate::orbit::constants::{EARTH_MASS, EARTH_RADIUS, MARS_APHELION, MARS_MASS, MARS_PERIHELION, MARS_RADIUS, MOON_APOAPSIS, MOON_MASS, MOON_PERIAPSIS, MOON_RADIUS};
use crate::orbit::orbit::{calculate_point_on_orbit, calculate_world_position_of_orbit};
use crate::{manager::ClientHandlerMessage, SCALE};
@@ 26,9 24,7 @@ pub struct Planet {
impl Planet {
pub fn gravity(&self, position: (f64, f64), mass: f64) -> (f64, f64) {
- let distance = ((position.0 - self.position.0).powi(2)
- + (position.1 - self.position.1).powi(2))
- .sqrt();
+ let distance = (position.0 - self.position.0).hypot(position.1 - self.position.1);
let force = GRAVITY * ((self.mass * mass) / (distance * distance));
let mut direction =
Vector2::new(self.position.0 - position.0, self.position.1 - position.1);
@@ 51,7 47,7 @@ impl Planets {
self.planets.get_mut(planet_id)
}
- pub async fn make_planet(
+ pub fn make_planet(
_planet_id: &str,
planet_type: PlanetType,
mass: f64,
@@ 82,13 78,13 @@ impl Planets {
)
}
- pub async fn create_planets(
+ pub fn create_planets(
rigid_body_set: &mut RigidBodySet,
collider_set: &mut ColliderSet,
entities: &mut Entities,
) -> Vec<EntityId> {
let mut planet_ids: Vec<EntityId> = Vec::new();
- let (earth_id, entity) = Planets::make_planet(
+ let (earth_id, entity) = Self::make_planet(
"earth",
PlanetType::Earth,
EARTH_MASS,
@@ 96,13 92,13 @@ impl Planets {
(100.0, 100.0),
rigid_body_set,
collider_set,
- )
- .await;
+ );
entities.insert(earth_id, entity);
planet_ids.push(earth_id);
let moon_start_point;
- if let Entity::Planet(earth) = entities.get(&earth_id).unwrap() {
+ #[allow(clippy::expect_used)]
+ if let Entity::Planet(earth) = entities.get(&earth_id).expect("earth does not exist") {
moon_start_point = calculate_world_position_of_orbit(
calculate_point_on_orbit(MOON_PERIAPSIS, MOON_APOAPSIS, 0.0),
vector![earth.position.0, earth.position.1],
@@ 111,7 107,7 @@ impl Planets {
moon_start_point = vector![0., 0.];
}
- let (moon_id, moon) = Planets::make_planet(
+ let (moon_id, moon) = Self::make_planet(
"moon",
PlanetType::Moon,
MOON_MASS,
@@ 119,10 115,33 @@ impl Planets {
(moon_start_point[0], moon_start_point[1]),
rigid_body_set,
collider_set,
- )
- .await;
+ );
entities.insert(moon_id, moon);
planet_ids.push(moon_id);
+
+ let mars_start_point;
+ #[allow(clippy::expect_used)]
+ if let Entity::Planet(moon) = entities.get(&moon_id).expect("moon does not exist") {
+ mars_start_point = calculate_world_position_of_orbit(
+ calculate_point_on_orbit(MARS_PERIHELION, MARS_APHELION, 0.0),
+ vector![moon.position.0, moon.position.1],
+ );
+ } else {
+ mars_start_point = vector![0., 0.];
+ }
+
+ let (mars_id, mars) = Self::make_planet(
+ "mars",
+ PlanetType::Mars,
+ MARS_MASS,
+ MARS_RADIUS,
+ (mars_start_point[0], mars_start_point[1]),
+ rigid_body_set,
+ collider_set,
+ );
+ entities.insert(mars_id, mars);
+ planet_ids.push(mars_id);
+
planet_ids
}
@@ 136,7 155,7 @@ impl Planets {
x: planet.position.0 * SCALE,
y: planet.position.1 * SCALE,
radius: planet.radius * SCALE, // DO NOT * SCALE - THIS VALUE IS NOT SCALED! YES IT IS
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
});
}
A server/src/tcp_handler.rs => server/src/tcp_handler.rs +176 -0
@@ 0,0 1,176 @@
+use std::error::Error;
+use std::net::SocketAddr;
+use std::sync::Arc;
+use async_std::io::WriteExt;
+use async_std::net::TcpStream;
+use async_std::sync::RwLock;
+use log::{error, info, warn};
+use starkingdoms_protocol::PROTOCOL_VERSION;
+use crate::entity::{Entity, EntityHandler};
+use crate::manager::{ClientHandler, ClientManager, PhysicsData};
+use crate::{CMGR, ServerPingResponse, ServerPingResponseVersion};
+use crate::handler::handle_client;
+use futures::StreamExt;
+
+pub async fn handle_request(
+ conn: TcpStream,
+ remote_addr: SocketAddr,
+ mgr: ClientManager,
+ entities: Arc<RwLock<EntityHandler>>,
+ physics_data: Arc<RwLock<PhysicsData>>,
+) {
+ match _handle_request(conn, remote_addr, mgr, entities, physics_data).await {
+ Ok(_) => (),
+ Err(e) => {
+ error!("[{}] error in handler thread: {}", remote_addr, e);
+ }
+ }
+}
+
+async fn _handle_request(
+ mut conn: TcpStream,
+ remote_addr: SocketAddr,
+ mgr: ClientManager,
+ entities: Arc<RwLock<EntityHandler>>,
+ physics_data: Arc<RwLock<PhysicsData>>,
+) -> Result<(), Box<dyn Error + Sync + Send>> {
+ let mut peek_buf = [0u8; 9];
+
+ loop {
+ let read = conn.peek(&mut peek_buf).await?;
+ if read == 9 {
+ break;
+ }
+ }
+
+ if peek_buf == *b"GET /ping" {
+ info!("[{}] incoming http connection", remote_addr);
+ let ping_resp = serde_json::to_string(&ServerPingResponse {
+ version: ServerPingResponseVersion {
+ name: env!("STK_VERSION_NAME").to_string(), // Set by build.rs
+ number: env!("STK_VERSION").to_string(), // Set by build.rs
+ protocol: PROTOCOL_VERSION,
+ channel: env!("STK_CHANNEL").to_string(),
+ build: env!("STK_BUILD").to_string(),
+ },
+ players: u32::try_from(CMGR.usernames.read().await.len())?,
+ description: env!("STK_SLP_DESCRIPTION").to_string(),
+ })?;
+
+ let resp_str = format!(
+ "HTTP/1.0 200 OK\nAccess-Control-Allow-Origin: *\nContent-Length: {}\n\n{}",
+ ping_resp.len(),
+ ping_resp
+ );
+ let http_resp = resp_str.as_bytes();
+
+ conn.write_all(http_resp).await?;
+ info!(
+ "[{}] sent ping response (200 OK {} bytes)",
+ remote_addr,
+ ping_resp.len()
+ );
+ return Ok(());
+ }
+ info!("[{}] incoming websocket connection", remote_addr);
+
+ // if its not GET /ping, assume its websocket and attempt to handshake with them
+ let ws_stream = async_tungstenite::accept_async(conn).await?;
+
+ let (ws_write, ws_read) = ws_stream.split();
+
+ let (tx, rx) = async_std::channel::unbounded();
+
+ let client = ClientHandler { tx };
+
+ // Acquire the write lock in a small scope, so it's dropped as quickly as possible
+ {
+ mgr.handlers.write().await.insert(remote_addr, client);
+ }
+
+ info!("[{}] passing to client handler", remote_addr);
+
+ //forward the stream to the sink to achieve echo
+ match handle_client(
+ mgr.clone(),
+ entities.clone(),
+ physics_data.clone(),
+ remote_addr,
+ rx,
+ ws_write,
+ ws_read,
+ )
+ .await
+ {
+ Ok(_) => (),
+ Err(e) if e.is::<async_tungstenite::tungstenite::error::Error>() => {
+ #[allow(clippy::expect_used)]
+ let e = {
+ e.downcast::<async_tungstenite::tungstenite::error::Error>()
+ .expect("unable to convert between types safely")
+ };
+
+ if matches!(*e, async_tungstenite::tungstenite::Error::ConnectionClosed) {
+ info!("[{}] connection closed normally", remote_addr);
+ } else {
+ error!("[{}] error in client thread: {}", remote_addr, e);
+ }
+ }
+ Err(e) => {
+ error!("[{}] error in client thread: {}", remote_addr, e);
+ }
+ }
+
+ // clean up values left over
+ {
+ mgr.handlers.write().await.remove(&remote_addr);
+ mgr.usernames.write().await.remove(&remote_addr);
+ // remove player physics body
+ let mut entity_write = entities.write().await;
+ let mut data = physics_data.write().await;
+ let mut rigid_body_set = data.rigid_body_set.clone();
+ let mut island_manager = data.island_manager.clone();
+ let mut collider_set = data.collider_set.clone();
+ let mut impulse_joint_set = data.impulse_joint_set.clone();
+ let mut multibody_joint_set = data.multibody_joint_set.clone();
+ let Some(player_id) = entity_write.get_player_id(remote_addr) else {
+ warn!("[{}] player missing from entities.players", remote_addr);
+ return Err("Player missing from entities.players".into());
+ };
+
+ if let Some(Entity::Player(player)) = entity_write.entities.get(&player_id) {
+ rigid_body_set.remove(
+ player.handle,
+ &mut island_manager,
+ &mut collider_set,
+ &mut impulse_joint_set,
+ &mut multibody_joint_set,
+ true,
+ );
+ for module in player.search_modules(&entity_write) {
+ rigid_body_set.remove(
+ module.handle,
+ &mut island_manager,
+ &mut collider_set,
+ &mut impulse_joint_set,
+ &mut multibody_joint_set,
+ true,
+ );
+ let module_id = entity_write
+ .get_id_from_attached(&module)
+ .ok_or("Tried to remove nonexistent module")?;
+ entity_write.entities.remove(&module_id);
+ }
+ } else {
+ warn!("tried to remove player that doesnt exist: #{}", player_id);
+ }
+ data.rigid_body_set = rigid_body_set;
+ data.collider_set = collider_set;
+ data.island_manager = island_manager;
+ data.impulse_joint_set = impulse_joint_set;
+ data.multibody_joint_set = multibody_joint_set;
+ entity_write.entities.remove(&player_id);
+ }
+
+ Ok(())
+}<
\ No newline at end of file
M server/src/timer.rs => server/src/timer.rs +224 -89
@@ 1,40 1,38 @@
use crate::entity::EntityHandler;
-use crate::module::Module;
-use crate::orbit::constants::{
- GAME_ORBITS_ENABLED, MOON_APOAPSIS, MOON_ORBIT_TIME, MOON_PERIAPSIS,
-};
+use crate::module::{Module, AttachedModule};
+use crate::orbit::constants::{GAME_ORBITS_ENABLED, MARS_APHELION, MARS_ORBIT_TIME, MARS_PERIHELION, MOON_APOAPSIS, MOON_ORBIT_TIME, MOON_PERIAPSIS};
use crate::orbit::orbit::{calculate_point_on_orbit, calculate_world_position_of_orbit};
use crate::{
entity::{get_entity_id, Entity},
manager::{ClientHandlerMessage, ClientManager, PhysicsData},
- planet::{Planet, Planets},
+ planet::Planets,
SCALE,
};
use async_std::sync::RwLock;
use async_std::task::sleep;
-use log::{info, warn, debug};
+use log::warn;
use nalgebra::{point, vector};
+use protobuf::SpecialFields;
use rand::Rng;
-use rapier2d_f64::prelude::{
- ColliderBuilder, MassProperties, PhysicsPipeline, RigidBodyBuilder, RigidBodyHandle,
-};
+use rapier2d_f64::prelude::{ColliderBuilder, MassProperties, PhysicsPipeline, RigidBodyBuilder};
use starkingdoms_protocol::{module::ModuleType, planet::PlanetType, player::Player};
+use std::error::Error;
use std::{f64::consts::PI, sync::Arc, time::Duration};
pub const LATERAL_FORCE: f64 = 0.0002;
pub const MODULE_SPAWN: f64 = 3.0;
pub const MODULE_MAX: u32 = 10;
+//noinspection ALL
pub async fn timer_main(
mgr: ClientManager,
physics_data_orig: Arc<RwLock<PhysicsData>>,
entities: Arc<RwLock<EntityHandler>>,
-) {
+) -> Result<(), Box<dyn Error>> {
let mut pipeline = PhysicsPipeline::new();
let mut time = 0.0;
let mut module_timer = 0.0;
- let _planet_ids;
{
let mut data_handle = physics_data_orig.write().await;
@@ 42,17 40,18 @@ pub async fn timer_main(
let mut rigid_body_set = data_handle.rigid_body_set.clone();
let mut collider_set = data_handle.collider_set.clone();
- _planet_ids = Planets::create_planets(
+ let _ = Planets::create_planets(
&mut rigid_body_set,
&mut collider_set,
&mut entities.write().await.entities,
- )
- .await;
+ );
data_handle.rigid_body_set = rigid_body_set;
data_handle.collider_set = collider_set;
}
+ #[allow(clippy::significant_drop_tightening)]
+ // underdeveloped lint, TODO remove when its better
loop {
sleep(Duration::from_millis(5)).await;
time += 5.0 / 1000.0; // 5ms, time is in seconds
@@ 65,27 64,59 @@ pub async fn timer_main(
// IT MAY ALWAYS BE TRUE
// THATS FINE
if GAME_ORBITS_ENABLED {
- let planets = entities.write().await;
+ let mut planets = entities.write().await;
+ let mut map = planets.entities.clone();
// update earth (nothing changes, yet)
- let earth = planets.get_planet(PlanetType::Earth).unwrap();
- let new_earth_position = vector![earth.position.0, earth.position.1];
-
- // update moon
- let moon: &mut Planet = &mut planets.get_planet(PlanetType::Moon).unwrap();
- let new_moon_position = calculate_world_position_of_orbit(
- calculate_point_on_orbit(MOON_PERIAPSIS, MOON_APOAPSIS, time / MOON_ORBIT_TIME),
- new_earth_position,
- );
- let moon_body = physics_data
- .rigid_body_set
- .get_mut(moon.body_handle)
- .unwrap();
- moon_body.set_next_kinematic_position(new_moon_position.into());
- moon.position = (
- moon_body.translation()[0] / SCALE,
- moon_body.translation()[1] / SCALE,
- );
+ let earth_id = planets.get_planet_id(PlanetType::Earth).ok_or("earth does not exist")?;
+ if let Entity::Planet(earth) = map
+ .get(&earth_id)
+ .ok_or("earth does not exist")? {
+ let new_earth_position = vector![earth.position.0, earth.position.1];
+
+ // update moon
+ let moon_id = planets.get_planet_id(PlanetType::Moon).ok_or("moon does not exist")?;
+ if let Entity::Planet(moon) = map
+ .get_mut(&moon_id)
+ .ok_or("moon does not exist")? {
+ let new_moon_position = calculate_world_position_of_orbit(
+ calculate_point_on_orbit(MOON_PERIAPSIS, MOON_APOAPSIS, time / MOON_ORBIT_TIME),
+ new_earth_position,
+ );
+ let new_moon_position = new_moon_position / SCALE;
+ let moon_body = physics_data
+ .rigid_body_set
+ .get_mut(moon.body_handle)
+ .ok_or("moon does not exist")?;
+ moon_body.set_next_kinematic_translation(new_moon_position);
+ moon.position = (
+ moon_body.translation()[0],
+ moon_body.translation()[1],
+ );
+
+ // update mars
+ let mars_id = planets.get_planet_id(PlanetType::Mars).ok_or("mars does not exist")?;
+ if let Entity::Planet(mars) = map
+ .get_mut(&mars_id)
+ .ok_or("mars does not exist")? {
+ let new_mars_position = calculate_world_position_of_orbit(
+ calculate_point_on_orbit(MARS_PERIHELION, MARS_APHELION, time / MARS_ORBIT_TIME),
+ new_moon_position,
+ );
+ let new_mars_position = new_mars_position/SCALE;
+ let mars_body = physics_data
+ .rigid_body_set
+ .get_mut(mars.body_handle)
+ .ok_or("mars does not exist")?;
+ mars_body.set_next_kinematic_translation(new_mars_position);
+ mars.position = (
+ mars_body.translation()[0],
+ mars_body.translation()[1],
+ );
+ }
+ }
+ }
+ planets.entities = map;
}
physics_data.tick(&mut pipeline);
@@ 102,7 133,7 @@ pub async fn timer_main(
let module_collider = ColliderBuilder::cuboid(18.75 / SCALE, 23.4375 / SCALE)
.translation(vector![0.0, 1.5625 / SCALE])
- .mass_properties(MassProperties::new(point![0.0, 0.0], 0.0001, 0.005))
+ .mass_properties(MassProperties::new(point![0.0, 0.0], 0.000075, 0.005))
.build();
let angle: f64 = {
let mut rng = rand::thread_rng();
@@ 137,9 168,12 @@ pub async fn timer_main(
.insert(get_entity_id(), Entity::Module(module));
}
let mut entities = entities.write().await;
- for module in entities.get_modules().iter_mut() {
+ for module in &mut entities.get_modules() {
let module_handle = module.handle;
- let module_body = physics_data.rigid_body_set.get_mut(module_handle).unwrap();
+ let module_body = physics_data
+ .rigid_body_set
+ .get_mut(module_handle)
+ .ok_or("module does not exist")?;
module_body.reset_forces(true);
module_body.reset_torques(true);
let grav_force = entities.gravity(
@@ 147,8 181,14 @@ pub async fn timer_main(
module_body.mass(),
);
module_body.apply_impulse(vector![grav_force.0, grav_force.1], true);
- let id = entities.get_from_module(module).unwrap();
- if let Entity::Module(p_module) = entities.entities.get_mut(&id).unwrap() {
+ let id = entities
+ .get_from_module(module)
+ .ok_or("module entity does not exist")?;
+ if let Entity::Module(p_module) = entities
+ .entities
+ .get_mut(&id)
+ .ok_or("module does not exist")?
+ {
p_module.lifetime += 5. / 1000.;
}
if module.lifetime > 80. {
@@ 173,9 213,12 @@ pub async fn timer_main(
entities.entities.remove(&id);
}
}
- for module in entities.get_all_attached().iter_mut() {
+ for module in &mut entities.get_all_attached() {
let module_handle = module.handle;
- let module_body = physics_data.rigid_body_set.get_mut(module_handle).unwrap();
+ let module_body = physics_data
+ .rigid_body_set
+ .get_mut(module_handle)
+ .ok_or("module does not exist")?;
module_body.reset_forces(true);
module_body.reset_torques(true);
let grav_force = entities.gravity(
@@ 183,17 226,45 @@ pub async fn timer_main(
module_body.mass(),
);
module_body.apply_impulse(vector![grav_force.0, grav_force.1], true);
+
+ for child in module.children.clone() {
+ if let Some(child) = child {
+ let joint = physics_data.impulse_joint_set
+ .get(child.connection).ok_or("module joint does not exist")?;
+ if joint.impulses.magnitude() > 0.00012 {
+ let module: Option<AttachedModule>;
+ if let Some(Entity::AttachedModule(p_module)) =
+ entities.entities.get_mut(&child.child)
+ {
+ module = Some(p_module.clone());
+ } else {
+ warn!("attempted to detach nonexistent module");
+ continue;
+ }
+ let player_id = module.as_ref().ok_or("cannot detach module that doesn't exist")?.player_id;
+ AttachedModule::detach(
+ &mut physics_data,
+ &mut entities,
+ player_id,
+ &module.ok_or("cannot detach module that doesn't exist")?,
+ );
+ }
+ }
+ }
}
}
{
- for (player_id, player) in entities.read().await.get_players().iter() {
+ let mut entities = entities.write().await;
+ for (player_id, player) in &entities.get_players() {
let player_handle = player.handle;
- let player_body = physics_data.rigid_body_set.get_mut(player_handle).unwrap();
+ let player_body = physics_data
+ .rigid_body_set
+ .get_mut(player_handle)
+ .ok_or("player body does not exist")?;
player_body.reset_forces(true);
player_body.reset_torques(true);
- let planets = entities.read().await;
- let grav_force = planets.gravity(
+ let grav_force = entities.gravity(
(player_body.translation().x, player_body.translation().y),
player_body.mass(),
);
@@ 245,20 316,20 @@ pub async fn timer_main(
right_bottom_thruster / scale * rotation.cos()
];
let top_left_point = point![
- -25. / scale * rotation.cos() + 25. / scale * rotation.sin(),
- -25. / scale * rotation.sin() - 25. / scale * rotation.cos()
+ (-25. / scale).mul_add(rotation.cos(), 25. / scale * rotation.sin()),
+ (-25. / scale).mul_add(rotation.sin(), -25. / scale * rotation.cos())
] + player_body.translation();
let top_right_point = point![
- 25. / scale * rotation.cos() + 25. / scale * rotation.sin(),
- 25. / scale * rotation.sin() - 25. / scale * rotation.cos()
+ (25. / scale).mul_add(rotation.cos(), 25. / scale * rotation.sin()),
+ (25. / scale).mul_add(rotation.sin(), -25. / scale * rotation.cos())
] + player_body.translation();
let bottom_left_point = point![
- -25. / scale * rotation.cos() - 25. / scale * rotation.sin(),
- -25. / scale * rotation.sin() + 25. / scale * rotation.cos()
+ (-25. / scale).mul_add(rotation.cos(), -25. / scale * rotation.sin()),
+ (-25. / scale).mul_add(rotation.sin(), 25. / scale * rotation.cos())
] + player_body.translation();
let bottom_right_point = point![
- 25. / scale * rotation.cos() - 25. / scale * rotation.sin(),
- 25. / scale * rotation.sin() + 25. / scale * rotation.cos()
+ (25. / scale).mul_add(rotation.cos(), -25. / scale * rotation.sin()),
+ (25. / scale).mul_add(rotation.sin(), 25. / scale * rotation.cos())
] + player_body.translation();
player_body.add_force_at_point(left_top_thruster, top_left_point, true);
@@ 271,17 342,47 @@ pub async fn timer_main(
let username;
{
let usernames = mgr.usernames.read().await;
- username = usernames.get(player_id).unwrap().clone();
+ username = usernames
+ .get(player_id)
+ .ok_or("username does not exist")?
+ .clone();
}
- // TODO: Figure out how to adjust codegen to use f64
protocol_players.push(Player {
rotation,
x: (translation.x * SCALE),
y: (translation.y * SCALE),
username,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
});
+
+ for child in player.children.clone() {
+ if let Some(child) = child {
+ let joint = physics_data.impulse_joint_set
+ .get(child.connection).ok_or("module joint does not exist")?;
+ // displays impulse on joint * 10000 so its visible, use to tune breaking
+ // force
+ //debug!("impulse: {}", joint.impulses.magnitude() * 10000.);
+ if joint.impulses.magnitude() > 0.00012 {
+ let module: Option<AttachedModule>;
+ if let Some(Entity::AttachedModule(p_module)) =
+ entities.entities.get_mut(&child.child)
+ {
+ module = Some(p_module.clone());
+ } else {
+ warn!("attempted to detach nonexistent module");
+ continue;
+ }
+ let player_id = module.as_ref().ok_or("cannot detach module that doesn't exist")?.player_id;
+ AttachedModule::detach(
+ &mut physics_data,
+ &mut entities,
+ player_id,
+ &module.ok_or("cannot detach module that doesn't exist")?,
+ );
+ }
+ }
+ }
}
}
@@ 290,7 391,7 @@ pub async fn timer_main(
let mut mgr_w = mgr.handlers.write().await;
let mgr_r = mgr_w.clone();
- for (addr, client_thread) in mgr_r.iter() {
+ for (addr, client_thread) in &mgr_r {
match client_thread.tx.send(ClientHandlerMessage::Tick).await {
Ok(_) => {
match client_thread
@@ 308,44 409,74 @@ pub async fn timer_main(
let modules = entities.read().await.get_modules_id();
let entities = entities.read().await;
let this_player = entities.get_player_id(*addr);
- let mut attached_modules: Vec<starkingdoms_protocol::module::AttachedModule> = Vec::new();
+ let mut attached_modules: Vec<starkingdoms_protocol::module::AttachedModule> =
+ Vec::new();
let unattached_modules = entities.get_all_attached();
- let mut unattached_modules: Vec<starkingdoms_protocol::module::Module> = unattached_modules
- .iter()
- .filter(|m| {
- match this_player {
+ let mut unattached_modules: Vec<starkingdoms_protocol::module::Module> =
+ unattached_modules
+ .iter()
+ .filter(|m| match this_player {
Some(id) => {
- if m.player_id != id {
- true
- } else {
- attached_modules.push(m.to_protocol(&entities, &physics_data.rigid_body_set));
+ if m.player_id == id {
+ #[allow(clippy::expect_used)]
+ {
+ attached_modules.push(
+ m.to_protocol(
+ &entities,
+ &physics_data.rigid_body_set,
+ )
+ .expect("module does not exist"),
+ );
+ }
false
+ } else {
+ true
}
}
- None => {
- true
+ None => true,
+ })
+ .map(|m| {
+ let id;
+ let module;
+ #[allow(clippy::expect_used)]
+ {
+ (id, module) =
+ m.to_module_id(&entities).expect("unable to get module id");
}
- }
- })
- .map(|m| {
- let (id, module) = m.to_module_id(&entities);
- //info!("{:?}", module);
- let body = physics_data.rigid_body_set.get(module.handle).unwrap();
- starkingdoms_protocol::module::Module {
- module_type: module.module_type.into(),
- rotation: body.rotation().angle(),
- x: body.translation().x * SCALE,
- y: body.translation().y * SCALE,
- id,
- flags: module.flags,
- special_fields: Default::default(),
- }
- })
- .collect();
+ //info!("{:?}", module);
+ let body;
+ #[allow(clippy::expect_used)]
+ {
+ body = physics_data
+ .rigid_body_set
+ .get(module.handle)
+ .expect("module body does not exist");
+ }
+
+ starkingdoms_protocol::module::Module {
+ module_type: module.module_type.into(),
+ rotation: body.rotation().angle(),
+ x: body.translation().x * SCALE,
+ y: body.translation().y * SCALE,
+ id,
+ flags: module.flags,
+ special_fields: SpecialFields::default(),
+ }
+ })
+ .collect();
let mut protocol_modules: Vec<starkingdoms_protocol::module::Module> = modules
.iter()
.map(|(id, module)| {
- let body = physics_data.rigid_body_set.get(module.handle).unwrap();
+ let body;
+
+ #[allow(clippy::expect_used)]
+ {
+ body = physics_data
+ .rigid_body_set
+ .get(module.handle)
+ .expect("module body does not exist");
+ }
+
starkingdoms_protocol::module::Module {
module_type: module.module_type.into(),
rotation: body.rotation().angle(),
@@ 353,7 484,7 @@ pub async fn timer_main(
y: body.translation().y * SCALE,
id: *id,
flags: module.flags,
- special_fields: Default::default(),
+ special_fields: SpecialFields::default(),
}
})
.collect();
@@ 371,9 502,13 @@ pub async fn timer_main(
}
};
- match client_thread.tx.send(ClientHandlerMessage::ModuleTreeUpdate {
- modules: attached_modules
- }).await {
+ match client_thread
+ .tx
+ .send(ClientHandlerMessage::ModuleTreeUpdate {
+ modules: attached_modules,
+ })
+ .await
+ {
Ok(_) => (),
Err(e) => {
warn!("unable to send module tree update packet: {}", e);
M spacetime_rs/src/commands/docker.rs => spacetime_rs/src/commands/docker.rs +6 -3
@@ 2,11 2,11 @@ use crate::commands::api::build_api_prod;
use crate::commands::client::build_client_prod;
use crate::commands::server::build_server_prod;
use crate::ninja::exec;
+use sedregex::find_and_replace;
use std::error::Error;
use std::fs;
use std::path::PathBuf;
use std::process::Command;
-use sedregex::find_and_replace;
fn _build(img: &str, channel: &str, root: &PathBuf) -> Result<(), Box<dyn Error>> {
let mut patched = "".to_string();
@@ 18,7 18,7 @@ fn _build(img: &str, channel: &str, root: &PathBuf) -> Result<(), Box<dyn Error>
} else if img == "web" {
let (a, b) = match channel {
"stable" => ("starkingdoms", "tk"),
- _ => (channel, "starkingdoms.io")
+ _ => (channel, "starkingdoms.io"),
};
let index_html_path = root.clone().join("client/").join("index.html");
@@ 30,7 30,10 @@ fn _build(img: &str, channel: &str, root: &PathBuf) -> Result<(), Box<dyn Error>
fs::write(&index_html_path, index_html_patched.as_bytes())?;
- fs::write(root.clone().join("client/").join("index.html.orig"), index_html_src.clone())?;
+ fs::write(
+ root.clone().join("client/").join("index.html.orig"),
+ index_html_src.clone(),
+ )?;
patched = index_html_src.clone();
M spacetime_rs/src/configure/asset.rs => spacetime_rs/src/configure/asset.rs +6 -1
@@ 27,7 27,12 @@ pub fn configure_assets(writer: &mut NinjaWriter<File>, root: &Path) -> Result<(
);
let default_asset_size = 512;
- let asset_overrides = HashMap::from([("earth.svg", 2048), ("moon.svg", 2048), ("starfield.svg", 2048)]);
+ let asset_overrides = HashMap::from([
+ ("earth.svg", 2048),
+ ("moon.svg", 2048),
+ ("mars.svg", 2048),
+ ("starfield.svg", 2048),
+ ]);
// generate an inkscape rule for all required asset sizes
let mut written_rules_for = vec![];
M web/play.html => web/play.html +1 -1
@@ 2,7 2,7 @@
<html lang="en-US">
<head>
<title>StarKingdoms.TK</title>
- <link rel="stylesheet" href="/static/css/play.css"></link>
+ <link rel="stylesheet" href="/static/css/play.css"/>
<meta charset="utf-8">
</head>
M web/static/css/index.css => web/static/css/index.css +0 -3
@@ 11,6 11,3 @@
width: 100%;
}
-.w-90 {
- width: 90%;
-}>
\ No newline at end of file
M web/static/css/play.css => web/static/css/play.css +0 -5
@@ 1,8 1,3 @@
-.texturebox {
- display: inline;
- margin: 5px;
-}
-
#canvas {
position: absolute;
top: 0;