Implement (somwhat) accurate login bonus functionality

This commit is contained in:
Ethan O'Brien 2024-04-09 16:46:49 -05:00
parent fafe5ba1f1
commit 37410f888e
6 changed files with 214 additions and 10 deletions

View file

@ -84,6 +84,9 @@ async fn user_initialize(req: HttpRequest, body: String) -> HttpResponse { route
#[post("/api/user/detail")] #[post("/api/user/detail")]
async fn user_detail(req: HttpRequest, body: String) -> HttpResponse { router::user::detail(req, body) } async fn user_detail(req: HttpRequest, body: String) -> HttpResponse { router::user::detail(req, body) }
#[post("/api/gift")]
async fn gift(req: HttpRequest, body: String) -> HttpResponse { router::user::gift(req, body) }
#[post("/api/deck")] #[post("/api/deck")]
async fn user_deck(req: HttpRequest, body: String) -> HttpResponse { router::user::deck(req, body) } async fn user_deck(req: HttpRequest, body: String) -> HttpResponse { router::user::deck(req, body) }
@ -242,6 +245,7 @@ async fn main() -> std::io::Result<()> {
.service(gglrequestmigrationcode) .service(gglrequestmigrationcode)
.service(gglverifymigrationcode) .service(gglverifymigrationcode)
.service(serial_code_events) .service(serial_code_events)
.service(gift)
.default_service(web::route().to(log_unknown_request))) .default_service(web::route().to(log_unknown_request)))
.bind(("0.0.0.0", 8080))? .bind(("0.0.0.0", 8080))?
.run(); .run();

View file

