diff --git a/Cargo.lock b/Cargo.lock index b10230d..0a93b9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "aho-corasick" version = "1.0.4" @@ -181,15 +175,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -352,16 +337,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "flate2" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -440,7 +415,6 @@ dependencies = [ "base64", "diesel", "dotenvy", - "flate2", "maplit", "password-auth", "regex", @@ -716,15 +690,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "mio" version = "0.8.6" diff --git a/Cargo.toml b/Cargo.toml index 03b9da2..acf5aa9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,9 +5,8 @@ edition = "2021" [dependencies] base64 = "0.21.3" -diesel = { version = "=2.1.0", features = ["postgres", "64-column-tables"] } +diesel = { version = "=2.1.0", features = ["postgres"] } dotenvy = "0.15.7" -flate2 = "1.0.27" maplit = "1.0.2" password-auth = "0.3.0" regex = "1.9.4" diff --git a/config.example.toml b/config.example.toml index 7e20b53..76fb6e2 100644 --- a/config.example.toml +++ b/config.example.toml @@ -20,8 +20,4 @@ allow_registration = true [db] # path for your data to be stored -data_folder = "data" - -[levels] -# object ids to block -blocklist = [ 31 ] # start position \ No newline at end of file +data_folder = "data" \ No newline at end of file diff --git a/migrations/2023-09-03-032651_levels/up.sql b/migrations/2023-09-03-032651_levels/up.sql index 3b53884..531b2b3 100644 --- a/migrations/2023-09-03-032651_levels/up.sql +++ b/migrations/2023-09-03-032651_levels/up.sql @@ -24,12 +24,11 @@ CREATE TABLE levels ( song_id INTEGER NOT NULL, - length INTEGER NOT NULL, - length_real DOUBLE PRECISION NOT NULL, - objects INTEGER NOT NULL, - coins INTEGER NOT NULL DEFAULT 0, - has_ldm INTEGER NOT NULL DEFAULT 0, - two_player INTEGER NOT NULL DEFAULT 0, + length INTEGER NOT NULL, + objects INTEGER NOT NULL, + coins INTEGER NOT NULL DEFAULT 0, + has_ldm INTEGER NOT NULL DEFAULT 0, + two_player INTEGER NOT NULL DEFAULT 0, downloads INTEGER NOT NULL DEFAULT 0, likes INTEGER NOT NULL DEFAULT 0, diff --git a/readme.md b/readme.md index 10a587e..6f91c6f 100644 --- a/readme.md +++ b/readme.md @@ -34,8 +34,8 @@ _these features are implemented_ ## todo -- swap to chrono instead of `(TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.MS'))` (thats REALLY ugly!!) -- patch `upload_level` to use 2.2 unlisted (friends only stuff) -- in our level parsing, check for dual portals rather than just starting dual - green name users... -- maybe tone down the clone usage (this is for sure causing memory problems 😉) \ No newline at end of file +- patch uploadlevel to use 2.2 unlisted(honsetly idk what this is) +- clean up uploadlevel +- add level parsing +- maybe swap to chrono instead of `(TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.MS'))` (thats REALLY ugly!!) \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 6333b20..c6b37ae 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,8 +6,7 @@ use std::sync::LazyLock; pub struct Config { pub general: ConfigGeneral, pub accounts: ConfigAccounts, - pub db: ConfigDB, - pub levels: ConfigLevels + pub db: ConfigDB } #[derive(Deserialize)] @@ -26,11 +25,6 @@ pub struct ConfigDB { pub data_folder: String } -#[derive(Deserialize)] -pub struct ConfigLevels { - pub blocklist: Vec -} - impl Config { pub fn load_from_file(file_path: &str) -> Self { let toml_str = fs::read_to_string(file_path).expect("Error finding toml config:"); diff --git a/src/db/models.rs b/src/db/models.rs index 464f162..b78af61 100644 --- a/src/db/models.rs +++ b/src/db/models.rs @@ -108,7 +108,6 @@ pub struct Level { pub editor_time_copies: i32, pub song_id: i32, pub length: i32, - pub length_real: f64, pub objects: i32, pub coins: i32, pub has_ldm: i32, @@ -143,7 +142,6 @@ pub struct NewLevel { pub editor_time_copies: i32, pub song_id: i32, pub length: i32, - pub length_real: f64, pub objects: i32, pub coins: i32, pub has_ldm: i32, diff --git a/src/db/schema.rs b/src/db/schema.rs index f116654..1a25502 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -46,7 +46,6 @@ diesel::table! { editor_time_copies -> Int4, song_id -> Int4, length -> Int4, - length_real -> Float8, objects -> Int4, coins -> Int4, has_ldm -> Int4, diff --git a/src/endpoints/levels/upload_level.rs b/src/endpoints/levels/upload_level.rs index 347d6c7..bae6579 100644 --- a/src/endpoints/levels/upload_level.rs +++ b/src/endpoints/levels/upload_level.rs @@ -1,3 +1,4 @@ +use password_auth::verify_password; use rocket::form::Form; use rocket::http::Status; use rocket::response::status; @@ -73,35 +74,7 @@ pub fn upload_level(input: Form) -> status::Custom<&'static str None => { extra_string = helpers::levels::DEFAULT_EXTRA_STRING.to_owned() } } - // level parsing - let level_raw_objects = helpers::levels::decode(input.levelString.clone()); - let level_objects = helpers::levels::to_objectdata(level_raw_objects.clone()); - let inner_level_string = level_raw_objects - .iter() - .find(|obj| !obj.contains_key("1") && obj.get("kA9") == Some(&"0".to_string())) - .expect("couldnt decode inner level string"); - - let level_length_secs = helpers::levels::measure_length( - level_objects.clone(), - inner_level_string.get("kA4").unwrap_or(&String::from("0")).parse::().expect("kA4 not int") - ); - - let coins_val = level_objects.iter().filter(|obj| obj.id() == 1329).count(); // 1329 is coin id - let objects_val = level_objects.len(); - let two_player_val = if inner_level_string.get("kA10").unwrap_or(&String::from("0")).parse::().expect("kA10 not int") == 1 { 1 } else { 0 }; - let level_length_val = helpers::levels::secs_to_time(level_length_secs); - - // blocking coins - if coins_val > 3 { - return status::Custom(Status::Ok, "-1") - } - - // forbidden object checking - if let Some(_forbidden_object) = level_objects.iter().find(|obj| crate::CONFIG.levels.blocklist.contains(&obj.id())) { - return status::Custom(Status::Ok, "-1") - } - - // data base 🤣😁 + // db shit use crate::models::{Level, NewLevel}; { @@ -138,11 +111,11 @@ pub fn upload_level(input: Form) -> status::Custom<&'static str editor_time.eq(input.wt.unwrap_or(0)), editor_time_copies.eq(input.wt2.unwrap_or(0)), song_id.eq(song_id_val), - length.eq(level_length_val), - objects.eq(objects_val as i32), - coins.eq(coins_val as i32), + length.eq(0), // unimplemeneted + objects.eq(0), // unimplemented + coins.eq(0), // unimplemented has_ldm.eq(input.ldm.unwrap_or(0)), - two_player.eq(two_player_val) + two_player.eq(0) // unimplemented )) .get_result::(connection) .expect("failed to update level"); @@ -171,12 +144,11 @@ pub fn upload_level(input: Form) -> status::Custom<&'static str editor_time: input.wt.unwrap_or(0), editor_time_copies: input.wt2.unwrap_or(0), song_id: song_id_val, - length: level_length_val, - length_real: level_length_secs, - objects: objects_val as i32, - coins: coins_val as i32, + length: 0, // not implemeneted + objects: 0, // not implemeneted + coins: 0, // not implemeneted has_ldm: input.ldm.unwrap_or(0), - two_player: two_player_val + two_player: 0 // not implemented }; let inserted_level = diesel::insert_into(levels) diff --git a/src/helpers/levels.rs b/src/helpers/levels.rs index c5d1e50..d85a395 100644 --- a/src/helpers/levels.rs +++ b/src/helpers/levels.rs @@ -1,180 +1,7 @@ use std::sync::LazyLock; -use std::io::prelude::*; - -use base64::{Engine as _, engine::general_purpose}; - -use flate2::read::GzDecoder; pub static DEFAULT_EXTRA_STRING: LazyLock = LazyLock::new(|| { let string = String::from("29_29_29_40_29_29_29_29_29_29_29_29_29_29_29_29"); - + return string; -}); - -macro_rules! object_prop_bool { - ($key:expr, $name:ident) => { - pub fn $name(&self) -> bool { - self.raw.get($key).map_or(false, |value| value == "1") - } - }; -} - -use std::collections::HashMap; - -#[derive(Clone)] -pub struct ObjectData { - raw: HashMap -} - -impl ObjectData { - pub fn new(raw: HashMap) -> Self { - ObjectData { raw } - } - - pub fn id(&self) -> i32 { - self.raw.get("1").unwrap_or(&String::new()).parse().unwrap_or(0) - } - - pub fn x(&self) -> f64 { - self.raw.get("2").unwrap_or(&String::new()).parse().unwrap_or(0.0) - } - - pub fn y(&self) -> f64 { - self.raw.get("3").unwrap_or(&String::new()).parse().unwrap_or(0.0) - } - - object_prop_bool!("13", checked); -} - -pub mod portal_speed { - pub enum PortalSpeed { - Slow, - Normal, - Medium, - Fast, - VeryFast - } - - impl PortalSpeed { - pub fn portal_speed(&self) -> f64 { - match self { - PortalSpeed::Slow => 251.16, - PortalSpeed::Normal => 311.58, - PortalSpeed::Medium => 387.42, - PortalSpeed::Fast => 478.0, - PortalSpeed::VeryFast => 576.0 - } - } - } -} - -pub fn id_to_portal_speed(id: i32) -> Option { - match id { - 200 => Some(portal_speed::PortalSpeed::Slow), - 201 => Some(portal_speed::PortalSpeed::Normal), - 202 => Some(portal_speed::PortalSpeed::Medium), - 203 => Some(portal_speed::PortalSpeed::Fast), - 1334 => Some(portal_speed::PortalSpeed::VeryFast), - _ => None, - } -} - -pub fn get_seconds_from_xpos(pos: f64, start_speed: portal_speed::PortalSpeed, portals: Vec) -> f64 { - let mut speed; - let mut last_obj_pos = 0.0; - let mut last_segment = 0.0; - let mut segments = 0.0; - - speed = start_speed.portal_speed(); - - if portals.is_empty() { - return pos / speed - } - - for portal in portals { - let mut s = portal.x() - last_obj_pos; - - if pos < s { - s = s / speed; - last_segment = s; - segments += s; - - speed = id_to_portal_speed(portal.id()).expect("not a portal").portal_speed(); - - last_obj_pos = portal.x() - } - } - - return ((pos - last_segment) / speed) + segments; -} - -pub fn measure_length(objects: Vec, ka4: i32) -> f64 { - let start_speed = match ka4 { - 0 => portal_speed::PortalSpeed::Normal, - 1 => portal_speed::PortalSpeed::Slow, - 2 => portal_speed::PortalSpeed::Medium, - 3 => portal_speed::PortalSpeed::Fast, - 4 => portal_speed::PortalSpeed::VeryFast, - _ => portal_speed::PortalSpeed::Normal - }; - - let max_x_pos = objects - .iter() - .fold(0.0, |max_x, obj| f64::max(max_x, obj.x())); - - let mut portals: Vec = objects - .into_iter() - .filter(|obj| id_to_portal_speed(obj.id()).is_some() && obj.checked()) - .collect(); - - portals.sort_by(|a, b| a.x().partial_cmp(&b.x()).unwrap()); - - return get_seconds_from_xpos(max_x_pos, start_speed, portals) -} - -pub fn secs_to_time(time: f64) -> i32 { - match time { - time if time < 10.0 => return 0, - time if time < 30.0 => return 1, - time if time < 60.0 => return 2, - time if time < 120.0 => return 3, - time if time >= 120.0 => return 4, - _ => 0 - } -} - -pub fn array_to_hash(arr: Vec) -> HashMap { - return arr.chunks(2) - .map(|chunk| (chunk[0].clone(), chunk[1].clone())) - .collect() -} - -pub fn parse(raw_level_data: &str) -> Vec> { - raw_level_data - .trim_end_matches(';') - .split(';') - .map(|v| { - let values: Vec = v.split(',').map(|s| s.to_string()).collect(); - array_to_hash(values) - }) - .collect() -} - -pub fn decode(level_data: String) -> Vec> { - let decoded_bytes = general_purpose::URL_SAFE.decode(level_data).expect("couldnt decode b64"); - - let mut decoder = GzDecoder::new(&decoded_bytes[..]); - - let mut uncompressed_data = String::new(); - decoder.read_to_string(&mut uncompressed_data).expect("err unzipping level"); - - return parse(uncompressed_data.as_str()) -} - -pub fn to_objectdata(objects: Vec>) -> Vec { - return objects - .into_iter() - .filter(|v| v.contains_key("1")) - .map(|v| ObjectData::new(v)) - .collect() -} \ No newline at end of file +}); \ No newline at end of file