merge in latest refactor changes
This commit is contained in:
parent
7af0f0f99f
commit
c2f45557da
49 changed files with 163 additions and 1960 deletions
|
|
@ -3,10 +3,10 @@
|
|||
This repo contains the code for all game servers using RNEX.
|
||||
|
||||
## Credits:
|
||||
- Pretendo team for their reverse engineering efforts
|
||||
- Kinnay for his huge work on reversing nex servers and documentation(https://github.com/Kinnay/NintendoClients/)
|
||||
- Splatfestival testing team for helping us test our messes of code
|
||||
- The SPFN team(RusticMaple, BloxerHD, Ceantix, RedBinder0526)
|
||||
- The SPFN team(redbinder0526, bloxerhd, kittentm, et al.)
|
||||
- Pretendo team for their reverse engineering efforts
|
||||
|
||||
This NEX implementation was not created to rival Pretendo, we don't want any bad blood between anyone.
|
||||
This project would never have been possible without their reverse engineering efforts.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ async fn main() {
|
|||
let param = ProxyStartupParam::new(proxy_common::ProxyType::Insecure)
|
||||
.expect("unable to get startup parameters");
|
||||
|
||||
setup_edge_node_connection(¶m, edge_node_dc_callback).await;
|
||||
// setup_edge_node_connection(¶m, edge_node_dc_callback).await;
|
||||
|
||||
proxy::start_insecure(param).await;
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -37,27 +37,7 @@ pub async fn start(param: ProxyStartupParam) {
|
|||
};
|
||||
|
||||
task::spawn(async move {
|
||||
// todo: add support for checking this to nex-account
|
||||
/*
|
||||
let Ok(mut c) = rnex_core::grpc::account::Client::new().await else {
|
||||
error!("failed to initialize gql client");
|
||||
return;
|
||||
};
|
||||
|
||||
let v = match c.get_user_level(conn.user_id).await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("failed to get user level: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if v < 0 {
|
||||
warn!("person with too low account level joined");
|
||||
return;
|
||||
} */
|
||||
|
||||
let mut stream = match TcpStream::connect(param.forward_destination).await {
|
||||
let stream = match TcpStream::connect(param.forward_destination).await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("unable to connect: {}", e);
|
||||
|
|
@ -65,7 +45,9 @@ pub async fn start(param: ProxyStartupParam) {
|
|||
}
|
||||
};
|
||||
|
||||
if let Err(e) = stream
|
||||
let (mut read_half, mut write_half) = stream.into_split();
|
||||
|
||||
if let Err(e) = write_half
|
||||
.send_buffer(
|
||||
&ConnectionInitData {
|
||||
addr: conn.socket_addr.regular_socket_addr,
|
||||
|
|
@ -80,6 +62,28 @@ pub async fn start(param: ProxyStartupParam) {
|
|||
return;
|
||||
};
|
||||
|
||||
let (tx, mut rx) = tokio::sync::mpsc::channel::<Vec<u8>>(100);
|
||||
|
||||
let reader_handle = task::spawn(async move {
|
||||
loop {
|
||||
match read_half.read_buffer().await {
|
||||
Ok(data) => {
|
||||
if data == [0, 0, 0, 0, 0] {
|
||||
continue;
|
||||
}
|
||||
if tx.send(data).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("error receiving data from backend: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let keepalive_data = vec![0u8; 5];
|
||||
'a: loop {
|
||||
tokio::select! {
|
||||
data = conn.recv() => {
|
||||
|
|
@ -87,34 +91,31 @@ pub async fn start(param: ProxyStartupParam) {
|
|||
break 'a;
|
||||
};
|
||||
|
||||
if let Err(e) = stream.send_buffer(&data[..]).await{
|
||||
if let Err(e) = write_half.send_buffer(&data[..]).await {
|
||||
error!("error sending data to backend: {}", e);
|
||||
break 'a;
|
||||
}
|
||||
},
|
||||
data = stream.read_buffer() => {
|
||||
let data = match data{
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
error!("error reveiving data from backend: {}", e);
|
||||
break 'a;
|
||||
}
|
||||
data = rx.recv() => {
|
||||
let Some(data) = data else {
|
||||
break 'a;
|
||||
};
|
||||
|
||||
if data == [0,0,0,0,0] {
|
||||
continue;
|
||||
}
|
||||
|
||||
if conn.send(data).await == None{
|
||||
if conn.send(data).await.is_none() {
|
||||
break 'a;
|
||||
}
|
||||
},
|
||||
_ = sleep(Duration::from_secs(10)) => {
|
||||
stream.send_buffer(&[0,0,0,0,0].to_vec()).await.ok();
|
||||
if let Err(e) = write_half.send_buffer(&keepalive_data).await {
|
||||
error!("failed to send keepalive: {}", e);
|
||||
break 'a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reader_handle.abort();
|
||||
conn.deref().close_connection().await;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE datastore.object_ratings\n SET total_value=total_value+$1, count=count+1\n WHERE data_id=$2 AND slot=$3\n RETURNING total_value, count, initial_value\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "total_value",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "count",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "initial_value",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int8",
|
||||
"Int2"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "15b108cbdaaf3ebb99254330fdcf31c7038239be4c9e88e76653d36482f74379"
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT owner, under_review FROM datastore.objects WHERE data_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "owner",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "under_review",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9"
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "owner",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "size",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "name",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "data_type",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "meta_binary",
|
||||
"type_info": "Bytea"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "permission",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "permission_recipients",
|
||||
"type_info": "Int4Array"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "delete_permission",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "delete_permission_recipients",
|
||||
"type_info": "Int4Array"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "period",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "refer_data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "flag",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "tags",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "creation_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "update_date",
|
||||
"type_info": "Timestamp"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703"
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Text",
|
||||
"Int4",
|
||||
"Bytea",
|
||||
"Int4",
|
||||
"Int4Array",
|
||||
"Int4",
|
||||
"Int4Array",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Int8",
|
||||
"TextArray",
|
||||
"Int4",
|
||||
"TextArray",
|
||||
"Timestamp",
|
||||
"Timestamp"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c"
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4"
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO datastore.course_records (\n data_id,\n slot,\n first_pid,\n best_pid,\n best_score,\n creation_date,\n update_date\n ) VALUES (\n $1,\n $2,\n $3,\n $4,\n $5,\n $6,\n $7\n ) ON CONFLICT (data_id, slot) DO UPDATE\n SET best_score = CASE WHEN datastore.course_records.best_score > $5 THEN $5 ELSE datastore.course_records.best_score END,\n best_pid = CASE WHEN datastore.course_records.best_score > $5 THEN $4 ELSE datastore.course_records.best_pid END,\n update_date = CASE WHEN datastore.course_records.best_score > $5 THEN $7 ELSE datastore.course_records.update_date END\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Timestamp",
|
||||
"Timestamp"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2c8f6740e719d786ed05d2d9cdb29a786ff7b34579938258b73504f7971b3849"
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Text",
|
||||
"Int4",
|
||||
"Bytea",
|
||||
"Int4",
|
||||
"Int4Array",
|
||||
"Int4",
|
||||
"Int4Array",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Int8",
|
||||
"TextArray",
|
||||
"Int4",
|
||||
"TextArray",
|
||||
"Timestamp",
|
||||
"Timestamp"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "2d025ae36b11518c43a0531c58f58e6c97c3f4726bae21e0cfaa8cc0ff218692"
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "exists",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb"
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE datastore.objects SET data_type=$1 WHERE data_id=$2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "31e36bb378bcf8e665391d9cd2c5282fea9540a0673456d58f8142cafc330240"
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT data_id\n FROM datastore.objects\n WHERE owner = $1 AND data_type > 2 AND data_type < 50\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92"
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "buffer",
|
||||
"type_info": "Bytea"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f"
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT update_password, under_review FROM datastore.objects WHERE data_id=$1 AND upload_completed=TRUE AND deleted=FALSE\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "update_password",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "under_review",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "433b8cbd7320b5463391b08545c09b11255b363112c3379319b9e69ed003f2eb"
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n object.data_id,\n object.owner,\n object.size,\n object.name,\n object.data_type,\n object.meta_binary,\n object.permission,\n object.permission_recipients,\n object.delete_permission,\n object.delete_permission_recipients,\n object.period,\n object.refer_data_id,\n object.flag,\n object.tags,\n object.creation_date,\n object.update_date,\n ranking.value\n FROM (\n SELECT * FROM datastore.objects object\n WHERE\n object.upload_completed = TRUE AND\n object.deleted = FALSE AND\n object.under_review = FALSE\n ) object\n JOIN (\n SELECT data_id, value\n FROM datastore.object_custom_rankings ranking\n WHERE ranking.application_id = 0\n ) ranking\n ON\n object.data_id = ranking.data_id\n ORDER BY RANDOM()\n LIMIT 100\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "owner",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "size",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "name",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "data_type",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "meta_binary",
|
||||
"type_info": "Bytea"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "permission",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "permission_recipients",
|
||||
"type_info": "Int4Array"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "delete_permission",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "delete_permission_recipients",
|
||||
"type_info": "Int4Array"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "period",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "refer_data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "flag",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "tags",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "creation_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "update_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "value",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "502f3f0fbb3739ddcffa2938680b2399e0b204b25631e14cac0d61fcff8e29c3"
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n data_id,\n value\n FROM datastore.object_custom_rankings\n WHERE application_id = $1\n AND value >= $2\n AND value <= $3\n ORDER BY value DESC\n LIMIT $4 OFFSET $5\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "value",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int8",
|
||||
"Int8",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "555c438210f49e3a8fd279bf3d493cfdef21c64fd31d1b2bd7a7605f97d550ee"
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO datastore.reports (\n data_id,\n reporter_pid,\n category,\n reason\n ) VALUES (\n $1, $2, $3, $4\n )\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int4",
|
||||
"Int2",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "5cea63e5c1d279af23ef56d7ba02f49ac8c4cb5668559a92daebea815a2d64ec"
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n first_pid,\n best_pid,\n best_score,\n creation_date,\n update_date\n FROM datastore.course_records WHERE data_id=$1 AND slot=$2\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "first_pid",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "best_pid",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "best_score",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "creation_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "update_date",
|
||||
"type_info": "Timestamp"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "720b2a71163a0d3907e847d874cf230267f8241bcc261ca968d143d4ab6b5ab8"
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO datastore.object_ratings (\n data_id,\n slot,\n flag,\n internal_flag,\n lock_type,\n initial_value,\n range_min,\n range_max,\n period_hour,\n period_duration,\n total_value\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11\n )\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int2",
|
||||
"Int2",
|
||||
"Int2",
|
||||
"Int2",
|
||||
"Int8",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Int2",
|
||||
"Int4",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "744047264f63b5eac396d8c0606824f43eb87c2739404d423b2d94bb727ed1c9"
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE datastore.objects SET deleted=true WHERE data_id=$1",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "75f4e823a82add9c1608a43a0dff6633db4cd635037622fd61d7a3a6a872db2e"
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "value",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8Array",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79"
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "slot",
|
||||
"type_info": "Int2"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "total_value",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "count",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "initial_value",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d"
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT slot, total_value, count, initial_value FROM datastore.object_ratings WHERE data_id=$1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "slot",
|
||||
"type_info": "Int2"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "total_value",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "count",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "initial_value",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "8df96ce41787673f9fd03aadf142f3a77f61ff0d3fbe54cf34e967fbb852cbb8"
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "under_review",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "access_password",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb"
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE datastore.objects SET meta_binary=$1 WHERE data_id=$2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Bytea",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "c27439038dc25c17738b4a9cc37f94f83f23239a0c37c7adbccaef571e0128da"
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE datastore.objects SET period=$1 WHERE data_id=$2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "daac203a168b0aab9550176524d0741da291e8861fd7c6ac4838d7fe20a871f8"
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9"
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "owner",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "size",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "name",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "data_type",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "meta_binary",
|
||||
"type_info": "Bytea"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "permission",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "permission_recipients",
|
||||
"type_info": "Int4Array"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "delete_permission",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "delete_permission_recipients",
|
||||
"type_info": "Int4Array"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "period",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "refer_data_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "flag",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "tags",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "creation_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "update_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "access_password",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"name": "under_review",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c"
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO datastore.buffer_queues (\n data_id,\n slot,\n creation_date,\n buffer\n ) VALUES (\n $1,\n $2,\n $3,\n $4\n ) ON CONFLICT (data_id, slot, buffer) DO UPDATE SET creation_date=$3\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Int4",
|
||||
"Timestamp",
|
||||
"Bytea"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "f66ad3f63457ee6b256d909dbbe9269ec6b63387a44b9beaa0da2e11c73d2680"
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT update_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "update_password",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "f7c6fdbd098c8c6f3e5520794c115a39af3e23d1acd523118088cf6f1b9dab92"
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
[package]
|
||||
name = "rnex-core"
|
||||
version = "0.1.1"
|
||||
edition = "2024"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
bytemuck = { version = "1.21.0", features = ["derive"] }
|
||||
dotenv = "0.15.0"
|
||||
rc4 = "0.1.0"
|
||||
thiserror = "2.0.11"
|
||||
v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" }
|
||||
chrono = "0.4.39"
|
||||
rand = "0.10.0"
|
||||
cfg-if = "1.0.4"
|
||||
hmac = "0.12.1"
|
||||
md-5 = "^0.10.6"
|
||||
tokio = { version = "1.43.0", features = ["full"] }
|
||||
hex = "0.4.3"
|
||||
|
||||
rnex-rmc = { path = "../rnex-rmc" }
|
||||
paste = "1.0.15"
|
||||
typenum = "1.18.0"
|
||||
json = "0.12.4"
|
||||
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.9.0", 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"
|
||||
sha2 = "0.10.9"
|
||||
urlencoding = "2.1.3"
|
||||
futures = "0.3.32"
|
||||
async-trait = "0.1.89"
|
||||
ctor = "1.0.7"
|
||||
nex-account = { version = "0.2.1", registry = "spbr" }
|
||||
tonic = "0.14.6"
|
||||
tracing = { version = "0.1.44" }
|
||||
tracing-subscriber = "0.3.23"
|
||||
sentry-tracing = "0.48.4"
|
||||
sentry = { version = "0.48.4", features = ["tracing"] }
|
||||
|
||||
[dev-dependencies]
|
||||
# criterion = "0.7.0"
|
||||
|
||||
[features]
|
||||
rmc_struct_header = []
|
||||
guest_login = []
|
||||
friends = ["guest_login", "database-support"]
|
||||
big_pid = []
|
||||
third-notif-param = []
|
||||
v3-3-2 = []
|
||||
v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"]
|
||||
v3-5-0 = ["v3-4-0"]
|
||||
v3-8-15 = ["v3-5-0"]
|
||||
v3-10-22 = ["v3-8-15"]
|
||||
v4-3-11 = ["v3-8-15"]
|
||||
nx = ["big_pid"]
|
||||
splatoon = ["v3-5-0"]
|
||||
datastore = ["database-support", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"]
|
||||
database-support = ["dep:sqlx"]
|
||||
|
||||
[[bench]]
|
||||
name = "rmc_serialization"
|
||||
harness = false
|
||||
|
||||
[[bin]]
|
||||
name = "backend_server_insecure"
|
||||
path = "src/executables/backend_server_insecure.rs"
|
||||
|
||||
|
||||
[[bin]]
|
||||
name = "backend_server_secure"
|
||||
path = "src/executables/backend_server_secure.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "edge_node_holder_server"
|
||||
path = "src/executables/edge_node_holder_server.rs"
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
use std::hint::black_box;
|
||||
use std::io::Cursor;
|
||||
use std::ops::Deref;
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use once_cell::sync::Lazy;
|
||||
use rnex_core::kerberos::KerberosDateTime;
|
||||
use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria};
|
||||
use rnex_core::rmc::structures::RmcSerialize;
|
||||
use rnex_core::rmc::structures::variant::Variant;
|
||||
|
||||
static DUMMY: Lazy<AutoMatchmakeParam> = Lazy::new(|| AutoMatchmakeParam{
|
||||
additional_participants: vec![1,2,3,4],
|
||||
auto_matchmake_option: 10,
|
||||
gid_for_participation_check: 9,
|
||||
join_message: "hi".to_string(),
|
||||
participation_count: 32,
|
||||
target_gids: vec![45,2,51,1,1,1,1],
|
||||
search_criteria: vec![MatchmakeSessionSearchCriteria{
|
||||
attribs: vec!["hi".to_string(), "ig".to_string(), "gotta put data here".to_string()],
|
||||
exclude_locked: true,
|
||||
exclude_non_host_pid: false,
|
||||
exclude_system_password_set: true,
|
||||
exclude_user_password_set: false,
|
||||
game_mode: "some gamemode".to_string(),
|
||||
matchmake_param: MatchmakeParam{
|
||||
params: vec![
|
||||
("SR".to_string(), Variant::Bool(true)),
|
||||
("SR2".to_string(), Variant::Double(1.0)),
|
||||
("SR3".to_string(), Variant::SInt64(42)),
|
||||
("SR4".to_string(), Variant::String("test".to_string()))
|
||||
]
|
||||
},
|
||||
matchmake_system_type: "some type".to_string(),
|
||||
maximum_participants: "???".to_string(),
|
||||
minimum_participants: "-99".to_string(),
|
||||
refer_gid: 123,
|
||||
selection_method: 9999999,
|
||||
vacant_only: true,
|
||||
vacant_participants: 1000
|
||||
}],
|
||||
matchmake_session: MatchmakeSession{
|
||||
refer_gid: 10,
|
||||
matchmake_system_type: 139,
|
||||
matchmake_param: MatchmakeParam{
|
||||
params: vec![
|
||||
("QSR".to_string(), Variant::Bool(false)),
|
||||
("SRQ2".to_string(), Variant::Double(1.1)),
|
||||
("SQR3".to_string(), Variant::SInt64(422)),
|
||||
("SDR4".to_string(), Variant::String("tetst".to_string()))
|
||||
]
|
||||
},
|
||||
participation_count: 99,
|
||||
application_buffer: vec![1,2,3,4,5,6,7,8,9],
|
||||
attributes: vec![10,20,99,100000],
|
||||
datetime: KerberosDateTime::now(),
|
||||
gamemode: 111,
|
||||
open_participation: false,
|
||||
option0: 100,
|
||||
progress_score: 1,
|
||||
system_password_enabled: false,
|
||||
user_password: "aaa".to_string(),
|
||||
session_key: vec![91,123,5,2,1,2,4,124,4],
|
||||
user_password_enabled: false,
|
||||
gathering: Gathering{
|
||||
minimum_participants: 1,
|
||||
maximum_participants: 12,
|
||||
description: "aaargh".to_string(),
|
||||
flags: 100,
|
||||
host_pid: 999999919,
|
||||
owner_pid: 138830,
|
||||
participant_policy: 1,
|
||||
policy_argument: 99837,
|
||||
self_gid: 129,
|
||||
state: 1389488
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
static DUMMY_SER: Lazy<Vec<u8>> = Lazy::new(|| serialize_to_vec(DUMMY.deref()));
|
||||
|
||||
fn serialize_to_vec(r: &impl RmcSerialize) -> Vec<u8>{
|
||||
let mut vec = r.to_data();
|
||||
|
||||
vec.unwrap()
|
||||
}
|
||||
|
||||
fn read_struct<T: RmcSerialize>(r: &[u8]) -> T{
|
||||
T::deserialize(&mut Cursor::new(r)).unwrap()
|
||||
}
|
||||
fn matchmake_with_param(c: &mut Criterion) {
|
||||
let raw = DUMMY.deref();
|
||||
let ser = DUMMY_SER.deref().as_slice();
|
||||
c.bench_function("mmparam: ser", |b| b.iter(move || serialize_to_vec(black_box(raw))));
|
||||
c.bench_function("mmparam: de", |b| b.iter(move || read_struct::<AutoMatchmakeParam>(black_box(ser))));
|
||||
}
|
||||
|
||||
criterion_group!(benches, matchmake_with_param);
|
||||
criterion_main!(benches);
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use rnex_core::common::with_setup;
|
||||
use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend};
|
||||
use rnex_core::nex::auth_handler::AuthHandler;
|
||||
use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister;
|
||||
use rnex_core::reggie::RemoteEdgeNodeHolder;
|
||||
use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection};
|
||||
use rnex_core::rmc::structures::RmcSerialize;
|
||||
use rnex_core::util::SplittableBufferConnection;
|
||||
use std::env;
|
||||
use std::net::SocketAddrV4;
|
||||
use std::sync::Arc;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
pub static FORWARD_EDGE_NODE_HOLDER: Lazy<SocketAddrV4> = Lazy::new(|| {
|
||||
env::var("FORWARD_EDGE_NODE_HOLDER")
|
||||
.ok()
|
||||
.and_then(|s| Some(s.parse().unwrap()))
|
||||
.expect("FORWARD_EDGE_NODE_HOLDER not set")
|
||||
});
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
with_setup(async || {
|
||||
let conn = TcpStream::connect(&*FORWARD_EDGE_NODE_HOLDER)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let conn: SplittableBufferConnection = conn.into();
|
||||
|
||||
conn.send(DontRegister.to_data().unwrap()).await;
|
||||
|
||||
let conn = new_rmc_gateway_connection(conn, |r| {
|
||||
Arc::new(OnlyRemote::<RemoteEdgeNodeHolder>::new(r))
|
||||
});
|
||||
|
||||
new_simple_backend(move |_, _| {
|
||||
let controller = conn.clone();
|
||||
Arc::new(AuthHandler {
|
||||
destination_server_acct: &SECURE_SERVER_ACCOUNT,
|
||||
build_name: env!("AUTH_REPORT_VERSION"),
|
||||
control_server: controller,
|
||||
})
|
||||
})
|
||||
.await;
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
use cfg_if::cfg_if;
|
||||
use rnex_core::common::with_setup;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
with_setup(async || {
|
||||
#[cfg(feature = "database-support")]
|
||||
{
|
||||
use rnex_core::executables::common::DB_POOL;
|
||||
use sqlx::PgPool;
|
||||
let database_url = std::env::var("RNEX_DATASTORE_DATABASE_URL")
|
||||
.expect("RNEX_DATASTORE_DATABASE_URL must be set");
|
||||
|
||||
let pool = PgPool::connect(&database_url)
|
||||
.await
|
||||
.expect("Failed to create pool");
|
||||
|
||||
DB_POOL.set(pool).expect("failed to set global DB_POOL");
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "friends")]{
|
||||
use rnex_core::executables::friends_backend::start_friends_backend;
|
||||
start_friends_backend().await;
|
||||
} else {
|
||||
use rnex_core::executables::regular_backend;
|
||||
regular_backend::start_regular_backend().await
|
||||
}
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
use crate::reggie::UnitPacketRead;
|
||||
use cfg_if::cfg_if;
|
||||
use rnex_core::nex::account::Account;
|
||||
use rnex_core::rmc::protocols::{RmcCallable, RmcConnection, new_rmc_gateway_connection};
|
||||
use rnex_core::rmc::structures::RmcSerialize;
|
||||
use rnex_core::rnex_proxy_common::ConnectionInitData;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
use std::io::{Cursor, Read, Write};
|
||||
use std::net::{Ipv4Addr, SocketAddrV4, TcpStream};
|
||||
use std::sync::Arc;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing::error;
|
||||
|
||||
const IP_REQ_SERVICE_URLS: &[(&str, &str, &str)] = &[
|
||||
("ipinfo.io:80", "ipinfo.io", "/ip"),
|
||||
("api.ipify.org:80", "api.ipify.org", "/"),
|
||||
// preresolved
|
||||
("34.117.59.81:80", "ipinfo.io", "/ip"),
|
||||
("104.26.13.205:80", "api.ipify.org", "/"),
|
||||
("172.67.74.152:80", "api.ipify.org", "/"),
|
||||
("104.26.12.205:80", "api.ipify.org", "/"),
|
||||
];
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "database-support")] {
|
||||
use std::sync::{LazyLock, OnceLock};
|
||||
use sqlx::postgres::PgPool;
|
||||
pub static RNEX_DATABASE_URL: LazyLock<String> = LazyLock::new(|| {
|
||||
std::env::var("RNEX_DATABASE_URL")
|
||||
.expect("RNEX_DATABASE_URL must be set")
|
||||
});
|
||||
|
||||
pub static DB_POOL: OnceLock<PgPool> = OnceLock::new();
|
||||
|
||||
pub fn get_db() -> &'static PgPool {
|
||||
DB_POOL.get().expect("db_pool not initialized")
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "datastore")]{
|
||||
pub static RNEX_DATASTORE_S3_ENDPOINT: LazyLock<String> = LazyLock::new(|| {
|
||||
std::env::var("RNEX_DATASTORE_S3_ENDPOINT")
|
||||
.expect("RNEX_DATASTORE_S3_ENDPOINT must be set")
|
||||
});
|
||||
pub static RNEX_DATASTORE_S3_BUCKET: LazyLock<String> = LazyLock::new(|| {
|
||||
std::env::var("RNEX_DATASTORE_S3_BUCKET")
|
||||
.expect("RNEX_DATASTORE_S3_BUCKET must be set")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_to_log<R, E: Display>(fun: impl FnOnce() -> Result<R, E>) -> Option<R> {
|
||||
match fun() {
|
||||
Ok(v) => Some(v),
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_get_ip() -> Option<Ipv4Addr> {
|
||||
for url in IP_REQ_SERVICE_URLS {
|
||||
println!("trying to get ip via: {:?}", url);
|
||||
if let Some(v) = try_to_log::<_, Box<dyn Error>>(|| {
|
||||
let mut stream = TcpStream::connect(url.0)?;
|
||||
stream.write_all(
|
||||
format!(
|
||||
"GET {} HTTP/1.0
|
||||
Host: {}
|
||||
User-Agent: RNEX
|
||||
Accept: */*
|
||||
|
||||
",
|
||||
url.2, url.1
|
||||
)
|
||||
.as_str()
|
||||
.as_bytes(),
|
||||
)?;
|
||||
let mut data = vec![];
|
||||
stream.read_to_end(&mut data)?;
|
||||
let string = String::from_utf8(data)?;
|
||||
let (_, ip) = string
|
||||
.split_once("\r\n\r\n")
|
||||
.ok_or("unable to get ip from response")?;
|
||||
Ok(ip.parse()?)
|
||||
}) {
|
||||
return Some(v);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub static OWN_IP_PRIVATE: LazyLock<Ipv4Addr> = LazyLock::new(|| {
|
||||
env::var("SERVER_IP")
|
||||
.ok()
|
||||
.map(|s| s.parse().expect("invalid ip address"))
|
||||
.unwrap_or(Ipv4Addr::UNSPECIFIED)
|
||||
});
|
||||
|
||||
pub static OWN_IP_PUBLIC: LazyLock<Ipv4Addr> = LazyLock::new(|| {
|
||||
env::var("SERVER_IP_PUBLIC")
|
||||
.ok()
|
||||
.map(|s| s.parse().expect("invalid ip address"))
|
||||
.unwrap_or_else(|| try_get_ip().unwrap())
|
||||
});
|
||||
|
||||
pub static SERVER_PORT: LazyLock<u16> = LazyLock::new(|| {
|
||||
env::var("SERVER_PORT")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(10000)
|
||||
});
|
||||
|
||||
pub static KERBEROS_SERVER_PASSWORD: LazyLock<String> = LazyLock::new(|| {
|
||||
env::var("AUTH_SERVER_PASSWORD")
|
||||
.ok()
|
||||
.unwrap_or("password".to_owned())
|
||||
});
|
||||
|
||||
pub static AUTH_SERVER_ACCOUNT: LazyLock<Account> =
|
||||
LazyLock::new(|| Account::new(1, "Quazal Authentication", &KERBEROS_SERVER_PASSWORD));
|
||||
pub static SECURE_SERVER_ACCOUNT: LazyLock<Account> =
|
||||
LazyLock::new(|| Account::new(2, "Quazal Rendez-Vous", &KERBEROS_SERVER_PASSWORD));
|
||||
|
||||
pub async fn new_simple_backend<T: RmcCallable + Sync + Send + 'static, F>(mut creation_function: F)
|
||||
where
|
||||
F: FnMut(ConnectionInitData, RmcConnection) -> Arc<T>,
|
||||
{
|
||||
let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT))
|
||||
.await
|
||||
.unwrap();
|
||||
while let Ok((mut stream, _addr)) = listen.accept().await {
|
||||
let buffer = match stream.read_buffer().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(
|
||||
"an error ocurred whilst reading connection data buffer: {:?}",
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer));
|
||||
|
||||
let user_connection_data = match user_connection_data {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("an error ocurred whilst reading connection data: {:?}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let fun_ref = &mut creation_function;
|
||||
new_rmc_gateway_connection(stream.into(), move |r| fun_ref(user_connection_data, r));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::executables::common::try_get_ip;
|
||||
|
||||
#[test]
|
||||
fn get_ip() {
|
||||
println!("{}", try_get_ip().unwrap());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
use macros::rmc_struct;
|
||||
use rnex_core::common::with_setup;
|
||||
use rnex_core::executables::common::{OWN_IP_PRIVATE, SERVER_PORT};
|
||||
use rnex_core::reggie::{EdgeNodeHolderConnectOption, EdgeNodeManagement, LocalEdgeNodeHolder};
|
||||
use rnex_core::rmc::protocols::new_rmc_gateway_connection;
|
||||
use rnex_core::rmc::response::ErrorCode;
|
||||
use rnex_core::rmc::structures::RmcSerialize;
|
||||
use rnex_core::util::SplittableBufferConnection;
|
||||
use std::io::Cursor;
|
||||
use std::net::SocketAddrV4;
|
||||
use std::sync::{Arc, Weak};
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
#[rmc_struct(EdgeNodeHolder)]
|
||||
struct EdgeNode {
|
||||
data_holder: Arc<DataHolder>,
|
||||
address: SocketAddrV4,
|
||||
}
|
||||
|
||||
impl EdgeNodeManagement for EdgeNode {
|
||||
async fn get_url(&self, seed: u64) -> Result<SocketAddrV4, ErrorCode> {
|
||||
self.data_holder.get_url(seed).await
|
||||
}
|
||||
}
|
||||
|
||||
#[rmc_struct(EdgeNodeHolder)]
|
||||
#[derive(Default)]
|
||||
struct DataHolder {
|
||||
edge_nodes: RwLock<Vec<Weak<EdgeNode>>>,
|
||||
}
|
||||
|
||||
impl EdgeNodeManagement for DataHolder {
|
||||
async fn get_url(&self, seed: u64) -> Result<SocketAddrV4, ErrorCode> {
|
||||
let nodes = self.edge_nodes.read().await;
|
||||
|
||||
let nodes: Vec<_> = nodes.iter().filter_map(|n| n.upgrade()).collect();
|
||||
|
||||
// avoid a devide by zero
|
||||
if nodes.len() == 0 {
|
||||
return Err(ErrorCode::Core_InvalidIndex);
|
||||
};
|
||||
|
||||
let node = &nodes[seed as usize % nodes.len()];
|
||||
|
||||
Ok(node.address)
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
with_setup(async || {
|
||||
log::error!("test");
|
||||
let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let holder: Arc<DataHolder> = Default::default();
|
||||
|
||||
while let Ok((stream, _addr)) = listen.accept().await {
|
||||
let mut conn: SplittableBufferConnection = stream.into();
|
||||
|
||||
let Some(data) = conn.recv().await else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let Ok(data) = EdgeNodeHolderConnectOption::deserialize(&mut Cursor::new(data)) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let holder = holder.clone();
|
||||
|
||||
match data {
|
||||
EdgeNodeHolderConnectOption::DontRegister => {
|
||||
new_rmc_gateway_connection(conn, |_| holder);
|
||||
}
|
||||
EdgeNodeHolderConnectOption::Register(address) => {
|
||||
let edge_node = EdgeNode {
|
||||
address,
|
||||
data_holder: holder.clone(),
|
||||
};
|
||||
|
||||
let node = new_rmc_gateway_connection(conn, move |_| Arc::new(edge_node));
|
||||
|
||||
let mut nodes = holder.edge_nodes.write().await;
|
||||
nodes.push(Arc::downgrade(&node));
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
use std::{
|
||||
io::Cursor,
|
||||
net::SocketAddrV4,
|
||||
sync::{Arc, atomic::AtomicU32},
|
||||
};
|
||||
|
||||
use tokio::net::TcpListener;
|
||||
use tracing::error;
|
||||
|
||||
use crate::{
|
||||
executables::common::{OWN_IP_PRIVATE, SERVER_PORT},
|
||||
nex::friends_handler::{FriendsGuest, FriendsManager, FriendsUser, RemoteFriendRemote},
|
||||
reggie::UnitPacketRead,
|
||||
rmc::{
|
||||
protocols::{RmcPureRemoteObject, new_rmc_gateway_connection},
|
||||
structures::RmcSerialize,
|
||||
},
|
||||
rnex_proxy_common::ConnectionInitData,
|
||||
};
|
||||
|
||||
pub async fn start_friends_backend() {
|
||||
let fm = Arc::new(FriendsManager {
|
||||
cid_counter: AtomicU32::new(1),
|
||||
users: Default::default(),
|
||||
});
|
||||
let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT))
|
||||
.await
|
||||
.unwrap();
|
||||
while let Ok((mut stream, _addr)) = listen.accept().await {
|
||||
let buffer = match stream.read_buffer().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(
|
||||
"an error ocurred whilst reading connection data buffer: {:?}",
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer));
|
||||
|
||||
let c = match user_connection_data {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("an error ocurred whilst reading connection data: {:?}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let fm = fm.clone();
|
||||
if c.pid != 100 {
|
||||
new_rmc_gateway_connection(stream.into(), move |r| {
|
||||
Arc::new_cyclic(move |this| FriendsUser {
|
||||
fm,
|
||||
addr: c.prudpsock_addr,
|
||||
pid: c.pid,
|
||||
this: this.clone(),
|
||||
remote: RemoteFriendRemote::new(r),
|
||||
friend_pids: Default::default(),
|
||||
maybe_remote_friend: Default::default(),
|
||||
presence: Default::default(),
|
||||
})
|
||||
});
|
||||
} else {
|
||||
new_rmc_gateway_connection(stream.into(), move |_| {
|
||||
Arc::new_cyclic(move |_| FriendsGuest {
|
||||
fm,
|
||||
addr: c.prudpsock_addr,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
use cfg_if::cfg_if;
|
||||
|
||||
pub mod common;
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "friends")]{
|
||||
pub mod friends_backend;
|
||||
} else {
|
||||
pub mod regular_backend;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
use std::sync::{Arc, atomic::AtomicU32};
|
||||
|
||||
use tokio::sync::{Mutex, mpsc::channel};
|
||||
|
||||
use crate::{
|
||||
executables::common::new_simple_backend,
|
||||
nex::{
|
||||
matchmake::MatchmakeManager,
|
||||
remote_console::RemoteConsole,
|
||||
user::{ConnectionTicket, User},
|
||||
},
|
||||
rmc::protocols::RmcPureRemoteObject,
|
||||
};
|
||||
|
||||
pub async fn start_regular_backend() {
|
||||
let mmm = Arc::new(MatchmakeManager {
|
||||
//gid_counter: AtomicU32::new(1),
|
||||
sessions: Default::default(),
|
||||
users: Default::default(),
|
||||
users_by_pid: Default::default(),
|
||||
rv_cid_counter: AtomicU32::new(1),
|
||||
});
|
||||
|
||||
let weak_mmm = Arc::downgrade(&mmm);
|
||||
|
||||
MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await;
|
||||
|
||||
new_simple_backend(move |c, r| {
|
||||
let mmm = mmm.clone();
|
||||
Arc::new_cyclic(move |this| {
|
||||
let (join_tickets_stage1_sender, join_tickets_stage1_recv) =
|
||||
channel::<ConnectionTicket>(100);
|
||||
let join_tickets_stage1_recv = Mutex::new(join_tickets_stage1_recv);
|
||||
|
||||
let (join_tickets_stage2_sender, join_tickets_stage2_recv) =
|
||||
channel::<ConnectionTicket>(100);
|
||||
let join_tickets_stage2_recv = Mutex::new(join_tickets_stage2_recv);
|
||||
let cid = mmm.next_cid();
|
||||
|
||||
User {
|
||||
cid,
|
||||
this: this.clone(),
|
||||
ip: c.prudpsock_addr,
|
||||
pid: c.pid,
|
||||
remote: RemoteConsole::new(r),
|
||||
matchmake_manager: mmm,
|
||||
station_url: Default::default(),
|
||||
join_tickets_stage1_recv,
|
||||
join_tickets_stage1_sender,
|
||||
join_tickets_stage2_recv,
|
||||
join_tickets_stage2_sender,
|
||||
self_join_ticket_requesters: Default::default(),
|
||||
remote_join_ticket_requesters: Default::default(),
|
||||
}
|
||||
})
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#![allow(dead_code)]
|
||||
// rnex makes extensive use of async functions in public traits
|
||||
// this is however fine because these traits should never(and i mean NEVER) be used dynamically
|
||||
#![allow(async_fn_in_trait)]
|
||||
//#![warn(missing_docs)]
|
||||
|
||||
pub use ctor::ctor;
|
||||
|
||||
pub mod prudp;
|
||||
pub mod rmc;
|
||||
//mod protocols;
|
||||
|
||||
pub mod common;
|
||||
pub mod executables;
|
||||
pub mod grpc;
|
||||
pub mod kerberos;
|
||||
pub mod nex;
|
||||
pub mod reggie;
|
||||
pub mod rnex_proxy_common;
|
||||
pub mod util;
|
||||
pub mod versions;
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
use rnex_core::prudp::station_url::StationUrl;
|
||||
use rnex_core::prudp::station_url::UrlOptions::{
|
||||
Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID,
|
||||
};
|
||||
use rnex_core::prudp::station_url::nat_types::PUBLIC;
|
||||
use rnex_core::rmc::response::ErrorCode::Core_Exception;
|
||||
|
||||
use rnex_core::prudp::socket_addr::PRUDPSockAddr;
|
||||
use rnex_core::rmc::response::ErrorCode;
|
||||
|
||||
use rnex_core::PID;
|
||||
|
||||
use crate::prudp::station_url::UrlOptions::ConnectionID;
|
||||
|
||||
pub async fn get_station_urls(
|
||||
station_urls: &[StationUrl],
|
||||
addr: PRUDPSockAddr,
|
||||
pid: PID,
|
||||
cid: u32,
|
||||
) -> Result<Vec<StationUrl>, ErrorCode> {
|
||||
let mut public_station: Option<StationUrl> = None;
|
||||
let mut private_station: Option<StationUrl> = None;
|
||||
|
||||
for station in station_urls {
|
||||
let is_public = station.options.iter().any(|v| {
|
||||
if let NatType(v) = v
|
||||
&& *v & PUBLIC != 0
|
||||
{
|
||||
return true;
|
||||
}
|
||||
false
|
||||
});
|
||||
|
||||
let Some(nat_filtering) = station.options.iter().find_map(|v| match v {
|
||||
NatFiltering(v) => Some(v),
|
||||
_ => None,
|
||||
}) else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
let Some(nat_mapping) = station.options.iter().find_map(|v| match v {
|
||||
NatMapping(v) => Some(v),
|
||||
_ => None,
|
||||
}) else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
if !is_public || (*nat_filtering == 0 && *nat_mapping == 0) {
|
||||
private_station = Some(station.clone());
|
||||
}
|
||||
|
||||
if is_public {
|
||||
public_station = Some(station.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let Some(mut private_station) = private_station else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
let mut public_station = if let Some(public_station) = public_station {
|
||||
public_station
|
||||
} else {
|
||||
let mut public_station = private_station.clone();
|
||||
|
||||
public_station.options.retain(|v| {
|
||||
!matches!(
|
||||
v,
|
||||
Address(_) | Port(_) | NatFiltering(_) | NatMapping(_) | NatType(_)
|
||||
)
|
||||
});
|
||||
|
||||
public_station
|
||||
.options
|
||||
.push(Address(addr.regular_socket_addr.ip()));
|
||||
public_station
|
||||
.options
|
||||
.push(Port(addr.regular_socket_addr.port()));
|
||||
public_station.options.push(NatFiltering(0));
|
||||
public_station.options.push(NatMapping(0));
|
||||
public_station.options.push(NatType(3));
|
||||
|
||||
public_station
|
||||
};
|
||||
|
||||
let both = [&mut public_station, &mut private_station];
|
||||
|
||||
for station in both {
|
||||
station
|
||||
.options
|
||||
.retain(|v| !matches!(v, PrincipalID(_) | RVConnectionID(_)));
|
||||
|
||||
station.options.push(PrincipalID(pid));
|
||||
station.options.push(RVConnectionID(cid));
|
||||
station.options.push(ConnectionID(cid));
|
||||
}
|
||||
|
||||
Ok(vec![public_station])
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[cfg(feature = "database-support")]
|
||||
fn test() {}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
use cfg_if::cfg_if;
|
||||
|
||||
pub mod account;
|
||||
pub mod auth_handler;
|
||||
pub mod common;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "friends")]{
|
||||
pub mod friends_handler;
|
||||
} else {
|
||||
pub mod matchmake;
|
||||
pub mod remote_console;
|
||||
pub mod user;
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "datastore")] {
|
||||
pub mod s3presigner;
|
||||
pub mod datastore;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
use crate::define_rmc_proto;
|
||||
use crate::rmc::protocols::message_delivery::{
|
||||
MessageDeliveryNoResponse, RawMessageDeliveryNoResponse, RawMessageDeliveryNoResponseInfo,
|
||||
RemoteMessageDeliveryNoResponse,
|
||||
};
|
||||
use crate::rmc::protocols::nat_traversal::{
|
||||
NatTraversalConsole, RawNatTraversalConsole, RawNatTraversalConsoleInfo,
|
||||
RemoteNatTraversalConsole,
|
||||
};
|
||||
use crate::rmc::protocols::notifications::{
|
||||
Notification, RawNotification, RawNotificationInfo, RemoteNotification,
|
||||
};
|
||||
|
||||
define_rmc_proto!(
|
||||
proto Console{
|
||||
Notification,
|
||||
NatTraversalConsole,
|
||||
MessageDeliveryNoResponse
|
||||
}
|
||||
);
|
||||
/*
|
||||
#[rmc_struct(Console)]
|
||||
pub struct TestRemoteConsole{
|
||||
pub remote: RemoteUserProtocol,
|
||||
}
|
||||
|
||||
impl Notification for TestRemoteConsole{
|
||||
async fn process_notification_event(&self, event: NotificationEvent) {
|
||||
println!("NOTIF RECIEVED: {:?}", event);
|
||||
}
|
||||
}*/
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
use rnex_rmc::{
|
||||
RmcSerialize, any::Any, data::Data, method_id, qresult::QResult, response::ErrorCode,
|
||||
rmc_proto, util::station_url::StationUrl,
|
||||
RmcSerialize, any::Any, data::Data, method_id, qbuffer::QBuffer, qresult::QResult, response::ErrorCode, rmc_proto, util::station_url::StationUrl
|
||||
};
|
||||
|
||||
#[derive(RmcSerialize)]
|
||||
|
|
@ -35,4 +34,6 @@ pub trait Secure {
|
|||
) -> Result<(QResult, u32, StationUrl), ErrorCode>;
|
||||
#[method_id(7)]
|
||||
async fn replace_url(&self, target: StationUrl, dest: StationUrl) -> Result<(), ErrorCode>;
|
||||
#[method_id(8)]
|
||||
async fn send_report(&self, id: u32, data: QBuffer) -> Result<(), ErrorCode>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::net::SocketAddr;
|
||||
|
||||
use rnex_base_protos::{LocalBaseProtocol, secure::Secure, util::Utility};
|
||||
use rnex_rmc::{any::Any, qresult::QResult, response::ErrorCode, rmc_struct};
|
||||
use rnex_rmc::{any::Any, qbuffer::QBuffer, qresult::QResult, response::ErrorCode, rmc_struct};
|
||||
use rnex_util::{
|
||||
PID,
|
||||
station_url::{StationUrl, UrlOptions, nat_types::PUBLIC},
|
||||
|
|
@ -176,6 +176,10 @@ impl Secure for BaseUser {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_report(&self,id: u32,data: QBuffer) -> Result<(),ErrorCode> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Utility for BaseUser {
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ macro_rules! launch_rnex_module_server {
|
|||
{
|
||||
$init_ty:ty;
|
||||
$(
|
||||
$(#[$($tt:tt)*])*
|
||||
$(#[$meta:meta])*
|
||||
$module_type:ty
|
||||
),* $(,)?} => {{
|
||||
use $crate::tracing::Instrument;
|
||||
|
|
@ -165,22 +165,22 @@ macro_rules! launch_rnex_module_server {
|
|||
#[derive(Debug)]
|
||||
struct MultiEndpoint {
|
||||
$(
|
||||
$(#[$($tt)*])*
|
||||
$(#[$meta])*
|
||||
[<user_ $module_type>]: $crate::PassthroughInitModule<
|
||||
<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::User,
|
||||
>
|
||||
),*
|
||||
>,
|
||||
)*
|
||||
}
|
||||
}
|
||||
$crate::paste::paste!{
|
||||
#[derive(Debug)]
|
||||
struct MultiManager {
|
||||
$(
|
||||
$(#[$($tt)*])*
|
||||
$(#[$meta])*
|
||||
[<manager_ $module_type>]: $crate::PassthroughInitModule<
|
||||
<$module_type as $crate::RnexModule>::Manager,
|
||||
>
|
||||
),*
|
||||
>,
|
||||
)*
|
||||
}
|
||||
}
|
||||
impl $crate::rmc::RmcCallable for MultiEndpoint {
|
||||
|
|
@ -191,13 +191,13 @@ macro_rules! launch_rnex_module_server {
|
|||
method_id: u32,
|
||||
call_id: u32,
|
||||
rest: &[u8],
|
||||
) -> bool{
|
||||
) -> bool {
|
||||
$(
|
||||
$(#[$($tt)*])*
|
||||
$(#[$meta])*
|
||||
$crate::paste::paste!{
|
||||
if self. [<user_ $module_type>]
|
||||
if self.[<user_ $module_type>]
|
||||
.rmc_call(responder, protocol_id, method_id, call_id, rest)
|
||||
.await{
|
||||
.await {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -210,22 +210,22 @@ macro_rules! launch_rnex_module_server {
|
|||
let mut holder = $crate::ModuleHolder::default();
|
||||
|
||||
$(
|
||||
$(#[$($tt)*])*
|
||||
$(#[$meta])*
|
||||
$crate::tracing::info!(
|
||||
module_manager = ::std::any::type_name::<<$module_type as $crate::RnexModule>::Manager>(),
|
||||
"creating module slot"
|
||||
);
|
||||
$(#[$($tt)*])*
|
||||
$(#[$meta])*
|
||||
holder.create_empty_module_slot::<<$module_type as $crate::RnexModule>::Manager>();
|
||||
)*
|
||||
|
||||
$(
|
||||
$(#[$($tt)*])*
|
||||
$(#[$meta])*
|
||||
$crate::tracing::info!(
|
||||
module_manager = ::std::any::type_name::<<$module_type as $crate::RnexModule>::Manager>(),
|
||||
"initializing and filling module slot"
|
||||
);
|
||||
$(#[$($tt)*])*
|
||||
$(#[$meta])*
|
||||
let $crate::paste::paste!{[<manager_ $module_type>]} = holder
|
||||
.init_slot::<<$module_type as $crate::RnexModule>::Manager>(
|
||||
<$module_type as $crate::RnexModule>::create_manager(&holder).await?,
|
||||
|
|
@ -233,8 +233,8 @@ macro_rules! launch_rnex_module_server {
|
|||
.expect("initialized manager twice");
|
||||
)*
|
||||
$crate::paste::paste!{
|
||||
Ok::<_, $crate::anyhow::Error>(MultiManager{
|
||||
$( $(#[$($tt)*])* [<manager_ $module_type>] ),*
|
||||
Ok::<_, $crate::anyhow::Error>(MultiManager {
|
||||
$( $(#[$meta])* [<manager_ $module_type>] ),*
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -247,7 +247,7 @@ macro_rules! launch_rnex_module_server {
|
|||
while let Ok((mut stream, _addr)) = socket.accept().await {
|
||||
$crate::tracing::info!("new incoming connection");
|
||||
async {
|
||||
let Some(conn_data) = async {
|
||||
let Some(conn_data) = async {
|
||||
let buffer = match stream.read_buffer().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
|
|
@ -274,39 +274,51 @@ macro_rules! launch_rnex_module_server {
|
|||
return;
|
||||
};
|
||||
|
||||
$crate::rmc::new_rmc_gateway_connection(stream.into(),
|
||||
async |r| {
|
||||
$crate::tracing::info!("creating module holder for module users");
|
||||
let mut holder = $crate::ModuleHolder::default();
|
||||
$crate::rmc::new_rmc_gateway_connection(stream.into(),
|
||||
async |r| {
|
||||
$crate::tracing::info!("creating module holder for module users");
|
||||
let mut holder = $crate::ModuleHolder::default();
|
||||
|
||||
$(
|
||||
$(#[$($tt)*])*
|
||||
$crate::tracing::info!(
|
||||
module_manager = ::std::any::type_name::<<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::User>(),
|
||||
"creating user module slot"
|
||||
);
|
||||
$(#[$($tt)*])*
|
||||
holder.create_empty_module_slot::<<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::User>();
|
||||
)*
|
||||
$(
|
||||
$(#[$($tt)*])*
|
||||
$crate::tracing::info!(
|
||||
module_manager = ::std::any::type_name::<<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::User>(),
|
||||
"initializing and filling user module slot if specified as present"
|
||||
);
|
||||
$crate::paste::paste!{
|
||||
$(#[$($tt)*])*
|
||||
let [<user_ $module_type>] = holder.init_slot($crate::RnexManager::init_new_user(managers.[<manager_ $module_type>].clone(), &holder, &r, &conn_data, $crate::PassthroughInitModule::downgrade(&holder.get_ref_init_pt().expect("module slot should be initialized by now"))).await).expect("double init or uninit slot");
|
||||
}
|
||||
)*
|
||||
$crate::paste::paste!{
|
||||
::std::sync::Arc::new(MultiEndpoint{
|
||||
$(
|
||||
$(#[$meta])*
|
||||
$crate::tracing::info!(
|
||||
module_manager = ::std::any::type_name::<<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::User>(),
|
||||
"creating user module slot"
|
||||
);
|
||||
$(#[$meta])*
|
||||
holder.create_empty_module_slot::<<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::User>();
|
||||
)*
|
||||
|
||||
$( $(#[$($tt)*])* [<user_ $module_type>] ),*
|
||||
})
|
||||
}
|
||||
}
|
||||
).instrument($crate::tracing::info_span!("initializing user"))
|
||||
$(
|
||||
$(#[$meta])*
|
||||
$crate::tracing::info!(
|
||||
module_manager = ::std::any::type_name::<<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::User>(),
|
||||
"initializing and filling user module slot if specified as present"
|
||||
);
|
||||
$crate::paste::paste!{
|
||||
$(#[$meta])*
|
||||
let [<user_ $module_type>] = holder.init_slot(
|
||||
$crate::RnexManager::init_new_user(
|
||||
managers.[<manager_ $module_type>].clone(),
|
||||
&holder,
|
||||
&r,
|
||||
&conn_data,
|
||||
$crate::PassthroughInitModule::downgrade(&holder.get_ref_init_pt().expect("module slot should be initialized by now"))
|
||||
).await
|
||||
).expect("double init or uninit slot");
|
||||
|
||||
$(#[$meta])*
|
||||
<<$module_type as $crate::RnexModule>::Manager as $crate::RnexManager>::post_init([<user_ $module_type>].as_ref()).await;
|
||||
}
|
||||
)*
|
||||
|
||||
$crate::paste::paste!{
|
||||
::std::sync::Arc::new(MultiEndpoint {
|
||||
$( $(#[$meta])* [<user_ $module_type>] ),*
|
||||
})
|
||||
}
|
||||
}
|
||||
).instrument($crate::tracing::info_span!("initializing user"))
|
||||
.await;
|
||||
}
|
||||
.instrument($crate::tracing::info_span!("handeling new incoming connection"))
|
||||
|
|
@ -502,4 +514,4 @@ mod test {
|
|||
man.create_empty_module_slot::<i32>();
|
||||
man.get_ref::<i32>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,8 +9,8 @@ use std::ops::Deref;
|
|||
use std::sync::{Arc, Weak};
|
||||
use std::vec;
|
||||
use tokio::io::{self, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||
use tokio::sync::Notify;
|
||||
use tokio::sync::mpsc::{Receiver, Sender, channel};
|
||||
use tokio::task;
|
||||
use tracing::{error, info};
|
||||
|
||||
|
|
@ -19,36 +19,44 @@ pub type PID = i64;
|
|||
#[cfg(not(feature = "nx"))]
|
||||
pub type PID = i32;
|
||||
|
||||
pub const MAX_PACKET_SIZE: usize = 128 * 1024 * 1024;
|
||||
|
||||
pub trait UnitPacketRead: AsyncRead + Unpin {
|
||||
async fn read_buffer(&mut self) -> Result<Vec<u8>, io::Error> {
|
||||
let mut len_raw: [u8; _] = [0; size_of::<usize>()];
|
||||
let mut len_raw = [0u8; 8];
|
||||
|
||||
self.read_exact(&mut len_raw).await?;
|
||||
|
||||
let len = usize::from_le_bytes(len_raw);
|
||||
let len = u64::from_le_bytes(len_raw) as usize;
|
||||
|
||||
let mut vec = vec![0u8; len as _];
|
||||
if len > MAX_PACKET_SIZE {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!("packet size {len} bytes exceeds maximum allowed limit of {MAX_PACKET_SIZE} bytes"),
|
||||
));
|
||||
}
|
||||
|
||||
let mut vec = vec![0u8; len];
|
||||
self.read_exact(&mut vec).await?;
|
||||
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + Unpin> UnitPacketRead for T {}
|
||||
impl<T: AsyncRead + Unpin + ?Sized> UnitPacketRead for T {}
|
||||
|
||||
pub trait UnitPacketWrite: AsyncWrite + Unpin {
|
||||
async fn send_buffer(&mut self, data: &[u8]) -> Result<(), io::Error> {
|
||||
let len_data = data.len().to_le_bytes();
|
||||
let len_data = (data.len() as u64).to_le_bytes();
|
||||
self.write_all(&len_data[..]).await?;
|
||||
self.write_all(data).await?;
|
||||
|
||||
self.flush().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncWrite + Unpin> UnitPacketWrite for T {}
|
||||
impl<T: AsyncWrite + Unpin + ?Sized> UnitPacketWrite for T {}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SendingBufferConnection(Sender<Vec<u8>>, Arc<Notify>);
|
||||
|
|
@ -77,18 +85,40 @@ impl<T: Send + Unpin + AsyncWrite + AsyncRead + 'static> From<T> for SplittableB
|
|||
}
|
||||
|
||||
impl SplittableBufferConnection {
|
||||
fn new<T: Send + Unpin + AsyncWrite + AsyncRead + 'static>(stream: T) -> Self {
|
||||
fn new<T>(stream: T) -> Self
|
||||
where
|
||||
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||
{
|
||||
let (outside_send, inside_recv) = channel::<Vec<u8>>(10);
|
||||
let (inside_send, outside_recv) = channel::<Vec<u8>>(10);
|
||||
|
||||
let notify = Arc::new(Notify::new());
|
||||
let (mut reader, mut writer) = io::split(stream);
|
||||
|
||||
{
|
||||
task::spawn(async move {
|
||||
loop {
|
||||
match reader.read_buffer().await {
|
||||
Ok(data) => {
|
||||
if inside_send.send(data).await.is_err() {
|
||||
// reciever dropped
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("error receiving data from backend: {e}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
let notify = notify.clone();
|
||||
|
||||
task::spawn(async move {
|
||||
let sender = inside_send;
|
||||
let mut recver = inside_recv;
|
||||
let mut stream = stream;
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
|
|
@ -97,33 +127,19 @@ impl SplittableBufferConnection {
|
|||
break;
|
||||
};
|
||||
|
||||
if let Err(e) = stream.send_buffer(&data[..]).await{
|
||||
if let Err(e) = writer.send_buffer(&data[..]).await {
|
||||
error!("error sending data to backend: {e}");
|
||||
break;
|
||||
}
|
||||
},
|
||||
data = stream.read_buffer() => {
|
||||
let data = match data{
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
error!("error reveiving data from backend: {e}");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = sender.send(data).await{
|
||||
error!("a send error occurred {e}");
|
||||
return;
|
||||
}
|
||||
},
|
||||
() = notify.notified() => {
|
||||
info!("shutting down connection");
|
||||
info!("shutting down writer task");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Err(e) = stream.shutdown().await {
|
||||
error!("failed to shut down stream: {e}");
|
||||
if let Err(e) = writer.shutdown().await {
|
||||
error!("failed to shut down stream writer: {e}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -179,4 +195,4 @@ impl<T> WeakVec<T> {
|
|||
pub fn iter(&self) -> impl Iterator<Item = Arc<T>> {
|
||||
self.0.iter().filter_map(Weak::upgrade)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,6 +96,10 @@ pub struct StationUrlParseError;
|
|||
impl FromStr for StationUrl {
|
||||
type Err = StationUrlParseError;
|
||||
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||
if value.len() >= 1024 {
|
||||
return Err(StationUrlParseError);
|
||||
}
|
||||
|
||||
let (url_type, options) = value.split_at(value.find(":/").ok_or(StationUrlParseError)?);
|
||||
|
||||
let options = &options[2..];
|
||||
|
|
|
|||
Loading…
Reference in a new issue