diff --git a/Cargo.lock b/Cargo.lock index 8bb87b5..1123416 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2871,7 +2871,6 @@ dependencies = [ "sha2 0.10.9", "smallvec", "thiserror", - "time", "tokio", "tokio-stream", "tracing", @@ -2955,7 +2954,6 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", - "time", "tracing", "whoami", ] @@ -2994,7 +2992,6 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", - "time", "tracing", "whoami", ] @@ -3020,7 +3017,6 @@ dependencies = [ "serde_urlencoded", "sqlx-core", "thiserror", - "time", "tracing", "url", ] diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index a50a30d..c37f99a 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -28,7 +28,7 @@ anyhow = "1.0.100" ureq = { version = "3.3.0", features = [ "json" ] } serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" -sqlx = { version = "0.8.6", optional = true, features = ["postgres", "runtime-tokio", "chrono", "time"] } +sqlx = { version = "0.8.6", optional = true, features = ["postgres", "runtime-tokio", "chrono"] } aws-sdk-s3 = { version = "1.129.0", optional = true } aws-config = { version = "1.8.15", optional = true } base64 = "0.22.1" diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 43346b4..7991c7e 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -46,13 +46,14 @@ pub fn derive_key(pid: PID, password: &[u8]) -> [u8; 16] { key } -#[derive(Pod, Zeroable, Copy, Clone, Debug, Eq, PartialEq, Default)] +#[derive(Pod, Zeroable, Copy, Clone, Debug, Eq, PartialEq)] #[repr(transparent)] pub struct KerberosDateTime(pub u64); impl KerberosDateTime { + #[deprecated] pub fn from_i64(val: i64) -> Self { - Self(val as u64) + Self(bytemuck::cast(val)) } pub fn from_naive(dt: chrono::NaiveDateTime) -> Self { @@ -68,7 +69,7 @@ impl KerberosDateTime { ) } - pub fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year: u64) -> Self { + pub const fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year: u64) -> Self { Self(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26)) } @@ -84,35 +85,26 @@ impl KerberosDateTime { ) } - #[inline] - pub fn get_seconds(&self) -> u8 { + pub const fn get_seconds(&self) -> u8 { (self.0 & 0b111111) as u8 } - #[inline] - pub fn get_minutes(&self) -> u8 { + pub const fn get_minutes(&self) -> u8 { ((self.0 >> 6) & 0b111111) as u8 } - #[inline] - pub fn get_hours(&self) -> u8 { + pub const fn get_hours(&self) -> u8 { ((self.0 >> 12) & 0b111111) as u8 } - #[inline] - pub fn get_days(&self) -> u8 { + pub const fn get_days(&self) -> u8 { ((self.0 >> 17) & 0b111111) as u8 } - - #[inline] - pub fn get_month(&self) -> u8 { + pub const fn get_month(&self) -> u8 { ((self.0 >> 22) & 0b1111) as u8 } - - #[inline] - pub fn get_year(&self) -> u64 { + pub const fn get_year(&self) -> u64 { (self.0 >> 26) & 0xFFFFFFFF } - - pub fn to_regular_time(&self) -> chrono::DateTime { + pub const fn to_regular_time(&self) -> chrono::DateTime { NaiveDateTime::new( NaiveDate::from_ymd_opt( self.get_year() as i32, @@ -131,6 +123,12 @@ impl KerberosDateTime { } } +impl Default for KerberosDateTime { + fn default() -> Self { + Self::now() + } +} + impl RmcSerialize for KerberosDateTime { fn serialize(&self, writer: &mut impl Write) -> Result<()> { Ok(self.0.serialize(writer)?) diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 7241e53..9d97eeb 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -1,18 +1,28 @@ +use crate::rmc::protocols::datastore::{ + DataStoreGetCourseRecordParam, DataStoreGetCourseRecordResult, DataStoreUploadCourseRecordParam, +}; +use chrono::{NaiveDateTime, Utc}; use futures::TryStreamExt; -use rnex_core::nex::user::User; use rnex_core::PID; use rnex_core::executables::common::{ RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db, }; use rnex_core::kerberos::KerberosDateTime; use rnex_core::nex::s3presigner::S3Presigner; -use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreChangeMetaParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot, RatingInitParamWithSlot}; -use rnex_core::rmc::protocols::datastore::{DataStore, PreparePostParam, ReqPostInfo, AttachFileParam, DataStoreRateObjectParam, DataStoreRatingTarget}; +use rnex_core::nex::user::User; +use rnex_core::rmc::protocols::datastore::{ + AttachFileParam, DataStore, DataStoreRateObjectParam, DataStoreRatingTarget, PreparePostParam, + ReqPostInfo, +}; +use rnex_core::rmc::protocols::datastore::{ + BufferQueueParam, CompletePostParam, DataStoreChangeMetaParam, DataStoreCustomRankingResult, + DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, + DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, + RateCustomRankingParam, RatingInfo, RatingInfoWithSlot, RatingInitParamWithSlot, +}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::rmc::structures::qresult::QResult; -use sqlx::types::time; -use crate::rmc::protocols::datastore::{DataStoreGetCourseRecordParam, DataStoreGetCourseRecordResult, DataStoreUploadCourseRecordParam}; fn map_row_to_meta_info( row_data_id: i64, @@ -68,7 +78,6 @@ fn map_row_to_meta_info( } } - pub async fn check_object_availability(data_id: i64, password: i64) -> Result<(), ErrorCode> { let row = sqlx::query!( r#" @@ -134,7 +143,10 @@ pub async fn get_object_ratings( Ok(ratings) } -pub async fn get_object_info_by_data_id(data_id: i64, password: i64) -> Result { +pub async fn get_object_info_by_data_id( + data_id: i64, + password: i64, +) -> Result { check_object_availability(data_id, password).await?; let row = sqlx::query!( @@ -174,34 +186,8 @@ pub async fn get_object_info_by_data_id(data_id: i64, password: i64) -> Result Vec { } // couldn't find a better way to do this im going crazyy -async fn rate_object(dataid: i64, slot: i8, rating_value: i32, access_password: i64) -> Result { +async fn rate_object( + dataid: i64, + slot: i8, + rating_value: i32, + access_password: i64, +) -> Result { check_object_availability(dataid, access_password).await?; let rating = RatingInfo::default(); @@ -651,12 +616,12 @@ async fn rate_object(dataid: i64, slot: i8, rating_value: i32, access_password: dataid, slot as i16 ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("DB Error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; Ok(rating) } @@ -753,7 +718,7 @@ impl DataStore for User { .iter() .map(|&id| id as i32) .collect(); - let now = time::OffsetDateTime::now_utc(); + let now = Utc::now().naive_utc(); let row = sqlx::query!( r#" @@ -782,8 +747,8 @@ impl DataStore for User { &postparam.tags, postparam.persistence_init_param.persistence_slot_id as i32, &postparam.extra_data, - time::PrimitiveDateTime::new(now.date(), now.time()), - time::PrimitiveDateTime::new(now.date(), now.time()) + now, + now ) .fetch_one(get_db()) .await @@ -803,8 +768,7 @@ impl DataStore for User { log::info!("RIP len is: {}", postparam.rating_init_params.len()); for rating_param in &postparam.rating_init_params { log::info!("running init params"); - init_object_rating_slot(data_id, rating_param.clone()) - .await + init_object_rating_slot(data_id, rating_param.clone()).await } let key = format!("data/{}.bin", data_id); @@ -1145,7 +1109,8 @@ impl DataStore for User { match info_result { Ok(mut meta) => { - if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission).await + if let Err(e) = + verify_object_permission(meta.owner, self.pid, &meta.permission).await { metas.push(GetMetaInfo::default()); results.push(QResult::error(e)); @@ -1206,8 +1171,7 @@ impl DataStore for User { .map(|e| e.to_string()) .collect(); - let now = time::OffsetDateTime::now_utc(); - let db_now = time::PrimitiveDateTime::new(now.date(), now.time()); + let now = Utc::now().naive_utc(); let row = sqlx::query!( r#" @@ -1236,29 +1200,28 @@ impl DataStore for User { &tags, param.post_param.persistence_init_param.persistence_slot_id as i32, &extra_data, - db_now, - db_now + now, + now ) - .fetch_one(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + .fetch_one(get_db()) + .await + .map_err(|e| { + log::error!("DB Error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; let data_id = row.data_id; for rating_param in ¶m.post_param.rating_init_params { log::info!("running init params"); - init_object_rating_slot(data_id, rating_param.clone()) - .await + init_object_rating_slot(data_id, rating_param.clone()).await } let presigner = S3Presigner::new( &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), format!("{}", *RNEX_DATASTORE_S3_BUCKET), ) - .await; + .await; let key = format!("data/{}.jpg", data_id); @@ -1278,14 +1241,18 @@ impl DataStore for User { }) } - async fn complete_attach_file(&self, complete_attach_param: CompletePostParam) -> Result { + async fn complete_attach_file( + &self, + complete_attach_param: CompletePostParam, + ) -> Result { log::info!("Data ID: {:?}", complete_attach_param.dataid); log::info!("Success: {:?}", complete_attach_param.success); let presigner = S3Presigner::new( &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ).await; + ) + .await; let key = format!("data/{}.jpg", complete_attach_param.dataid); let download_url = presigner.generate_presigned_get(&key); @@ -1293,13 +1260,19 @@ impl DataStore for User { Ok(download_url) } - async fn rate_objects(&self, targets: Vec, params: Vec, _transactional: bool, fetch_ratings: bool) -> Result<(Vec, Vec), ErrorCode> { + async fn rate_objects( + &self, + targets: Vec, + params: Vec, + _transactional: bool, + fetch_ratings: bool, + ) -> Result<(Vec, Vec), ErrorCode> { let mut ratings: Vec = vec![]; let results: Vec = vec![]; // SMM seems to work fine with this, no clue for other DTSR games if targets.len() != params.len() { - return Err(ErrorCode::DataStore_OperationNotAllowed) + return Err(ErrorCode::DataStore_OperationNotAllowed); } for (i, target) in targets.into_iter().enumerate() { @@ -1309,11 +1282,18 @@ impl DataStore for User { log::info!("Slot: {:?}", target.slot); log::info!("Access Password: {:?}", param.access_password); - let object_info = get_object_info_by_data_id(target.dataid, param.access_password).await?; + let object_info = + get_object_info_by_data_id(target.dataid, param.access_password).await?; log::info!("object info get complete"); verify_object_permission(object_info.owner, self.pid, &object_info.permission).await?; log::info!("object permission complete"); - let rating = rate_object(target.dataid, target.slot, param.rating_value, param.access_password).await?; + let rating = rate_object( + target.dataid, + target.slot, + param.rating_value, + param.access_password, + ) + .await?; log::info!("rating complete"); if fetch_ratings { @@ -1336,12 +1316,12 @@ impl DataStore for User { param.period as i16, param.dataid ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + .execute(get_db()) + .await + .map_err(|e| { + eprintln!("update error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; } if param.modifies_flag & 0x10 != 0 { @@ -1352,12 +1332,12 @@ impl DataStore for User { param.meta_binary.0, param.dataid ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + .execute(get_db()) + .await + .map_err(|e| { + eprintln!("update error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; } if param.modifies_flag & 0x80 != 0 { @@ -1368,22 +1348,26 @@ impl DataStore for User { param.data_type as i16, param.dataid ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + .execute(get_db()) + .await + .map_err(|e| { + eprintln!("update error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; } Ok(()) } - async fn recommended_course_search_object(&self, course_search_param: DataStoreSearchParam, extra_data: Vec) -> Result, ErrorCode> { + async fn recommended_course_search_object( + &self, + course_search_param: DataStoreSearchParam, + extra_data: Vec, + ) -> Result, ErrorCode> { let mut courses = Vec::new(); let mut stream = sqlx::query!( - r#" + r#" SELECT object.data_id, object.owner, @@ -1413,14 +1397,13 @@ impl DataStore for User { ORDER BY RANDOM() LIMIT 100 "# - ) - .fetch(get_db()); + ) + .fetch(get_db()); while let Some(row) = stream.try_next().await.map_err(|e| { eprintln!("stream error: {:?}", e); ErrorCode::DataStore_NotFound })? { - let permission = Permission { permission: row.permission.unwrap_or(0) as u8, recipient_ids: row.permission_recipients.unwrap_or_default(), @@ -1431,21 +1414,25 @@ impl DataStore for User { recipient_ids: row.delete_permission_recipients.unwrap_or_default(), }; - let meta_binary = row.meta_binary + let meta_binary = row + .meta_binary .map(|bytes| QBuffer(bytes)) .unwrap_or_default(); - let created_time = row.creation_date - .map(|t| KerberosDateTime::from_i64(t.assume_utc().unix_timestamp())) - .unwrap_or_else(|| KerberosDateTime::from_i64(0)); + let created_time = row + .creation_date + .map(KerberosDateTime::from_naive) + .unwrap_or_default(); - let updated_time = row.update_date - .map(|t| KerberosDateTime::from_i64(t.assume_utc().unix_timestamp())) - .unwrap_or_else(|| KerberosDateTime::from_i64(0)); + let updated_time = row + .update_date + .map(KerberosDateTime::from_naive) + .unwrap_or_default(); - let referred_time = row.creation_date - .map(|t| KerberosDateTime::from_i64(t.assume_utc().unix_timestamp())) - .unwrap_or_else(|| KerberosDateTime::from_i64(0)); + let referred_time = row + .creation_date + .map(KerberosDateTime::from_naive) + .unwrap_or_default(); let mut meta_info = GetMetaInfo { dataid: row.data_id, @@ -1486,9 +1473,11 @@ impl DataStore for User { Ok(courses) } - async fn upload_course_record(&self, upload_course_record_param: DataStoreUploadCourseRecordParam) -> Result<(), ErrorCode> { - let now = time::OffsetDateTime::now_utc(); - let db_now = time::PrimitiveDateTime::new(now.date(), now.time()); + async fn upload_course_record( + &self, + upload_course_record_param: DataStoreUploadCourseRecordParam, + ) -> Result<(), ErrorCode> { + let now = Utc::now().naive_utc(); let row = sqlx::query!( r#" @@ -1518,8 +1507,8 @@ impl DataStore for User { self.pid, self.pid, upload_course_record_param.score, - db_now, - db_now + now, + now ) .execute(get_db()) .await @@ -1531,7 +1520,10 @@ impl DataStore for User { Ok(()) } - async fn get_course_record(&self, get_course_record_param: DataStoreGetCourseRecordParam) -> Result { + async fn get_course_record( + &self, + get_course_record_param: DataStoreGetCourseRecordParam, + ) -> Result { let row = sqlx::query!( r#" SELECT @@ -1545,23 +1537,21 @@ impl DataStore for User { get_course_record_param.dataid, get_course_record_param.slot as i16 ) - .fetch_one(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + .fetch_one(get_db()) + .await + .map_err(|e| { + log::error!("DB Error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; - Ok( - DataStoreGetCourseRecordResult { - dataid: get_course_record_param.dataid, - slot: get_course_record_param.slot, - first_pid: row.first_pid as u32, - best_pid: row.best_pid as u32, - best_score: row.best_score, - created_time: KerberosDateTime::from_i64(0x9C3F3E0000), - updated_time: KerberosDateTime::from_i64(0x9C3F3E0000), - } - ) + Ok(DataStoreGetCourseRecordResult { + dataid: get_course_record_param.dataid, + slot: get_course_record_param.slot, + first_pid: row.first_pid as u32, + best_pid: row.best_pid as u32, + best_score: row.best_score, + created_time: KerberosDateTime::from_i64(0x9C3F3E0000), + updated_time: KerberosDateTime::from_i64(0x9C3F3E0000), + }) } }