dont lock up the connection whilest sending fragments
All checks were successful
Build and Test / splatoon (push) Successful in 5m57s
Build and Test / friends (push) Successful in 6m14s
Build and Test / super-mario-maker (push) Successful in 11m21s

This commit is contained in:
Maple 2026-04-27 00:09:55 +02:00
commit dc6307cfcf
3 changed files with 947 additions and 677 deletions

View file

@ -16,6 +16,7 @@ use std::io::Cursor;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::Deref; use std::ops::Deref;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use tokio::spawn;
use v_byte_helpers::ReadExtensions; use v_byte_helpers::ReadExtensions;
use v_byte_helpers::little_endian::read_u16; use v_byte_helpers::little_endian::read_u16;
@ -68,6 +69,33 @@ impl<E: CryptoHandlerConnectionInstance> InternalConnection<E> {
prev_val prev_val
} }
async fn close_connection(&mut self) {
let mut packet = PRUDPV1Packet {
header: PRUDPV1Header {
sequence_id: self.next_server_count(),
substream_id: 0,
session_id: self.session_id,
types_and_flags: TypesFlags::default().types(DISCONNECT),
destination_port: self.common.socket_addr.virtual_port,
source_port: self.server_port,
..Default::default()
},
payload: Vec::new(),
options: vec![FragmentId(0)],
..Default::default()
};
// no need for encryption the, the payload is empty
packet.set_sizes();
self.crypto_handler_instance.sign_packet(&mut packet);
self.send_raw_packet(&packet).await;
self.delete_connection().await;
}
/// Sends a raw packet to a given client on the connection /// Sends a raw packet to a given client on the connection
/// ///
/// a raw packet is one which does not get processed any further(other than to send it /// a raw packet is one which does not get processed any further(other than to send it
@ -103,7 +131,7 @@ pub struct ExternalConnection {
#[derive(Clone)] #[derive(Clone)]
pub struct SendingConnection { pub struct SendingConnection {
common: Arc<CommonConnection>, common: Arc<CommonConnection>,
internal: Weak<Mutex<dyn AnyInternalConnection>>, internal: Weak<dyn AnyInternalConnection>,
} }
pub struct CommonSocket { pub struct CommonSocket {
@ -166,29 +194,32 @@ pub(super) trait AnyInternalSocket:
} }
#[async_trait] #[async_trait]
pub(super) trait AnyInternalConnection: pub(super) trait AnyInternalConnection: Send + Sync + 'static {
Send + Sync + Deref<Target = CommonConnection> + 'static async fn send_data_packet(&self, data: Vec<u8>);
{
async fn send_data_packet(&mut self, data: Vec<u8>);
async fn close_connection(&mut self); async fn close_connection(&self);
} }
#[async_trait] #[async_trait]
impl<T: CryptoHandlerConnectionInstance> AnyInternalConnection for InternalConnection<T> { impl<T: CryptoHandlerConnectionInstance> AnyInternalConnection for Mutex<InternalConnection<T>> {
async fn send_data_packet(&mut self, data: Vec<u8>) { async fn send_data_packet(&self, data: Vec<u8>) {
let pieces = data.chunks(600); let pieces = data.chunks(600);
let max_piece = pieces.len() - 1; let max_piece = pieces.len() - 1;
let mut piece_num = 1; let mut piece_num = 1;
for (i, piece) in pieces.enumerate() { let mut locked = self.lock().await;
let packets: Vec<_> = pieces
.enumerate()
.map(|(i, piece)| {
let mut packet = PRUDPV1Packet { let mut packet = PRUDPV1Packet {
header: PRUDPV1Header { header: PRUDPV1Header {
sequence_id: self.next_server_count(), sequence_id: locked.next_server_count(),
substream_id: 0, substream_id: 0,
session_id: self.session_id, session_id: locked.session_id,
types_and_flags: TypesFlags::default().types(DATA).flags(RELIABLE | NEED_ACK), types_and_flags: TypesFlags::default()
destination_port: self.common.socket_addr.virtual_port, .types(DATA)
source_port: self.server_port, .flags(RELIABLE | NEED_ACK),
destination_port: locked.common.socket_addr.virtual_port,
source_port: locked.server_port,
..Default::default() ..Default::default()
}, },
payload: piece.to_owned(), payload: piece.to_owned(),
@ -196,50 +227,34 @@ impl<T: CryptoHandlerConnectionInstance> AnyInternalConnection for InternalConne
..Default::default() ..Default::default()
}; };
self.crypto_handler_instance locked
.crypto_handler_instance
.encrypt_outgoing(0, &mut packet.payload[..]); .encrypt_outgoing(0, &mut packet.payload[..]);
packet.set_sizes(); packet.set_sizes();
self.crypto_handler_instance.sign_packet(&mut packet); locked.crypto_handler_instance.sign_packet(&mut packet);
self.send_raw_packet(&packet).await;
self.unacknowleged_packets.push((Instant::now(), packet));
sleep(Duration::from_secs(16)).await;
piece_num += 1; piece_num += 1;
packet
})
.collect();
drop(locked);
for packet in packets {
let mut locked = self.lock().await;
locked.send_raw_packet(&packet).await;
locked.unacknowleged_packets.push((Instant::now(), packet));
drop(locked);
sleep(Duration::from_secs(16)).await;
} }
} }
async fn close_connection(&mut self) { async fn close_connection(&self) {
// jon confirmed that this should be a safe way to dc a client let mut locked = self.lock().await;
let mut packet = PRUDPV1Packet { locked.close_connection().await;
header: PRUDPV1Header {
sequence_id: self.next_server_count(),
substream_id: 0,
session_id: self.session_id,
types_and_flags: TypesFlags::default().types(DISCONNECT),
destination_port: self.common.socket_addr.virtual_port,
source_port: self.server_port,
..Default::default()
},
payload: Vec::new(),
options: vec![FragmentId(0)],
..Default::default()
};
// no need for encryption the, the payload is empty
packet.set_sizes();
self.crypto_handler_instance.sign_packet(&mut packet);
self.send_raw_packet(&packet).await;
self.delete_connection().await;
} }
} }
@ -403,7 +418,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
let internal = Arc::new(Mutex::new(internal)); let internal = Arc::new(Mutex::new(internal));
let dyn_internal: Arc<Mutex<dyn AnyInternalConnection>> = internal.clone(); let dyn_internal: Arc<dyn AnyInternalConnection> = internal.clone();
let external = ExternalConnection { let external = ExternalConnection {
sending: SendingConnection { sending: SendingConnection {
@ -884,10 +899,9 @@ impl ExternalConnection {
impl SendingConnection { impl SendingConnection {
pub async fn send(&self, data: Vec<u8>) -> Option<()> { pub async fn send(&self, data: Vec<u8>) -> Option<()> {
let internal = self.internal.upgrade()?; let internal = self.internal.upgrade()?;
spawn(async move {
let mut internal = internal.lock().await;
internal.send_data_packet(data).await; internal.send_data_packet(data).await;
});
Some(()) Some(())
} }
@ -896,8 +910,6 @@ impl SendingConnection {
return; return;
}; };
let mut internal = internal.lock().await;
internal.close_connection().await; internal.close_connection().await;
} }
} }

View file

@ -22,6 +22,7 @@ const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip";
cfg_if! { cfg_if! {
if #[cfg(feature = "datastore")] { if #[cfg(feature = "datastore")] {
use std::sync::{LazyLock, OnceLock};
pub static RNEX_DATASTORE_DATABASE_URL: LazyLock<String> = LazyLock::new(|| { pub static RNEX_DATASTORE_DATABASE_URL: LazyLock<String> = LazyLock::new(|| {
std::env::var("RNEX_DATASTORE_DATABASE_URL") std::env::var("RNEX_DATASTORE_DATABASE_URL")
.expect("RNEX_DATASTORE_DATABASE_URL must be set") .expect("RNEX_DATASTORE_DATABASE_URL must be set")

View file

@ -1,28 +1,22 @@
use cfg_if::cfg_if; use crate::nex::user::User;
cfg_if! { use rnex_core::executables::common::{
if #[cfg(feature = "datastore")] { RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db,
use crate::define_rmc_proto; };
use macros::rmc_struct; use rnex_core::kerberos::KerberosDateTime;
use rnex_core::prudp::socket_addr::PRUDPSockAddr; use rnex_core::nex::s3presigner::S3Presigner;
use std::sync::{Weak}; use rnex_core::rmc::protocols::datastore::{
use chrono::Utc; BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult,
use sqlx::types::time; DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo,
use sqlx::types::time::PrimitiveDateTime; DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget,
use rnex_core::PID; RateCustomRankingParam, RatingInfo, RatingInfoWithSlot,
use rnex_core::nex::remote_console::RemoteConsole; };
use rnex_core::nex::s3presigner::S3Presigner; use rnex_core::rmc::protocols::datastore::{DataStore, PreparePostParam, ReqPostInfo};
use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::response::ErrorCode;
use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; use rnex_core::rmc::structures::qbuffer::QBuffer;
use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; use rnex_core::rmc::structures::qresult::QResult;
use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; use sqlx::types::time;
use crate::nex::user::User;
use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db};
use rnex_core::rmc::structures::qbuffer::QBuffer;
use sqlx::types::chrono::DateTime;
use rnex_core::kerberos::KerberosDateTime;
use rnex_core::rmc::structures::qresult::QResult;
fn map_row_to_meta_info( fn map_row_to_meta_info(
row_data_id: i64, row_data_id: i64,
row_owner: i32, row_owner: i32,
row_size: i32, row_size: i32,
@ -39,8 +33,8 @@ cfg_if! {
row_tags: Vec<String>, row_tags: Vec<String>,
row_creation_date: chrono::NaiveDateTime, row_creation_date: chrono::NaiveDateTime,
row_update_date: chrono::NaiveDateTime, row_update_date: chrono::NaiveDateTime,
ratings: Vec<RatingInfoWithSlot> ratings: Vec<RatingInfoWithSlot>,
) -> GetMetaInfo { ) -> GetMetaInfo {
GetMetaInfo { GetMetaInfo {
dataid: row_data_id as u64, dataid: row_data_id as u64,
owner: row_owner as u32, owner: row_owner as u32,
@ -50,11 +44,17 @@ cfg_if! {
meta_binary: QBuffer(row_meta_binary), meta_binary: QBuffer(row_meta_binary),
permission: Permission { permission: Permission {
permission: row_permission as u8, permission: row_permission as u8,
recipient_ids: row_permission_recipients.into_iter().map(|id| id as u32).collect(), recipient_ids: row_permission_recipients
.into_iter()
.map(|id| id as u32)
.collect(),
}, },
del_permission: Permission { del_permission: Permission {
permission: row_delete_permission as u8, permission: row_delete_permission as u8,
recipient_ids: row_delete_permission_recipients.into_iter().map(|id| id as u32).collect(), recipient_ids: row_delete_permission_recipients
.into_iter()
.map(|id| id as u32)
.collect(),
}, },
period: row_period as u16, period: row_period as u16,
status: 0, status: 0,
@ -68,9 +68,9 @@ cfg_if! {
referred_time: KerberosDateTime::from_naive(row_creation_date), referred_time: KerberosDateTime::from_naive(row_creation_date),
ratings, ratings,
} }
} }
async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> {
let row = sqlx::query!( let row = sqlx::query!(
r#" r#"
SELECT under_review, access_password SELECT under_review, access_password
@ -97,9 +97,12 @@ cfg_if! {
} }
Ok(()) Ok(())
} }
async fn get_object_ratings(data_id: u64, password: u64) -> Result<Vec<RatingInfoWithSlot>, ErrorCode> { async fn get_object_ratings(
data_id: u64,
password: u64,
) -> Result<Vec<RatingInfoWithSlot>, ErrorCode> {
check_object_availability(data_id, password).await?; check_object_availability(data_id, password).await?;
let rows = sqlx::query!( let rows = sqlx::query!(
@ -117,21 +120,22 @@ cfg_if! {
ErrorCode::DataStore_SystemFileError ErrorCode::DataStore_SystemFileError
})?; })?;
let ratings = rows.into_iter().map(|row| { let ratings = rows
RatingInfoWithSlot { .into_iter()
.map(|row| RatingInfoWithSlot {
slot: row.slot as i8, slot: row.slot as i8,
rating: RatingInfo { rating: RatingInfo {
total_value: row.total_value.unwrap_or(0), total_value: row.total_value.unwrap_or(0),
count: row.count as u32, count: row.count as u32,
initial_value: row.initial_value.unwrap_or(0), initial_value: row.initial_value.unwrap_or(0),
}, },
} })
}).collect(); .collect();
Ok(ratings) Ok(ratings)
} }
async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result<GetMetaInfo, ErrorCode> { async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result<GetMetaInfo, ErrorCode> {
check_object_availability(data_id, password).await?; check_object_availability(data_id, password).await?;
let row = sqlx::query!( let row = sqlx::query!(
@ -156,26 +160,57 @@ cfg_if! {
row.data_type.unwrap_or(0) as i16, row.data_type.unwrap_or(0) as i16,
row.meta_binary.unwrap_or_default(), row.meta_binary.unwrap_or_default(),
row.permission.unwrap_or(0) as i16, row.permission.unwrap_or(0) as i16,
row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), row.permission_recipients
.unwrap_or_default()
.into_iter()
.map(|id| id as i64)
.collect(),
row.delete_permission.unwrap_or(0) as i16, row.delete_permission.unwrap_or(0) as i16,
row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), row.delete_permission_recipients
.unwrap_or_default()
.into_iter()
.map(|id| id as i64)
.collect(),
row.period.unwrap_or(0) as i16, row.period.unwrap_or(0) as i16,
row.refer_data_id.unwrap_or(0), row.refer_data_id.unwrap_or(0),
row.flag.unwrap_or(0), row.flag.unwrap_or(0),
row.tags.unwrap_or_default(), row.tags.unwrap_or_default(),
row.creation_date.map(|dt| chrono::NaiveDateTime::new( row.creation_date
chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), .map(|dt| {
chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() chrono::NaiveDateTime::new(
)).unwrap_or_default(), chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32)
row.update_date.map(|dt| chrono::NaiveDateTime::new( .unwrap(),
chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), chrono::NaiveTime::from_hms_opt(
chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() dt.hour() as u32,
)).unwrap_or_default(), dt.minute() as u32,
ratings dt.second() as u32,
)
.unwrap(),
)
})
.unwrap_or_default(),
row.update_date
.map(|dt| {
chrono::NaiveDateTime::new(
chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32)
.unwrap(),
chrono::NaiveTime::from_hms_opt(
dt.hour() as u32,
dt.minute() as u32,
dt.second() as u32,
)
.unwrap(),
)
})
.unwrap_or_default(),
ratings,
)) ))
} }
async fn get_object_info_by_persistence_target(target: PersistenceTarget, password: u64) -> Result<GetMetaInfo, ErrorCode> { async fn get_object_info_by_persistence_target(
target: PersistenceTarget,
password: u64,
) -> Result<GetMetaInfo, ErrorCode> {
let row = sqlx::query!( let row = sqlx::query!(
r#"SELECT data_id, owner, size, name, data_type, meta_binary, r#"SELECT data_id, owner, size, name, data_type, meta_binary,
permission, permission_recipients, delete_permission, delete_permission_recipients, permission, permission_recipients, delete_permission, delete_permission_recipients,
@ -211,29 +246,57 @@ cfg_if! {
row.data_type.unwrap_or(0) as i16, row.data_type.unwrap_or(0) as i16,
row.meta_binary.unwrap_or_default(), row.meta_binary.unwrap_or_default(),
row.permission.unwrap_or(0) as i16, row.permission.unwrap_or(0) as i16,
row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), row.permission_recipients
.unwrap_or_default()
.into_iter()
.map(|id| id as i64)
.collect(),
row.delete_permission.unwrap_or(0) as i16, row.delete_permission.unwrap_or(0) as i16,
row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), row.delete_permission_recipients
.unwrap_or_default()
.into_iter()
.map(|id| id as i64)
.collect(),
row.period.unwrap_or(0) as i16, row.period.unwrap_or(0) as i16,
row.refer_data_id.unwrap_or(0), row.refer_data_id.unwrap_or(0),
row.flag.unwrap_or(0), row.flag.unwrap_or(0),
row.tags.unwrap_or_default(), row.tags.unwrap_or_default(),
row.creation_date.map(|dt| chrono::NaiveDateTime::new( row.creation_date
chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), .map(|dt| {
chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() chrono::NaiveDateTime::new(
)).unwrap_or_default(), chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32)
row.update_date.map(|dt| chrono::NaiveDateTime::new( .unwrap(),
chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), chrono::NaiveTime::from_hms_opt(
chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() dt.hour() as u32,
)).unwrap_or_default(), dt.minute() as u32,
ratings dt.second() as u32,
)
.unwrap(),
)
})
.unwrap_or_default(),
row.update_date
.map(|dt| {
chrono::NaiveDateTime::new(
chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32)
.unwrap(),
chrono::NaiveTime::from_hms_opt(
dt.hour() as u32,
dt.minute() as u32,
dt.second() as u32,
)
.unwrap(),
)
})
.unwrap_or_default(),
ratings,
)) ))
} }
async fn get_buffer_queues_by_data_id_and_slot( async fn get_buffer_queues_by_data_id_and_slot(
data_id: u64, data_id: u64,
slot: u32 slot: u32,
) -> Result<Vec<QBuffer>, ErrorCode> { ) -> Result<Vec<QBuffer>, ErrorCode> {
check_object_availability(data_id, 0).await?; check_object_availability(data_id, 0).await?;
let rows = sqlx::query!( let rows = sqlx::query!(
@ -253,19 +316,16 @@ cfg_if! {
ErrorCode::DataStore_SystemFileError ErrorCode::DataStore_SystemFileError
})?; })?;
let buffer_queues = rows let buffer_queues = rows.into_iter().map(|row| QBuffer(row.buffer)).collect();
.into_iter()
.map(|row| QBuffer(row.buffer))
.collect();
Ok(buffer_queues) Ok(buffer_queues)
} }
fn verify_object_permission( fn verify_object_permission(
owner_id: u32, owner_id: u32,
viewer_id: u32, viewer_id: u32,
permission: &Permission, permission: &Permission,
) -> Result<(), ErrorCode> { ) -> Result<(), ErrorCode> {
if owner_id == viewer_id { if owner_id == viewer_id {
return Ok(()); return Ok(());
} }
@ -284,12 +344,9 @@ cfg_if! {
3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant
_ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r
} }
} }
fn filter_properties_by_result_option( fn filter_properties_by_result_option(meta_info: &mut GetMetaInfo, result_option: u8) {
meta_info: &mut GetMetaInfo,
result_option: u8,
) {
if (result_option & 0x01) == 0 { if (result_option & 0x01) == 0 {
meta_info.meta_binary = QBuffer(Vec::new()); meta_info.meta_binary = QBuffer(Vec::new());
} }
@ -299,13 +356,13 @@ cfg_if! {
} }
// No idea what the other things do. :shrug: // No idea what the other things do. :shrug:
} }
// Dawg... // Dawg...
async fn get_custom_rankings_by_data_ids( async fn get_custom_rankings_by_data_ids(
application_id: u32, application_id: u32,
data_ids: Vec<u64> data_ids: Vec<u64>,
) -> Vec<DataStoreCustomRankingResult> { ) -> Vec<DataStoreCustomRankingResult> {
let mut results = Vec::with_capacity(data_ids.len()); let mut results = Vec::with_capacity(data_ids.len());
let rows = sqlx::query!( let rows = sqlx::query!(
@ -349,9 +406,9 @@ cfg_if! {
} }
results results
} }
async fn get_user_course_object_ids(owner_pid: u32) -> Result<Vec<u64>, ErrorCode> { async fn get_user_course_object_ids(owner_pid: u32) -> Result<Vec<u64>, ErrorCode> {
let rows = sqlx::query!( let rows = sqlx::query!(
r#" r#"
SELECT data_id SELECT data_id
@ -377,50 +434,176 @@ cfg_if! {
} }
Ok(valid_ids) Ok(valid_ids)
} }
fn get_blacklist_1() -> Vec<String> { fn get_blacklist_1() -> Vec<String> {
vec![ vec![
"けされ", "消され", "削除され", "リセットされ", "BANされ", "BANされ", "けされ",
"キミのコース", "君のコース", "きみのコース", "い い ね", "遊びます", "地震", "消され",
"震災", "被災", "津波", "バンされ", "い~ね", "震度", "じしん", "banされ", "削除され",
"くわしくは", "詳しくは", "ちんちん", "ち0こ", "bicth", "い.い.ね", "リセットされ",
"ナイ~ス", "い&い", "い-いね", "いぃね", "nigger", "ngger", "star if u", "BANされ",
"Star if u", "Star if you", "star if you", "PENlS", "マンコ", "butthole", "BANされ",
"LILI", "vagina", "vagyna", "うんち", "うんこ", "ウンコ", "", "キミのコース",
"EENE", "まんこ", "ウンチ", "niglet", "nigglet", "please like", "きんたま", "君のコース",
"Butthole", "llね", "iいね", "give a star", "ちんぽ", "亀頭", "penis", "きみのコース",
"ウンコ", "plz more stars", "star plz", "い()ね", "PLEASE star", "Bitte Sterne", "い い ね",
].into_iter().map(String::from).collect() "遊びます",
} "地震",
"震災",
"被災",
"津波",
"バンされ",
"い~ね",
"震度",
"じしん",
"banされ",
"くわしくは",
"詳しくは",
"ちんちん",
"ち0こ",
"bicth",
"い.い.ね",
"ナイ~ス",
"い&い",
"い-いね",
"いぃね",
"nigger",
"ngger",
"star if u",
"Star if u",
"Star if you",
"star if you",
"PENlS",
"マンコ",
"butthole",
"LILI",
"vagina",
"vagyna",
"うんち",
"うんこ",
"ウンコ",
"",
"EENE",
"まんこ",
"ウンチ",
"niglet",
"nigglet",
"please like",
"きんたま",
"Butthole",
"llね",
"iいね",
"give a star",
"ちんぽ",
"亀頭",
"penis",
"ウンコ",
"plz more stars",
"star plz",
"い()ね",
"PLEASE star",
"Bitte Sterne",
]
.into_iter()
.map(String::from)
.collect()
}
fn get_blacklist_2() -> Vec<String> { fn get_blacklist_2() -> Vec<String> {
vec![ vec![
"ゼロから", "0から", "0から", "い  い  ね", "いい", "東日本", "大震", "ゼロから",
].into_iter().map(String::from).collect() "0から",
} "0から",
"い  い  ね",
"いい",
"東日本",
"大震",
]
.into_iter()
.map(String::from)
.collect()
}
fn get_blacklist_3() -> Vec<String> { fn get_blacklist_3() -> Vec<String> {
vec![ vec![
"いいね", "下さい", "ください", "押して", "おして", "返す", "かえす", "いいね",
"", "してくれ", "するよ", "☆くれたら", "☆あげます", "★くれたら", "下さい",
"★あげます", "しね", "ころす", "ころされた", "アナル", "ファック", "ください",
"キンタマ", "○ね", "キチガイ", "うんこ", "KITIGAI", "金玉", "おっぱい", "押して",
"☆おす", "☆押す", "★おす", "★押す", "いいする", "いいよ", "イイネ", "おして",
"ケツ", "うんち", "かくせいざい", "覚せい剤", "シャブ", "きんたま", "返す",
"ちんちん", "おしっこ", "ちんぽこ", "ころして", "グッド", "グット", "かえす",
"レ●プ", "バーカ", "きちがい", "ちんげ", "マンコ", "まんこ", "チンポ", "",
"クズ", "ウンコ", "ナイスおねがいします", "penis", "イイね", "☆よろ", "してくれ",
"ナイス!して", "ま/んこ", "まん/こ", "するよ",
].into_iter().map(String::from).collect() "☆くれたら",
} "☆あげます",
"★くれたら",
"★あげます",
"しね",
"ころす",
"ころされた",
"アナル",
"ファック",
"キンタマ",
"○ね",
"キチガイ",
"うんこ",
"KITIGAI",
"金玉",
"おっぱい",
"☆おす",
"☆押す",
"★おす",
"★押す",
"いいする",
"いいよ",
"イイネ",
"ケツ",
"うんち",
"かくせいざい",
"覚せい剤",
"シャブ",
"きんたま",
"ちんちん",
"おしっこ",
"ちんぽこ",
"ころして",
"グッド",
"グット",
"レ●プ",
"バーカ",
"きちがい",
"ちんげ",
"マンコ",
"まんこ",
"チンポ",
"クズ",
"ウンコ",
"ナイスおねがいします",
"penis",
"イイね",
"☆よろ",
"ナイス!して",
"ま/んこ",
"まん/こ",
]
.into_iter()
.map(String::from)
.collect()
}
impl DataStore for User { impl DataStore for User {
async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result<GetMetaInfo, ErrorCode> { async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result<GetMetaInfo, ErrorCode> {
let mut meta_info = if metaparam.dataid != 0 { let mut meta_info = if metaparam.dataid != 0 {
get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await?
} else { } else {
get_object_info_by_persistence_target(metaparam.persistence_target, metaparam.access_password).await? get_object_info_by_persistence_target(
metaparam.persistence_target,
metaparam.access_password,
)
.await?
}; };
let current_pid = self.pid; let current_pid = self.pid;
@ -431,9 +614,22 @@ cfg_if! {
Ok(meta_info) Ok(meta_info)
} }
async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result<ReqPostInfo, ErrorCode> { async fn prepare_post_object(
let recipient_ids: Vec<i32> = postparam.permission.recipient_ids.iter().map(|&id| id as i32).collect(); &self,
let del_recipient_ids: Vec<i32> = postparam.del_permission.recipient_ids.iter().map(|&id| id as i32).collect(); postparam: PreparePostParam,
) -> Result<ReqPostInfo, ErrorCode> {
let recipient_ids: Vec<i32> = postparam
.permission
.recipient_ids
.iter()
.map(|&id| id as i32)
.collect();
let del_recipient_ids: Vec<i32> = postparam
.del_permission
.recipient_ids
.iter()
.map(|&id| id as i32)
.collect();
let now = time::OffsetDateTime::now_utc(); let now = time::OffsetDateTime::now_utc();
let row = sqlx::query!( let row = sqlx::query!(
@ -476,16 +672,18 @@ cfg_if! {
let data_id = row.data_id as u64; let data_id = row.data_id as u64;
let presigner = S3Presigner::new( let presigner = S3Presigner::new(
&format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT),
format!("{}", *RNEX_DATASTORE_S3_BUCKET) format!("{}", *RNEX_DATASTORE_S3_BUCKET),
).await; )
.await;
let key = format!("data/{}.bin", data_id); let key = format!("data/{}.bin", data_id);
let (upload_url, fields) = presigner.generate_presigned_post(&key).await; let (upload_url, fields) = presigner.generate_presigned_post(&key).await;
let form_fields = fields.into_iter().map(|(k, v)| { let form_fields = fields
KeyValue { key: k, value: v } .into_iter()
}).collect(); .map(|(k, v)| KeyValue { key: k, value: v })
.collect();
Ok(ReqPostInfo { Ok(ReqPostInfo {
dataid: data_id, dataid: data_id,
@ -496,7 +694,10 @@ cfg_if! {
}) })
} }
async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { async fn complete_post_object(
&self,
completeparam: CompletePostParam,
) -> Result<(), ErrorCode> {
log::info!("Data ID: {:?}", completeparam.dataid); log::info!("Data ID: {:?}", completeparam.dataid);
log::info!("Success: {:?}", completeparam.success); log::info!("Success: {:?}", completeparam.success);
@ -539,7 +740,10 @@ cfg_if! {
Ok(()) Ok(())
} }
async fn rate_custom_ranking(&self, rankingparam: Vec<RateCustomRankingParam>) -> Result<(), ErrorCode> { async fn rate_custom_ranking(
&self,
rankingparam: Vec<RateCustomRankingParam>,
) -> Result<(), ErrorCode> {
for abcparam in rankingparam { for abcparam in rankingparam {
let exists = sqlx::query_scalar!( let exists = sqlx::query_scalar!(
r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#,
@ -580,25 +784,50 @@ cfg_if! {
let config = match appid { let config = match appid {
0 => vec![ 0 => vec![
0x00000001, 0x00000032, 0x00000096, 0x0000012c, 0x000001f4, 0x00000001,
0x00000320, 0x00000514, 0x000007d0, 0x00000bb8, 0x00001388, 0x00000032,
MAX_COURSE_UPLOADS, 0x00000014, 0x0000001e, 0x00000028, 0x00000032, 0x00000096,
0x0000003c, 0x00000046, 0x00000050, 0x0000005a, 0x00000064, 0x0000012c,
0x00000023, 0x0000004b, 0x00000023, 0x0000004b, 0x00000032, 0x000001f4,
0x00000000, 0x00000003, 0x00000003, 0x00000064, 0x00000006, 0x00000320,
0x00000001, 0x00000060, 0x00000005, 0x00000060, 0x00000000, 0x00000514,
0x000007e4, 0x00000001, 0x00000001, 0x0000000c, 0x00000000, 0x000007d0,
0x00000bb8,
0x00001388,
MAX_COURSE_UPLOADS,
0x00000014,
0x0000001e,
0x00000028,
0x00000032,
0x0000003c,
0x00000046,
0x00000050,
0x0000005a,
0x00000064,
0x00000023,
0x0000004b,
0x00000023,
0x0000004b,
0x00000032,
0x00000000,
0x00000003,
0x00000003,
0x00000064,
0x00000006,
0x00000001,
0x00000060,
0x00000005,
0x00000060,
0x00000000,
0x000007e4,
0x00000001,
0x00000001,
0x0000000c,
0x00000000,
], ],
1 => vec![ 1 => vec![
2, 2, 1770179696, 1770179664, 1770179640, 1770180827, 1770180777, 1770180745,
1770179696, 1770177625, 1770177590,
1770179664,
1770179640,
1770180827,
1770180777,
1770180745,
1770177625,
1770177590,
], ],
2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000],
10 => vec![35, 75, 96, 40, 5, 6], 10 => vec![35, 75, 96, 40, 5, 6],
@ -613,13 +842,17 @@ cfg_if! {
async fn get_custom_ranking_by_data_id( async fn get_custom_ranking_by_data_id(
&self, &self,
custom_ranking_param: DataStoreGetCustomRankingByDataIDParam custom_ranking_param: DataStoreGetCustomRankingByDataIDParam,
) -> Result<(Vec<DataStoreCustomRankingResult>, Vec<QResult>), ErrorCode> { ) -> Result<(Vec<DataStoreCustomRankingResult>, Vec<QResult>), ErrorCode> {
println!("appid: {:?}", custom_ranking_param.application_id); println!("appid: {:?}", custom_ranking_param.application_id);
println!("dataid list: {:?}", custom_ranking_param.data_id_list); println!("dataid list: {:?}", custom_ranking_param.data_id_list);
println!("result option: {:?}", custom_ranking_param.result_option); println!("result option: {:?}", custom_ranking_param.result_option);
let mut ranking_results = get_custom_rankings_by_data_ids(custom_ranking_param.application_id, custom_ranking_param.data_id_list).await; let mut ranking_results = get_custom_rankings_by_data_ids(
custom_ranking_param.application_id,
custom_ranking_param.data_id_list,
)
.await;
let mut q_results = Vec::with_capacity(ranking_results.len()); let mut q_results = Vec::with_capacity(ranking_results.len());
@ -646,27 +879,40 @@ cfg_if! {
Ok((ranking_results, q_results)) Ok((ranking_results, q_results))
} }
async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result<Vec<QBuffer>, ErrorCode> { async fn get_buffer_queue(
&self,
bufferparam: BufferQueueParam,
) -> Result<Vec<QBuffer>, ErrorCode> {
// log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot);
let buffers = get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; let buffers =
get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?;
Ok(buffers) Ok(buffers)
} }
async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result<DataStoreReqGetInfo, ErrorCode> { async fn prepare_get_object(
&self,
prepare_get_param: DataStorePrepareGetParam,
) -> Result<DataStoreReqGetInfo, ErrorCode> {
let meta_info = if prepare_get_param.dataid != 0 { let meta_info = if prepare_get_param.dataid != 0 {
get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password).await? get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password)
.await?
} else { } else {
get_object_info_by_persistence_target(prepare_get_param.persistence_target, prepare_get_param.access_password).await? get_object_info_by_persistence_target(
prepare_get_param.persistence_target,
prepare_get_param.access_password,
)
.await?
}; };
verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?;
let presigner = S3Presigner::new( let presigner = S3Presigner::new(
&format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT),
format!("{}", *RNEX_DATASTORE_S3_BUCKET) format!("{}", *RNEX_DATASTORE_S3_BUCKET),
).await; )
.await;
let key = format!("data/{}.bin", meta_info.dataid); let key = format!("data/{}.bin", meta_info.dataid);
let download_url = presigner.generate_presigned_get(&key); let download_url = presigner.generate_presigned_get(&key);
@ -683,7 +929,7 @@ cfg_if! {
async fn followings_latest_course_search_object( async fn followings_latest_course_search_object(
&self, &self,
course_search_param: DataStoreSearchParam, course_search_param: DataStoreSearchParam,
_extra_data: Vec<String> _extra_data: Vec<String>,
) -> Result<Vec<DataStoreCustomRankingResult>, ErrorCode> { ) -> Result<Vec<DataStoreCustomRankingResult>, ErrorCode> {
let mut all_results = Vec::new(); let mut all_results = Vec::new();
@ -708,7 +954,8 @@ cfg_if! {
res.meta_info.ratings = Vec::new(); res.meta_info.ratings = Vec::new();
} }
if course_search_param.result_option & 0x4 == 0 { if course_search_param.result_option & 0x4 == 0 {
res.meta_info.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); res.meta_info.meta_binary =
rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new());
} }
if course_search_param.result_option & 0x20 == 0 { if course_search_param.result_option & 0x20 == 0 {
res.score = 0; res.score = 0;
@ -723,13 +970,19 @@ cfg_if! {
Ok(all_results) Ok(all_results)
} }
async fn get_application_config_string(&self, application_id: u32) -> Result<Vec<String>, ErrorCode> { async fn get_application_config_string(
&self,
application_id: u32,
) -> Result<Vec<String>, ErrorCode> {
let config = match application_id { let config = match application_id {
128 => get_blacklist_1(), 128 => get_blacklist_1(),
129 => get_blacklist_2(), 129 => get_blacklist_2(),
130 => get_blacklist_3(), 130 => get_blacklist_3(),
_ => { _ => {
log::warn!("unsupported application_id in GetApplicationConfigString: {}", application_id); log::warn!(
"unsupported application_id in GetApplicationConfigString: {}",
application_id
);
Vec::new() Vec::new()
} }
}; };
@ -739,7 +992,7 @@ cfg_if! {
async fn get_metas_multiple_param( async fn get_metas_multiple_param(
&self, &self,
params: Vec<GetMetaParam> params: Vec<GetMetaParam>,
) -> Result<(Vec<GetMetaInfo>, Vec<QResult>), ErrorCode> { ) -> Result<(Vec<GetMetaInfo>, Vec<QResult>), ErrorCode> {
let mut metas = Vec::with_capacity(params.len()); let mut metas = Vec::with_capacity(params.len());
let mut results = Vec::with_capacity(params.len()); let mut results = Vec::with_capacity(params.len());
@ -748,12 +1001,17 @@ cfg_if! {
let info_result = if param.dataid != 0 { let info_result = if param.dataid != 0 {
get_object_info_by_data_id(param.dataid, param.access_password).await get_object_info_by_data_id(param.dataid, param.access_password).await
} else { } else {
get_object_info_by_persistence_target(param.persistence_target, param.access_password).await get_object_info_by_persistence_target(
param.persistence_target,
param.access_password,
)
.await
}; };
match info_result { match info_result {
Ok(mut meta) => { Ok(mut meta) => {
if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) { if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission)
{
metas.push(GetMetaInfo::default()); metas.push(GetMetaInfo::default());
results.push(QResult::error(e)); results.push(QResult::error(e));
} else { } else {
@ -764,7 +1022,8 @@ cfg_if! {
meta.ratings = Vec::new(); meta.ratings = Vec::new();
} }
if param.result_option & 0x4 == 0 { if param.result_option & 0x4 == 0 {
meta.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); meta.meta_binary =
rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new());
} }
metas.push(meta); metas.push(meta);
@ -780,6 +1039,4 @@ cfg_if! {
Ok((metas, results)) Ok((metas, results))
} }
}
}
} }