Implement friend endpoints

This commit is contained in:
Ethan O'Brien 2024-04-15 16:17:44 -05:00
parent 8f018f558a
commit 597ed7fb34
5 changed files with 274 additions and 67 deletions

View file

@ -99,6 +99,24 @@ async fn tutorial(req: HttpRequest, body: String) -> HttpResponse { router::tuto
#[post("/api/friend")] #[post("/api/friend")]
async fn friend(req: HttpRequest, body: String) -> HttpResponse { router::friend::friend(req, body) } async fn friend(req: HttpRequest, body: String) -> HttpResponse { router::friend::friend(req, body) }
#[get("/api/friend/ids")]
async fn friend_ids(req: HttpRequest) -> HttpResponse { router::friend::ids(req) }
#[post("/api/friend/search")]
async fn friend_search(req: HttpRequest, body: String) -> HttpResponse { router::friend::search(req, body) }
#[post("/api/friend/search/recommend")]
async fn friend_recommend(req: HttpRequest, body: String) -> HttpResponse { router::friend::recommend(req, body) }
#[post("/api/friend/request")]
async fn friend_request(req: HttpRequest, body: String) -> HttpResponse { router::friend::request(req, body) }
#[post("/api/friend/request/approve")]
async fn friend_approve(req: HttpRequest, body: String) -> HttpResponse { router::friend::approve(req, body) }
#[post("/api/friend/request/cancel")]
async fn friend_cancel(req: HttpRequest, body: String) -> HttpResponse { router::friend::cancel(req, body) }
#[post("/api/live/guest")] #[post("/api/live/guest")]
async fn live_guest(req: HttpRequest, body: String) -> HttpResponse { router::live::guest(req, body) } async fn live_guest(req: HttpRequest, body: String) -> HttpResponse { router::live::guest(req, body) }
@ -241,6 +259,12 @@ async fn main() -> std::io::Result<()> {
.service(lottery_post) .service(lottery_post)
.service(lottery) .service(lottery)
.service(friend) .service(friend)
.service(friend_search)
.service(friend_recommend)
.service(friend_ids)
.service(friend_request)
.service(friend_approve)
.service(friend_cancel)
.service(mission) .service(mission)
.service(mission_clear) .service(mission_clear)
.service(mission_receive) .service(mission_receive)

View file

@ -1,21 +1,147 @@
use json; use json::{object, array};
use json::object;
use crate::router::global; use crate::router::global;
use actix_web::{HttpResponse, HttpRequest}; use actix_web::{HttpResponse, HttpRequest};
//use crate::router::userdata; use crate::router::userdata;
use crate::encryption;
pub fn friend(_req: HttpRequest, _body: String) -> HttpResponse { pub fn friend(req: HttpRequest, body: String) -> HttpResponse {
/*let blank_header = HeaderValue::from_static(""); let key = global::get_login(req.headers(), &body);
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let friends = userdata::get_acc_friends(&key);
let key = global::get_login(req.headers()); let mut rv = array![];
let user = userdata::get_acc(&key, uid);*/
let rv_data = if body["status"].as_i32().unwrap() == 3 {
friends["friend_user_id_list"].clone()
} else if body["status"].as_i32().unwrap() == 2 {
friends["pending_user_id_list"].clone()
} else if body["status"].as_i32().unwrap() == 1 {
friends["request_user_id_list"].clone()
} else {
array![]
};
for (_i, uid) in rv_data.members().enumerate() {
let mut to_push = global::get_user(uid.as_i64().unwrap());
to_push["status"] = body["status"].clone();
rv.push(to_push).unwrap();
}
let resp = object!{ let resp = object!{
"code": 0, "code": 0,
"server_time": global::timestamp(), "server_time": global::timestamp(),
"data": { "data": {
"friend_list": [] //todo - pull from userdata "friend_list": rv
} }
}; };
global::send(resp) global::send(resp)
} }
pub fn ids(req: HttpRequest) -> HttpResponse {
let key = global::get_login(req.headers(), "");
let friends = userdata::get_acc_friends(&key);
let resp = object!{
"code": 0,
"server_time": global::timestamp(),
"data": friends
};
global::send(resp)
}
pub fn recommend(_req: HttpRequest, _body: String) -> HttpResponse {
let resp = object!{
"code": 0,
"server_time": global::timestamp(),
"data": {
friend_list: []
}
};
global::send(resp)
}
pub fn search(_req: HttpRequest, body: String) -> HttpResponse {
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let uid = body["user_id"].as_i64().unwrap();
let user = global::get_user(uid);
let resp = object!{
"code": 0,
"server_time": global::timestamp(),
"data": user
};
global::send(resp)
}
pub fn request(req: HttpRequest, body: String) -> HttpResponse {
let key = global::get_login(req.headers(), &body);
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let user_id = userdata::get_acc(&key)["user"]["id"].as_i64().unwrap();
let mut friends = userdata::get_acc_friends(&key);
let uid = body["user_id"].as_i64().unwrap();
if !userdata::friend_request_disabled(uid) {
if !friends["request_user_id_list"].contains(uid) {
friends["request_user_id_list"].push(uid).unwrap();
userdata::save_acc_friends(&key, friends);
}
userdata::friend_request(uid, user_id);
}
let resp = object!{
"code": 0,
"server_time": global::timestamp(),
"data": []
};
global::send(resp)
}
pub fn approve(req: HttpRequest, body: String) -> HttpResponse {
let key = global::get_login(req.headers(), &body);
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let user_id = userdata::get_acc(&key)["user"]["id"].as_i64().unwrap();
let mut friends = userdata::get_acc_friends(&key);
let uid = body["user_id"].as_i64().unwrap();
let index = friends["request_user_id_list"].members().into_iter().position(|r| *r.to_string() == uid.to_string());
if !index.is_none() {
friends["request_user_id_list"].array_remove(index.unwrap());
}
if body["approve"].to_string() == "1" && ! friends["friend_user_id_list"].contains(uid) {
friends["friend_user_id_list"].push(uid).unwrap();
}
userdata::friend_request_approve(uid, user_id, body["approve"].to_string() == "1");
userdata::save_acc_friends(&key, friends);
let resp = object!{
"code": 0,
"server_time": global::timestamp(),
"data": []
};
global::send(resp)
}
pub fn cancel(req: HttpRequest, body: String) -> HttpResponse {
let key = global::get_login(req.headers(), &body);
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let user_id = userdata::get_acc(&key)["user"]["id"].as_i64().unwrap();
let mut friends = userdata::get_acc_friends(&key);
let uid = body["user_id"].as_i64().unwrap();
let index = friends["request_user_id_list"].members().into_iter().position(|r| *r.to_string() == uid.to_string());
if !index.is_none() {
friends["request_user_id_list"].array_remove(index.unwrap());
}
userdata::friend_request_approve(uid, user_id, false);
userdata::save_acc_friends(&key, friends);
let resp = object!{
"code": 0,
"server_time": global::timestamp(),
"data": []
};
global::send(resp)
}

View file

@ -1,4 +1,4 @@
use json::{object, JsonValue}; use json::{object, JsonValue, array};
use crate::encryption; use crate::encryption;
use actix_web::{ use actix_web::{
HttpResponse, HttpResponse,
@ -7,6 +7,7 @@ use actix_web::{
use crate::router::gree; use crate::router::gree;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use base64::{Engine as _, engine::general_purpose}; use base64::{Engine as _, engine::general_purpose};
use crate::router::userdata;
pub const ASSET_VERSION: &str = "13177023d4b7ad41ff52af4cefba5c55"; pub const ASSET_VERSION: &str = "13177023d4b7ad41ff52af4cefba5c55";
pub const ASSET_HASH_ANDROID: &str = "017ec1bcafbeea6a7714f0034b15bd0f"; pub const ASSET_HASH_ANDROID: &str = "017ec1bcafbeea6a7714f0034b15bd0f";
@ -135,3 +136,60 @@ pub fn give_exp(amount: i32, user: &mut JsonValue) {
user["stamina"]["last_updated_time"] = timestamp().into(); user["stamina"]["last_updated_time"] = timestamp().into();
} }
} }
fn get_card(id: i64, user: &JsonValue) -> JsonValue {
if id == 0 {
return object!{};
}
for (_i, data) in user["card_list"].members().enumerate() {
if data["master_card_id"].as_i64().unwrap_or(0) == id {
return data.clone();
}
}
return object!{};
}
fn get_cards(arr: JsonValue, user: &JsonValue) -> JsonValue {
let mut rv = array![];
for (_i, data) in arr.members().enumerate() {
let to_push = get_card(data.as_i64().unwrap_or(0), user);
if to_push.is_empty() {
continue;
}
rv.push(to_push).unwrap();
}
return rv;
}
pub fn get_user(id: i64) -> JsonValue {
let user = userdata::get_acc_from_uid(id);
if !user["error"].is_empty() {
return object!{};
}
let mut rv = object!{
user: user["user"].clone(),
live_data_summary: {
clear_count_list: [0, 0, 0, 0],
full_combo_list: [0, 0, 0, 0],
all_perfect_list: [0, 0, 0, 0],
high_score_rate: {
rate: 0,
detail: []
}
},
main_deck_detail: {
total_power: 0, //how to calculate?
deck: user["deck_list"][user["user"]["main_deck_slot"].as_usize().unwrap_or(1) - 1].clone(),
card_list: get_cards(user["deck_list"][user["user"]["main_deck_slot"].as_usize().unwrap_or(1) - 1]["main_card_ids"].clone(), &user)
},
favorite_card: get_card(user["user"]["favorite_master_card_id"].as_i64().unwrap_or(0), &user),
guest_smile_card: get_card(user["user"]["guest_smile_master_card_id"].as_i64().unwrap_or(0), &user),
guest_cool_card: get_card(user["user"]["guest_cool_master_card_id"].as_i64().unwrap_or(0), &user),
guest_pure_card: get_card(user["user"]["guest_pure_master_card_id"].as_i64().unwrap_or(0), &user),
master_title_ids: user["master_title_ids"].clone()
};
rv["user"].remove("sif_user_id");
rv["user"].remove("ss_user_id");
rv["user"].remove("birthday");
rv
}

View file

@ -364,63 +364,14 @@ pub fn migration(_req: HttpRequest, body: String) -> HttpResponse {
}; };
global::send(resp) global::send(resp)
} }
fn get_card(id: i64, user: &JsonValue) -> JsonValue {
if id == 0 {
return object!{};
}
for (_i, data) in user["card_list"].members().enumerate() {
if data["master_card_id"].as_i64().unwrap_or(0) == id {
return data.clone();
}
}
return object!{};
}
fn get_cards(arr: JsonValue, user: &JsonValue) -> JsonValue {
let mut rv = array![];
for (_i, data) in arr.members().enumerate() {
let to_push = get_card(data.as_i64().unwrap_or(0), user);
if to_push.is_empty() {
continue;
}
rv.push(to_push).unwrap();
}
return rv;
}
pub fn detail(_req: HttpRequest, body: String) -> HttpResponse { pub fn detail(_req: HttpRequest, body: String) -> HttpResponse {
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap(); let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let mut user_detail_list = array![]; let mut user_detail_list = array![];
for (_i, data) in body["user_ids"].members().enumerate() { for (_i, data) in body["user_ids"].members().enumerate() {
let uid = data.as_i64().unwrap(); let uid = data.as_i64().unwrap();
let user = userdata::get_acc_from_uid(uid); let user = global::get_user(uid);
user_detail_list.push(user).unwrap();
let mut to_push = object!{
user: user["user"].clone(),
live_data_summary: {
clear_count_list: [0, 0, 0, 0],
full_combo_list: [0, 0, 0, 0],
all_perfect_list: [0, 0, 0, 0],
high_score_rate: {
rate: 0,
detail: []
}
},
main_deck_detail: {
total_power: 0, //how to calculate?
deck: user["deck_list"][user["user"]["main_deck_slot"].as_usize().unwrap_or(1) - 1].clone(),
card_list: get_cards(user["deck_list"][user["user"]["main_deck_slot"].as_usize().unwrap_or(1) - 1]["main_card_ids"].clone(), &user)
},
favorite_card: get_card(user["user"]["favorite_master_card_id"].as_i64().unwrap_or(0), &user),
guest_smile_card: get_card(user["user"]["guest_smile_master_card_id"].as_i64().unwrap_or(0), &user),
guest_cool_card: get_card(user["user"]["guest_cool_master_card_id"].as_i64().unwrap_or(0), &user),
guest_pure_card: get_card(user["user"]["guest_pure_master_card_id"].as_i64().unwrap_or(0), &user),
master_title_ids: user["master_title_ids"].clone()
};
to_push["user"].remove("sif_user_id");
to_push["user"].remove("ss_user_id");
to_push["user"].remove("birthday");
user_detail_list.push(to_push).unwrap();
} }
let resp = object!{ let resp = object!{
"code": 0, "code": 0,

View file

@ -100,7 +100,8 @@ fn create_users_store() {
userhome TEXT NOT NULL, userhome TEXT NOT NULL,
missions TEXT NOT NULL, missions TEXT NOT NULL,
loginbonus TEXT NOT NULL, loginbonus TEXT NOT NULL,
sifcards TEXT NOT NULL sifcards TEXT NOT NULL,
friends TEXT NOT NULL
)"); )");
} }
@ -147,13 +148,14 @@ fn create_acc(uid: i64, login: &str) {
new_user["user"]["id"] = uid.into(); new_user["user"]["id"] = uid.into();
new_user["stamina"]["last_updated_time"] = global::timestamp().into(); new_user["stamina"]["last_updated_time"] = global::timestamp().into();
lock_and_exec("INSERT INTO users (user_id, userdata, userhome, missions, loginbonus, sifcards) VALUES (?1, ?2, ?3, ?4, ?5, ?6)", params!( lock_and_exec("INSERT INTO users (user_id, userdata, userhome, missions, loginbonus, sifcards, friends) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)", params!(
uid, uid,
json::stringify(new_user), json::stringify(new_user),
include_str!("new_user_home.json"), include_str!("new_user_home.json"),
include_str!("chat_missions.json"), include_str!("chat_missions.json"),
format!(r#"{{"last_rewarded": 0, "bonus_list": [], "start_time": {}}}"#, global::timestamp()), format!(r#"{{"last_rewarded": 0, "bonus_list": [], "start_time": {}}}"#, global::timestamp()),
"[]" "[]",
r#"{"friend_user_id_list":[],"request_user_id_list":[],"pending_user_id_list":[]}"#
)); ));
create_token_store(); create_token_store();
@ -224,6 +226,9 @@ pub fn get_acc_loginbonus(auth_key: &str) -> JsonValue {
pub fn get_acc_sif(auth_key: &str) -> JsonValue { pub fn get_acc_sif(auth_key: &str) -> JsonValue {
get_data(auth_key, "sifcards") get_data(auth_key, "sifcards")
} }
pub fn get_acc_friends(auth_key: &str) -> JsonValue {
get_data(auth_key, "friends")
}
pub fn save_data(auth_key: &str, row: &str, data: JsonValue) { pub fn save_data(auth_key: &str, row: &str, data: JsonValue) {
let key = get_key(&auth_key); let key = get_key(&auth_key);
@ -243,6 +248,9 @@ pub fn save_acc_missions(auth_key: &str, data: JsonValue) {
pub fn save_acc_loginbonus(auth_key: &str, data: JsonValue) { pub fn save_acc_loginbonus(auth_key: &str, data: JsonValue) {
save_data(auth_key, "loginbonus", data); save_data(auth_key, "loginbonus", data);
} }
pub fn save_acc_friends(auth_key: &str, data: JsonValue) {
save_data(auth_key, "friends", data);
}
pub fn get_acc_transfer(uid: i64, token: &str, password: &str) -> JsonValue { pub fn get_acc_transfer(uid: i64, token: &str, password: &str) -> JsonValue {
create_migration_store(); create_migration_store();
@ -267,7 +275,6 @@ pub fn save_acc_transfer(token: &str, password: &str) {
} }
pub fn get_name_and_rank(uid: i64) -> JsonValue { pub fn get_name_and_rank(uid: i64) -> JsonValue {
create_migration_store();
let login_token = get_login_token(uid); let login_token = get_login_token(uid);
if login_token == String::new() { if login_token == String::new() {
return object!{ return object!{
@ -292,12 +299,10 @@ pub fn get_name_and_rank(uid: i64) -> JsonValue {
} }
pub fn get_acc_from_uid(uid: i64) -> JsonValue { pub fn get_acc_from_uid(uid: i64) -> JsonValue {
create_migration_store();
let login_token = get_login_token(uid); let login_token = get_login_token(uid);
if login_token == String::new() { if login_token == String::new() {
return object!{ return object!{
user_name: "", error: true
user_rank: 1
} }
} }
let uid = get_uid(&login_token); let uid = get_uid(&login_token);
@ -307,3 +312,46 @@ pub fn get_acc_from_uid(uid: i64) -> JsonValue {
let result = lock_and_select("SELECT userdata FROM users WHERE user_id=?1", params!(uid)); let result = lock_and_select("SELECT userdata FROM users WHERE user_id=?1", params!(uid));
json::parse(&result.unwrap()).unwrap() json::parse(&result.unwrap()).unwrap()
} }
pub fn friend_request(uid: i64, requestor: i64) {
let login_token = get_login_token(uid);
if login_token == String::new() {
return;
}
let uid = get_uid(&login_token);
let friends = lock_and_select("SELECT friends FROM users WHERE user_id=?1", params!(uid));
let mut friends = json::parse(&friends.unwrap()).unwrap();
if !friends["pending_user_id_list"].contains(requestor) {
friends["pending_user_id_list"].push(requestor).unwrap();
lock_and_exec("UPDATE users SET friends=?1 WHERE user_id=?2", params!(json::stringify(friends), uid));
}
}
pub fn friend_request_approve(uid: i64, requestor: i64, accepted: bool) {
let login_token = get_login_token(uid);
if login_token == String::new() {
return;
}
let uid = get_uid(&login_token);
let friends = lock_and_select("SELECT friends FROM users WHERE user_id=?1", params!(uid));
let mut friends = json::parse(&friends.unwrap()).unwrap();
let index = friends["pending_user_id_list"].members().into_iter().position(|r| *r.to_string() == requestor.to_string());
if !index.is_none() {
friends["pending_user_id_list"].array_remove(index.unwrap());
}
if accepted && !friends["friend_user_id_list"].contains(requestor) {
friends["friend_user_id_list"].push(requestor).unwrap();
}
lock_and_exec("UPDATE users SET friends=?1 WHERE user_id=?2", params!(json::stringify(friends), uid));
}
pub fn friend_request_disabled(uid: i64) -> bool {
let login_token = get_login_token(uid);
if login_token == String::new() {
return true;
}
let uid = get_uid(&login_token);
let user = lock_and_select("SELECT userdata FROM users WHERE user_id=?1", params!(uid));
let user = json::parse(&user.unwrap()).unwrap();
user["user"]["friend_request_disabled"].to_string() == "1"
}