@ -56,6 +56,15 @@ pub fn timestamp() -> u64 {
let unix_timestamp = now.duration_since(UNIX_EPOCH).unwrap(); let unix_timestamp = now.duration_since(UNIX_EPOCH).unwrap();
return unix_timestamp.as_secs(); return unix_timestamp.as_secs();
} }
pub fn timestamp_since_midnight() -> u64 {
let now = SystemTime::now();
let unix_timestamp = now.duration_since(UNIX_EPOCH).unwrap();
let midnight = unix_timestamp.as_secs() % (24 * 60 * 60);
let rv = unix_timestamp.as_secs() - midnight;
rv
}
pub fn send(data: JsonValue) -> HttpResponse { pub fn send(data: JsonValue) -> HttpResponse {
//println!("{}", json::stringify(data.clone())); //println!("{}", json::stringify(data.clone()));
@ -72,7 +81,6 @@ pub fn error_resp() -> HttpResponse {
// true - added // true - added
// false - already has // false - already has
pub fn give_character(id: String, user: &mut JsonValue) -> bool { pub fn give_character(id: String, user: &mut JsonValue) -> bool {
for (_i, data) in user["card_list"].members().enumerate() { for (_i, data) in user["card_list"].members().enumerate() {
if data["master_card_id"].to_string() == id { if data["master_card_id"].to_string() == id {
return false; return false;
@ -90,3 +98,20 @@ pub fn give_character(id: String, user: &mut JsonValue) -> bool {
user["card_list"].push(to_push.clone()).unwrap(); user["card_list"].push(to_push.clone()).unwrap();
true true
} }
pub fn gift_item(item: &JsonValue, user: &mut JsonValue) {
let to_push = object!{
id: item["id"].clone(),
reward_type: item["type"].clone(),
give_type: item["giveType"].clone(),
is_receive: 0,
reason_text: "Because you logged in!!!!!!!!!!!!",
value: item["value"].clone(),
level: item["level"].clone(),
amount: item["amount"].clone(),
created_date_time: timestamp(),
expire_date_time: timestamp() + (5 * (24 * 60 * 60)),
received_date_time: 0
};
user["home"]["gift_list"].push(to_push).unwrap();
}

View file

@ -353,7 +353,7 @@ pub fn migration_verify(req: HttpRequest, body: String) -> HttpResponse {
migration_token: user["login_token"].clone(), migration_token: user["login_token"].clone(),
balance_charge_gem: data_user["gem"]["charge"].to_string(), balance_charge_gem: data_user["gem"]["charge"].to_string(),
balance_free_gem: data_user["gem"]["free"].to_string(), balance_free_gem: data_user["gem"]["free"].to_string(),
balance_total_gem: (data_user["gem"]["charge"].as_i32().unwrap() + data_user["gem"]["free"].as_i32().unwrap()).to_string() balance_total_gem: data_user["gem"]["total"].to_string()
}; };
} }
@ -371,12 +371,12 @@ pub fn migration(req: HttpRequest, body: String) -> HttpResponse {
let body = json::parse(&body).unwrap(); let body = json::parse(&body).unwrap();
let user = userdata::get_acc(&body["src_uuid"].to_string()); let user = userdata::get_acc(&body["src_uuid"].to_string());
update_cert(&user["user"]["id"].to_string(), &body["token"].to_string());
//clear old token //clear old token
if !body["dst_uuid"].is_null() { if !body["dst_uuid"].is_null() {
let user2 = userdata::get_acc(&body["dst_uuid"].to_string()); let user2 = userdata::get_acc(&body["dst_uuid"].to_string());
update_cert(&user2["user"]["id"].to_string(), "none"); update_cert(&user2["user"]["id"].to_string(), "none");
} }
update_cert(&user["user"]["id"].to_string(), &body["token"].to_string());
let resp = object!{ let resp = object!{
result: "OK" result: "OK"
@ -411,7 +411,7 @@ pub fn balance(req: HttpRequest) -> HttpResponse {
entry: { entry: {
balance_charge_gem: user["gem"]["charge"].to_string(), balance_charge_gem: user["gem"]["charge"].to_string(),
balance_free_gem: user["gem"]["free"].to_string(), balance_free_gem: user["gem"]["free"].to_string(),
balance_total_gem: (user["gem"]["charge"].as_i32().unwrap() + user["gem"]["free"].as_i32().unwrap()).to_string() balance_total_gem: user["gem"]["total"].to_string()
} }
}; };

View file

@ -1,9 +1,10 @@
use json; use json;
use json::object; use json::{object, array, JsonValue};
use crate::router::global; use crate::router::global;
//use crate::encryption; //use crate::encryption;
use actix_web::{HttpResponse, HttpRequest}; use actix_web::{HttpResponse, HttpRequest};
use crate::router::userdata; use crate::router::userdata;
use lazy_static::lazy_static;
//First time login handler //First time login handler
pub fn dummy(req: HttpRequest, body: String) -> HttpResponse { pub fn dummy(req: HttpRequest, body: String) -> HttpResponse {
@ -21,17 +22,98 @@ pub fn dummy(req: HttpRequest, body: String) -> HttpResponse {
global::send(resp) global::send(resp)
} }
lazy_static! {
static ref LOTTERY_INFO: JsonValue = {
let mut info = object!{};
let items = json::parse(include_str!("json/login_bonus.json")).unwrap();
for (_i, data) in items.members().enumerate() {
if info[data["masterReleaseLabelId"].to_string()].is_null() {
info[data["masterReleaseLabelId"].to_string()] = object!{
info: data.clone(),
days: []
};
}
}
let days = json::parse(include_str!("json/login_bonus_reward.json")).unwrap();
for (_i, data) in days.members().enumerate() {
if info[data["masterReleaseLabelId"].to_string()].is_null() {
continue;
}
info[data["masterReleaseLabelId"].to_string()]["days"].push(data.clone()).unwrap();
}
let mut real_info = object!{};
for (_i, data) in info.entries().enumerate() {
real_info[data.1["info"]["id"].to_string()] = data.1.clone();
}
real_info
};
}
fn get_login_bonus_info(id: i64) -> JsonValue {
LOTTERY_INFO[id.to_string()].clone()
}
pub fn bonus(req: HttpRequest, body: String) -> HttpResponse { pub fn bonus(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 key = global::get_login(req.headers(), &body); let key = global::get_login(req.headers(), &body);
let user = userdata::get_acc(&key); let user = userdata::get_acc(&key);
let mut user_home = userdata::get_acc_home(&key);
let last_reset = global::timestamp_since_midnight();
let mut bonuses = userdata::get_acc_loginbonus(&key);
if bonuses["bonus_list"].is_empty() {
bonuses["bonus_list"].push(object!{
master_login_bonus_id: 1,
day_counts: [],
event_bonus_list: []
}).unwrap();
bonuses["bonus_list"].push(object!{
master_login_bonus_id: 2,
day_counts: [],
event_bonus_list: []
}).unwrap();
bonuses["bonus_list"].push(object!{
master_login_bonus_id: 3,
day_counts: [],
event_bonus_list: []
}).unwrap();
}
let to_send;
if bonuses["last_rewarded"].as_u64().unwrap() < last_reset {
let mut to_rm = array![];
for (i, data) in bonuses["bonus_list"].members_mut().enumerate() {
let info = get_login_bonus_info(data["master_login_bonus_id"].as_i64().unwrap());
let current = data["day_counts"].len();
if current >= info["days"].len() && info["info"]["loop"].as_i32().unwrap_or(0) == 1 {
data["day_counts"] = array![];
} else if current >= info["days"].len() {
to_rm.push(i).unwrap();
continue;
}
global::gift_item(&info["days"][current + 1], &mut user_home);
data["day_counts"].push(current + 1).unwrap();
}
for (_i, data) in to_rm.members().enumerate() {
bonuses["bonus_list"].array_remove(data.as_usize().unwrap());//IPMGQAYWYAW6AYA7
}
bonuses["last_rewarded"] = last_reset.into();
userdata::save_acc_loginbonus(&key, bonuses.clone());
to_send = bonuses["bonus_list"].clone();
} else {
to_send = array![];
}
println!("{}", json::stringify(to_send.clone()));
userdata::save_acc_home(&key, user_home);
let resp = object!{ let resp = object!{
"code": 0, "code": 0,
"server_time": global::timestamp(), "server_time": global::timestamp(),
"data": { "data": {
"login_bonus_list": [], "login_bonus_list": to_send,
"start_time": global::timestamp(), "start_time": bonuses["start_time"].clone(),
"clear_mission_ids": user["clear_mission_ids"].clone() "clear_mission_ids": user["clear_mission_ids"].clone()
} }
}; };

View file

@ -45,6 +45,89 @@ pub fn user(req: HttpRequest) -> HttpResponse {
global::send(resp) global::send(resp)
} }
pub fn gift(req: HttpRequest, body: String) -> HttpResponse {
let key = global::get_login(req.headers(), &body);
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let mut user = userdata::get_acc_home(&key);
let mut userr = userdata::get_acc(&key);
let mut rewards = array![];
let mut failed = array![];
let mut to_remove = array![];
for (_i, gift_id) in body["gift_ids"].members().enumerate() {
for (j, data) in user["home"]["gift_list"].members_mut().enumerate() {
if data["id"].to_string() != gift_id.to_string() {
continue;
}
if data["reward_type"].to_string() == "1" {
//gems
userr["gem"]["free"] = (userr["gem"]["free"].as_i64().unwrap() + data["amount"].as_i64().unwrap()).into();
//} else if data["reward_type"].to_string() == "3" {
//not working
/*
//goes into user item_list
let mut contains = false;
for (_k, dataa) in userr["item_list"].members_mut().enumerate() {
if dataa["id"].to_string() != data["id"].to_string() {
continue;
}
contains = true;
dataa["amount"] = (dataa["amount"].as_i64().unwrap() + data["amount"].as_i64().unwrap()).into();
break;
}
if !contains {
let to_push = object!{
"id": data["id"].clone(),
"master_item_id": data["id"].clone(),//idk if this is correct
"amount": data["amount"].clone(),
"expire_date_time": null
};
userr["item_list"].push(to_push).unwrap();
}*/
} else {//idk
println!("Redeeming reward not implimented for reward id {}", data["id"].to_string());
failed.push(gift_id.clone()).unwrap();
continue;
}
let to_push = object!{
give_type: data["give_type"].clone(),
type: data["reward_type"].clone(),
value: data["value"].clone(),
level: data["level"].clone(),
amount: data["amount"].clone()
};
rewards.push(to_push).unwrap();
to_remove.push(j).unwrap();
break;
}
}
for (_i, index) in to_remove.members().enumerate() {
user["home"]["gift_list"].array_remove(index.as_usize().unwrap());
}
userdata::save_acc_home(&key, user.clone());
userdata::save_acc(&key, userr.clone());
let userr = userdata::get_acc(&key);
let resp = object!{
"code": 0,
"server_time": global::timestamp(),
"data": {
"failed_gift_ids": failed,
"updated_value_list": {
"gem": userr["gem"].clone(),
"item_list": userr["item_list"].clone()
},
"clear_mission_ids": user["clear_mission_ids"].clone(),
"reward_list": rewards
}
};
global::send(resp)
}
pub fn user_post(req: HttpRequest, body: String) -> HttpResponse { pub fn user_post(req: HttpRequest, body: String) -> HttpResponse {
let key = global::get_login(req.headers(), &body); let key = global::get_login(req.headers(), &body);
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap(); let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();

View file

@ -150,13 +150,15 @@ fn create_acc(uid: i64, login: &str) {
create_store(&format!("SELECT userhome FROM _{}_", key), &format!("CREATE TABLE _{}_ ( create_store(&format!("SELECT userhome FROM _{}_", key), &format!("CREATE TABLE _{}_ (
userdata TEXT NOT NULL, userdata TEXT NOT NULL,
userhome TEXT NOT NULL, userhome TEXT NOT NULL,
missions TEXT NOT NULL missions TEXT NOT NULL,
loginbonus TEXT NOT NULL
)", key), )", key),
&format!("INSERT INTO _{}_ (userdata, userhome, missions) VALUES (?1, ?2, ?3)", key), &format!("INSERT INTO _{}_ (userdata, userhome, missions, loginbonus) VALUES (?1, ?2, ?3, ?4)", key),
params!( params!(
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())
) )
); );
@ -206,6 +208,8 @@ fn get_data(auth_key: &str, row: &str) -> JsonValue {
pub fn get_acc(auth_key: &str) -> JsonValue { pub fn get_acc(auth_key: &str) -> JsonValue {
let mut user = get_data(auth_key, "userdata"); let mut user = get_data(auth_key, "userdata");
user["gem"]["total"] = (user["gem"]["charge"].as_i64().unwrap() + user["gem"]["free"].as_i64().unwrap()).into();
let max = get_user_rank_data(user["user"]["exp"].as_i64().unwrap())["maxLp"].as_u64().unwrap(); let max = get_user_rank_data(user["user"]["exp"].as_i64().unwrap())["maxLp"].as_u64().unwrap();
let speed = 300; //5 mins let speed = 300; //5 mins
let since_last = global::timestamp() - user["stamina"]["last_updated_time"].as_u64().unwrap(); let since_last = global::timestamp() - user["stamina"]["last_updated_time"].as_u64().unwrap();
@ -228,6 +232,9 @@ pub fn get_acc_home(auth_key: &str) -> JsonValue {
pub fn get_acc_missions(auth_key: &str) -> JsonValue { pub fn get_acc_missions(auth_key: &str) -> JsonValue {
get_data(auth_key, "missions") get_data(auth_key, "missions")
} }
pub fn get_acc_loginbonus(auth_key: &str) -> JsonValue {
get_data(auth_key, "loginbonus")
}
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);
@ -244,6 +251,9 @@ pub fn save_acc_home(auth_key: &str, data: JsonValue) {
pub fn save_acc_missions(auth_key: &str, data: JsonValue) { pub fn save_acc_missions(auth_key: &str, data: JsonValue) {
save_data(auth_key, "missions", data); save_data(auth_key, "missions", data);
} }
pub fn save_acc_loginbonus(auth_key: &str, data: JsonValue) {
save_data(auth_key, "loginbonus", 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();