diff --git a/.gitignore b/.gitignore index bfebb05..dd3cb4e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ asset_server/node_modules/ asset_server/resources/ target/ +*.db diff --git a/Cargo.lock b/Cargo.lock index 0f1eed1..c2ce2dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,6 +254,27 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -359,6 +380,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.0", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -483,12 +518,28 @@ version = "0.0.1" dependencies = [ "actix-web", "base64", + "chrono", + "hex", "json", + "lazy_static", "openssl", "rand", "reqwest", + "rusqlite", ] +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.0.1" @@ -634,6 +685,19 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown", +] [[package]] name = "hermit-abi" @@ -641,6 +705,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "http" version = "0.2.11" @@ -712,6 +782,29 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.5.0" @@ -783,6 +876,17 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -879,6 +983,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -1139,6 +1252,20 @@ dependencies = [ "winreg", ] +[[package]] +name = "rusqlite" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" +dependencies = [ + "bitflags 2.4.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1648,6 +1775,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 3d1d356..e64e476 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,12 @@ edition = "2021" [dependencies] actix-web = { version = "4.5.1", features = [ "openssl" ] } +rusqlite = { version = "0.30.0", features = ["bundled"] } openssl = { version = "0.10" } base64 = "0.21.5" reqwest = { version = "0.11", features = ["blocking"] } json = "0.12.4" rand = "0.8.5" +lazy_static = "1.4.0" +chrono = "0.4.31" +hex = "0.4.3" diff --git a/src/main.rs b/src/main.rs index f25e120..ab7341c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,15 +2,28 @@ mod encryption; mod router; use actix_web::{ post, + get, HttpResponse, HttpRequest, web, dev::Service }; +#[post("/api/start")] +async fn start_start(req: HttpRequest, body: String) -> HttpResponse { router::start::start(req, body) } + #[post("/api/start/assetHash")] async fn start_assethash(req: HttpRequest, body: String) -> HttpResponse { router::start::asset_hash(req, body) } +#[post("/api/dummy/login")] +async fn dummy_login(req: HttpRequest, body: String) -> HttpResponse { router::login::dummy(req, body) } + +#[get("/api/user")] +async fn user(req: HttpRequest) -> HttpResponse { router::user::user(req) } + +#[get("/api/purchase")] +async fn purchase(req: HttpRequest) -> HttpResponse { router::purchase::purchase(req) } + async fn log_unknown_request(req: HttpRequest) -> HttpResponse { println!("Unhandled request: {}", req.path()); HttpResponse::Ok().body("ok") @@ -25,7 +38,11 @@ async fn main() -> std::io::Result<()> { println!("Request: {}", req.path()); srv.call(req) }) + .service(purchase) + .service(start_start) .service(start_assethash) + .service(user) + .service(dummy_login) .default_service(web::route().to(log_unknown_request))) .bind(("0.0.0.0", 8080))? .run(); diff --git a/src/router.rs b/src/router.rs index 70b60ed..d2e36e8 100644 --- a/src/router.rs +++ b/src/router.rs @@ -1,2 +1,6 @@ pub mod start; pub mod global; +pub mod login; +pub mod userdata; +pub mod user; +pub mod purchase; diff --git a/src/router/global.rs b/src/router/global.rs index 50bb9e5..2a1917f 100644 --- a/src/router/global.rs +++ b/src/router/global.rs @@ -17,6 +17,7 @@ pub fn timestamp() -> u64 { } pub fn send(data: JsonValue) -> HttpResponse { + //println!("{}", json::stringify(data.clone())); let encrypted = encryption::encrypt_packet(&json::stringify(data)).unwrap(); let resp = encrypted.into_bytes(); diff --git a/src/router/login.rs b/src/router/login.rs new file mode 100644 index 0000000..fea93cd --- /dev/null +++ b/src/router/login.rs @@ -0,0 +1,24 @@ +use json; +use json::object; +use crate::router::global; +//use crate::encryption; +use actix_web::{HttpResponse, HttpRequest, http::header::HeaderValue}; +use crate::router::userdata; + +//First time login handler +pub fn dummy(req: HttpRequest, _body: String) -> HttpResponse { + //let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap(); + let blank_header = HeaderValue::from_static(""); + let key = req.headers().get("a6573cbe").unwrap_or(&blank_header).to_str().unwrap_or(""); + let user = userdata::get_acc(key, ""); + + println!("new uid: {}", user["user"]["id"].clone()); + let resp = object!{ + "code": 0, + "server_time": global::timestamp(), + "data": { + "user_id": user["user"]["id"].clone() + } + }; + global::send(resp) +} diff --git a/src/router/purchase.rs b/src/router/purchase.rs new file mode 100644 index 0000000..151a0ec --- /dev/null +++ b/src/router/purchase.rs @@ -0,0 +1,277 @@ +use json; +use json::object; +use crate::router::global; +use actix_web::{HttpResponse, HttpRequest}; + +pub fn purchase(_req: HttpRequest) -> HttpResponse { + + let resp = object!{ + "code": 0, + "server_time": global::timestamp(), + "data": { + "product_list": [//Client will error if this is an empty array + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.promo.4199", + "name": "6000 Love Gems", + "description": "6000 Paid Love Gems", + "thumbnail_url": null, + "charge_gem": 6000, + "free_gem": 0, + "campaign_type": 2, + "campaign_mode": 5, + "priority": 1, + "price": "999999.99", + "currency_code": "USD", + "formatted_price": "USD$999999.99", + "consumable": 0, + "limited_count": 2, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": "2024-02-01 00:00:00", + "end_datetime": "2024-02-29 23:59:59", + "total_gem": 6000 + } + ] + } + }; + global::send(resp) +} + +/* +resp.data = { + "product_list": [ + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.promo.4199", + "name": "6000 Love Gems", + "description": "6000 Paid Love Gems", + "thumbnail_url": null, + "charge_gem": 6000, + "free_gem": 0, + "campaign_type": 2, + "campaign_mode": 5, + "priority": 1, + "price": "34.99", + "currency_code": "USD", + "formatted_price": "USD$34.99", + "consumable": 0, + "limited_count": 2, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": "2024-02-01 00:00:00", + "end_datetime": "2024-02-29 23:59:59", + "total_gem": 6000 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.promo.8499", + "name": "13000 Love Gems", + "description": "13000 Paid Love Gems", + "thumbnail_url": null, + "charge_gem": 13000, + "free_gem": 0, + "campaign_type": 2, + "campaign_mode": 5, + "priority": 2, + "price": "69.99", + "currency_code": "USD", + "formatted_price": "USD$69.99", + "consumable": 0, + "limited_count": 2, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": "2024-02-01 00:00:00", + "end_datetime": "2024-02-29 23:59:59", + "total_gem": 13000 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.299", + "name": "140 Love Gems", + "description": "140 Paid Love Gems", + "thumbnail_url": null, + "charge_gem": 140, + "free_gem": 0, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 11, + "price": "0.99", + "currency_code": "USD", + "formatted_price": "USD$0.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 140 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.499", + "name": "430 Love Gems", + "description": "420 Paid Love Gems + 10 Free LoveGems", + "thumbnail_url": null, + "charge_gem": 420, + "free_gem": 10, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 12, + "price": "2.99", + "currency_code": "USD", + "formatted_price": "USD$2.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 430 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.899", + "name": "910 Love Gems", + "description": "870 Paid Love Gems + 40 Free LoveGems", + "thumbnail_url": null, + "charge_gem": 870, + "free_gem": 40, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 13, + "price": "6.99", + "currency_code": "USD", + "formatted_price": "USD$6.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 910 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.1299", + "name": "1380 Love Gems", + "description": "1310 Paid Love Gems + 70 Free LoveGems", + "thumbnail_url": null, + "charge_gem": 1310, + "free_gem": 70, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 14, + "price": "9.99", + "currency_code": "USD", + "formatted_price": "USD$9.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 1380 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.2499", + "name": "2700 Love Gems", + "description": "2530 Paid Love Gems + 170 Free LoveGems", + "thumbnail_url": null, + "charge_gem": 2530, + "free_gem": 170, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 15, + "price": "19.99", + "currency_code": "USD", + "formatted_price": "USD$19.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 2700 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.4199", + "name": "4800 Love Gems", + "description": "4460 Paid Love Gems + 340 Free LoveGems", + "thumbnail_url": null, + "charge_gem": 4460, + "free_gem": 340, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 16, + "price": "34.99", + "currency_code": "USD", + "formatted_price": "USD$34.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 4800 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.6499", + "name": "7500 Love Gems", + "description": "6730 Paid Love Gems + 770 Free LoveGems", + "thumbnail_url": null, + "charge_gem": 6730, + "free_gem": 770, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 17, + "price": "49.99", + "currency_code": "USD", + "formatted_price": "USD$49.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 7500 + }, + { + "product_id": "com.bushiroad.global.lovelive.sif2.google.gem.8499", + "name": "10100 Love Gems", + "description": "8910 Paid Love Gems + 1190 Free LoveGems", + "thumbnail_url": null, + "charge_gem": 8910, + "free_gem": 1190, + "campaign_type": 0, + "campaign_mode": 0, + "priority": 18, + "price": "69.99", + "currency_code": "USD", + "formatted_price": "USD$69.99", + "consumable": 1, + "limited_count": 0, + "product_type": 0, + "amenity_label": null, + "ticket_valid_days": null, + "ticket_issuing_gem": null, + "start_datetime": null, + "end_datetime": null, + "total_gem": 10100 + } + ] +} +*/ diff --git a/src/router/start.rs b/src/router/start.rs index 948b23b..084707e 100644 --- a/src/router/start.rs +++ b/src/router/start.rs @@ -2,7 +2,8 @@ use json; use json::object; use crate::router::global; use crate::encryption; -use actix_web::{HttpResponse, HttpRequest}; +use actix_web::{HttpResponse, HttpRequest, http::header::HeaderValue}; +use crate::router::userdata; pub fn asset_hash(_req: HttpRequest, body: String) -> HttpResponse { let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap(); @@ -18,3 +19,29 @@ pub fn asset_hash(_req: HttpRequest, body: String) -> HttpResponse { }; global::send(resp) } + +pub fn start(req: HttpRequest, body: String) -> HttpResponse { + let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap(); + if body["asset_version"].to_string() != global::ASSET_VERSION { + println!("Warning! Asset version is not what was expected. (Did the app update?)"); + } + let blank_header = HeaderValue::from_static(""); + let key = req.headers().get("a6573cbe").unwrap_or(&blank_header).to_str().unwrap_or(""); + let uid = req.headers().get("aoharu-user-id").unwrap_or(&blank_header).to_str().unwrap_or(""); + let mut user = userdata::get_acc(key, uid); + + user["user"]["last_login_time"] = global::timestamp().into(); + user["stamina"]["last_updated_time"] = global::timestamp().into(); + + userdata::save_acc(key, uid, user); + + let resp = object!{ + "code": 0, + "server_time": global::timestamp(), + "data": { + "asset_hash": global::ASSET_HASH, + "token": hex::encode("Hello") //what is this? + } + }; + global::send(resp) +} diff --git a/src/router/user.rs b/src/router/user.rs new file mode 100644 index 0000000..b24bb5c --- /dev/null +++ b/src/router/user.rs @@ -0,0 +1,20 @@ +use json; +use json::object; +use crate::router::global; +use actix_web::{HttpResponse, HttpRequest, http::header::HeaderValue}; +use crate::router::userdata; + +pub fn user(req: HttpRequest) -> HttpResponse { + let blank_header = HeaderValue::from_static(""); + + let key = req.headers().get("a6573cbe").unwrap_or(&blank_header).to_str().unwrap_or(""); + let uid = req.headers().get("aoharu-user-id").unwrap_or(&blank_header).to_str().unwrap_or(""); + let user = userdata::get_acc(key, uid); + + let resp = object!{ + "code": 0, + "server_time": global::timestamp(), + "data": user + }; + global::send(resp) +} diff --git a/src/router/userdata/mod.rs b/src/router/userdata/mod.rs new file mode 100644 index 0000000..d5cffe6 --- /dev/null +++ b/src/router/userdata/mod.rs @@ -0,0 +1,167 @@ +use rusqlite::{Connection, params}; +use std::sync::{Mutex, MutexGuard}; +use lazy_static::lazy_static; +use json::{JsonValue, array}; +//use base64::{Engine as _, engine::general_purpose}; + +lazy_static! { + pub static ref ENGINE: Mutex> = Mutex::new(None); +} + +fn init(engine: &mut MutexGuard<'_, Option>) { + let conn = Connection::open("userdata.db").unwrap(); + conn.execute("PRAGMA foreign_keys = ON;", ()).unwrap(); + + engine.replace(conn); +} +fn create_uid_store(conn: &Connection) { + match conn.prepare("SELECT jsondata FROM uids") { + Ok(_) => {} + Err(_) => { + conn.execute( + "CREATE TABLE uids ( + jsondata TEXT NOT NULL + )", + (), // empty list of parameters. + ).unwrap(); + init_data(conn, "uids", array![]); + } + } + store_data(conn, "uids", array![]); +} +fn acc_exists(conn: &Connection, key: i64) -> bool { + conn.prepare(&format!("SELECT jsondata FROM _{}_", key)).is_ok() +} +fn store_data(conn: &Connection, key: &str, value: JsonValue) { + conn.execute( + &format!("UPDATE {} SET jsondata=?1", key), + params!(json::stringify(value)) + ).unwrap(); +} +fn init_data(conn: &Connection, key: &str, value: JsonValue) { + conn.execute( + &format!("INSERT INTO {} (jsondata) VALUES (?1)", key), + params!(json::stringify(value)) + ).unwrap(); +} + +use rand::Rng; +fn get_uids(conn: &Connection) -> JsonValue { + let mut stmt = conn.prepare("SELECT jsondata FROM uids").unwrap(); + let result: Result = stmt.query_row([], |row| row.get(0)); + json::parse(&result.unwrap()).unwrap() +} + +fn generate_uid(conn: &Connection) -> i64 { + create_uid_store(conn); + let mut rng = rand::thread_rng(); + let random_number = rng.gen_range(100_000_000_000_000..=999_999_999_999_999); + let mut existing_ids = get_uids(conn); + //the chances of this...? + if existing_ids.contains(random_number) { + return generate_uid(conn); + } + existing_ids.push(random_number).unwrap(); + store_data(conn, "uids", existing_ids); + + random_number +} + +fn create_acc(conn: &Connection, uid: i64) { + let key = &uid.to_string(); + conn.execute( + &format!("CREATE TABLE _{}_ ( + jsondata TEXT NOT NULL + )", key), + (), + ).unwrap(); + let mut data = json::parse(include_str!("new_user.json")).unwrap(); + data["user"]["id"] = uid.into(); + + init_data(conn, &format!("_{}_", key), data); +} + +//a6573cbe is the name of the header - todo - more secure than just uid +pub fn get_acc(_a6573cbe: &str, uid: &str) -> JsonValue { + //let decoded = general_purpose::STANDARD.decode(a6573cbe).unwrap(); + //let header = String::from_utf8_lossy(&decoded); + + loop { + match ENGINE.lock() { + Ok(mut result) => { + if result.is_none() { + init(&mut result); + } + let conn = result.as_ref().unwrap(); + + let key: i64; + /* + if header.starts_with("0") { + key = generate_uid(conn); + create_acc(conn, key); + } else { + key = header[..15].parse::().unwrap();//.unwrap_or(generate_uid(conn)); + }*/ + if uid == "" { + key = generate_uid(conn); + create_acc(conn, key); + } else { + key = uid.parse::().unwrap(); + } + + if !acc_exists(conn, key) { + create_acc(conn, key); + } + let mut stmt = conn.prepare(&format!("SELECT jsondata FROM _{}_", key)).unwrap(); + let result: Result = stmt.query_row([], |row| row.get(0)); + + let rv = json::parse(&result.unwrap()).unwrap(); + + return rv; + } + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(15)); + } + } + } +} + +pub fn save_acc(_a6573cbe: &str, uid: &str, data: JsonValue) { + //let decoded = general_purpose::STANDARD.decode(a6573cbe).unwrap(); + //let header = String::from_utf8_lossy(&decoded); + + loop { + match ENGINE.lock() { + Ok(mut result) => { + if result.is_none() { + init(&mut result); + } + let conn = result.as_ref().unwrap(); + + let key: i64; + /* + if header.starts_with("0") { + key = generate_uid(conn); + create_acc(conn, key); + } else { + key = header[..15].parse::().unwrap();//.unwrap_or(generate_uid(conn)); + }*/ + if uid == "" { + key = generate_uid(conn); + create_acc(conn, key); + } else { + key = uid.parse::().unwrap(); + } + + if !acc_exists(conn, key) { + create_acc(conn, key); + } + store_data(conn, &format!("_{}_", key), data); + break; + } + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(15)); + } + } + } +} diff --git a/src/router/userdata/new_user.json b/src/router/userdata/new_user.json new file mode 100644 index 0000000..b95264d --- /dev/null +++ b/src/router/userdata/new_user.json @@ -0,0 +1,61 @@ +{ + "user": { + "id": 0, + "name": "Tutorial in progress", + "comment": "Lean and Play!", + "exp": 0, + "main_deck_slot": 1, + "favorite_master_card_id": 0, + "favorite_card_evolve": 0, + "guest_smile_master_card_id": 0, + "guest_cool_master_card_id": 0, + "guest_pure_master_card_id": 0, + "friend_request_disabled" :1, + "master_title_ids": [0,0], + "profile_settings": [1,2,3,4,5,6,7], + "sif_user_id": 0, + "ss_user_id": 0, + "birthday": "", + "last_login_time": 0 + }, + "gem": { + "total": 0, + "charge": 0, + "free": 0 + }, + "card_list": [], + "deck_list": [ + {"slot": 1,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 2,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 3,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 4,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 5,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 6,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 7,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 8,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 9,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 10,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]}, + {"slot": 100,"leader_role": 0,"main_card_ids": [0,0,0,0,0,0,0,0,0]} + ], + "stamina": { + "stamina": 100, + "last_updated_time": 0 + }, + "character_list": [], + "tutorial_step": 0, + "item_list": [], + "point_list": [], + "story_list": [], + "live_list": [], + "live_mission_list": [], + "master_music_ids": [1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1014,1015,1016,1017,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1035,1037,1038,1039,1040,1041,1042,1044,1045,1046,1047,1048,1049,1050,1054,1055,1057,1058,1059,1060,1061,1062,1063,1064,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1123,1124,1126,1127,1128,1129,1130,1131,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,2079,2080,2081,2082,2083,2084,2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3034,3035,3036,3037,3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3121,3122,3123,3124,3125,3126,3127,3128,3129,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4059,4060,4061,4064,4065,4066,4067,4068,4069,4071,4073,4074,4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088,4089,4090,4091,4092,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,4110,4111,4112,4113,4114,4115,4116,5001,5002,5003,5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,5019,5020,5021,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,9031,9032], + "event_point_list": [], + "start_time": null, + "master_title_ids": [], + "lottery_list": [], + "shop_list": [], + "function_lock_list": [], + "movie": null, + "subscription_list": [], + "membership": [] +}