Cleanup gifts

This commit is contained in:
Ethan O'Brien
2026-07-04 17:33:35 -05:00
parent 41b6e8f3c2
commit 47fa13259f
7 changed files with 217 additions and 58 deletions

View File

@@ -185,10 +185,35 @@ pub fn timestamp_since_midnight() -> u64 {
let midnight = unix_timestamp.as_secs() % (24 * 60 * 60); let midnight = unix_timestamp.as_secs() % (24 * 60 * 60);
unix_timestamp.as_secs() - midnight unix_timestamp.as_secs() - midnight
} }
pub fn get_uid(headers: &HeaderMap) -> i64 {
let blank_header = HeaderValue::from_static("");
headers.get("aoharu-user-id").unwrap_or(&blank_header).to_str().unwrap_or("").parse::<i64>().unwrap_or(0)
}
fn civil_from_days(z: i64) -> (i64, i64, i64) {
let z = z + 719468;
let era = if z >= 0 { z } else { z - 146096 } / 146097;
let doe = z - era * 146097;
let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
let y = yoe + era * 400;
let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
let mp = (5 * doy + 2) / 153;
let d = doy - (153 * mp + 2) / 5 + 1;
let m = if mp < 10 { mp + 3 } else { mp - 9 };
(if m <= 2 { y + 1 } else { y }, m, d)
}
pub fn format_datetime(time: u64) -> String {
let days = (time / 86400) as i64;
let secs = time % 86400;
let (y, m, d) = civil_from_days(days);
format!("{:04}-{:02}-{:02} {:02}:{:02}:{:02}", y, m, d, secs / 3600, (secs % 3600) / 60, secs % 60)
}
fn init_time(current_time: u64, server_data: &mut JsonValue, token: &str, max_time: u64, max: bool) { fn init_time(current_time: u64, server_data: &mut JsonValue, token: &str, max_time: u64, max: bool) {
let mut edited = false; let mut edited = false;
let default_time = 1709272800; let default_time = 1709272800;

View File

@@ -95,7 +95,7 @@ async fn home(req: HttpRequest) -> impl Responder {
check_gifts(&mut user); check_gifts(&mut user);
let mut user_missions = userdata::get_acc_missions(&key); let mut user_missions = userdata::get_acc_missions(&key);
let clear = items::completed_daily_mission(1253003, &mut user_missions); let clear = items::completed_daily_mission(1253003, global::timestamp(), &mut user_missions);
userdata::save_acc_home(&key, user.clone()); userdata::save_acc_home(&key, user.clone());
user["clear_mission_ids"] = clear; user["clear_mission_ids"] = clear;
if !user["clear_mission_ids"].is_empty() { if !user["clear_mission_ids"].is_empty() {

View File

@@ -268,7 +268,7 @@ pub fn gift_item_basic(id: i32, value: i64, ty_pe: i32, reason: &str, user: &mut
} }
pub fn lp_modification(user: &mut JsonValue, change_amount: u64, remove: bool) -> bool { pub fn lp_modification(user: &mut JsonValue, change_amount: u64, remove: bool) -> bool {
let now = global::set_time(global::timestamp(), user["user"]["id"].as_i64().unwrap_or(0), false); let now = global::timestamp();
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 orig_stamina = user["stamina"]["stamina"].as_u64().unwrap(); let orig_stamina = user["stamina"]["stamina"].as_u64().unwrap();
@@ -486,32 +486,67 @@ pub fn advance_mission(id: i64, count: i64, max: i64, missions: &mut JsonValue)
None None
} }
pub fn completed_daily_mission(id: i64, missions: &mut JsonValue) -> JsonValue { pub const DAILY_MISSION_IDS: [i64; 6] = [1224003, 1253003, 1273009, 1273010, 1273011, 1273012];
let all_daily_missions = array![1224003, 1253003, 1273009, 1273010, 1273011, 1273012];
pub fn get_expire(now: u64) -> u64 {
let jst = now + 9 * 60 * 60;
((jst / 86400 + 1) * 86400 - 9 * 60 * 60) - 1
}
pub fn refresh_dailies(missions: &mut JsonValue, now: u64) -> bool {
let target = get_expire(now);
let mut changed = false;
for id in DAILY_MISSION_IDS {
for mission in missions.members_mut() {
if mission["master_mission_id"].as_i64() != Some(id) {
continue;
}
let expire = mission["expire_date_time"].as_u64().unwrap_or(0);
if expire == 0 {
mission["expire_date_time"] = target.into();
changed = true;
} else if now > expire {
mission["status"] = (1).into();
mission["progress"] = (0).into();
mission["expire_date_time"] = target.into();
changed = true;
}
break;
}
}
changed
}
pub fn completed_daily_mission(id: i64, now: u64, missions: &mut JsonValue) -> JsonValue {
refresh_dailies(missions, now);
let mission = get_mission_status(id, missions); let mission = get_mission_status(id, missions);
if mission["expire_date_time"].as_u64().unwrap_or(0) >= global::timestamp() && mission["status"].as_i32().unwrap() > 1 { if mission.is_empty() || mission["status"].as_i32().unwrap_or(0) > 1 {
return array![]; return array![];
} }
let mut rv = array![]; let mut rv = array![];
if id == 1253003 { if id == 1253003 {
rv = advance_variable_mission(1153001, 1153019, 1, missions); rv = advance_variable_mission(1153001, 1153019, 1, missions);
} if update_mission_status(1653001, 0, true, false, 1, missions).is_some() {
let mut mission = get_mission_status(1224003, missions); rv.push(1653001).unwrap();
let next_reset = global::timestamp_since_midnight() + (24 * 60 * 60);
if mission["expire_date_time"].as_u64().unwrap_or(0) < global::timestamp() {
update_mission_status_multi(all_daily_missions, next_reset, false, false, 0, missions);
mission = get_mission_status(1224003, missions);
}
if mission["progress"].as_i32().unwrap_or(0) == 4 {
if update_mission_status(1224003, 0, true, false, 1, missions).is_some() {
rv.push(1224003).unwrap();
} }
} else if update_mission_status(1224003, 0, false, false, 1, missions).is_some() {
rv.push(1224003).unwrap();
} }
if update_mission_status(id, next_reset, true, false, 1, missions).is_some() { for mission in missions.members_mut() {
if mission["master_mission_id"].as_i64() != Some(1224003) {
continue;
}
let was_completed = mission["status"] == 2;
let progress = mission["progress"].as_i64().unwrap_or(0) + 1;
mission["progress"] = progress.into();
if progress >= 5 {
mission["status"] = (2).into();
if !was_completed {
rv.push(1224003).unwrap();
}
}
break;
}
if update_mission_status(id, get_expire(now), true, false, 1, missions).is_some() {
rv.push(id).unwrap(); rv.push(id).unwrap();
} }
rv rv

View File

@@ -638,7 +638,7 @@ pub fn live_end(req: &HttpRequest, body: &str, skipped: bool) -> JsonValue {
if body["master_live_id"].to_string().len() > 1 { if body["master_live_id"].to_string().len() > 1 {
let id = body["master_live_id"].to_string().split("").collect::<Vec<_>>()[2].parse::<i64>().unwrap_or(0); let id = body["master_live_id"].to_string().split("").collect::<Vec<_>>()[2].parse::<i64>().unwrap_or(0);
if (1..=4).contains(&id) { if (1..=4).contains(&id) {
let to_push = items::completed_daily_mission(1273009 + id - 1, &mut user_missions); let to_push = items::completed_daily_mission(1273009 + id - 1, global::timestamp(), &mut user_missions);
for data in to_push.members() { for data in to_push.members() {
cleared_missions.push(data.as_i32().unwrap()).unwrap(); cleared_missions.push(data.as_i32().unwrap()).unwrap();
} }

View File

@@ -66,7 +66,7 @@ async fn bonus(req: HttpRequest, body: String) -> impl Responder {
let mut cleared_missions = array![]; let mut cleared_missions = array![];
if !to_send.is_empty() { if !to_send.is_empty() {
cleared_missions = items::completed_daily_mission(1253003, &mut user_missions); cleared_missions = items::completed_daily_mission(1253003, global::timestamp(), &mut user_missions);
userdata::save_acc_missions(&key, user_missions); userdata::save_acc_missions(&key, user_missions);
} }

View File

@@ -1,4 +1,4 @@
use jzon::{array, object}; use jzon::{array, object, JsonValue};
use actix_web::{web, HttpRequest, Responder}; use actix_web::{web, HttpRequest, Responder};
use crate::router::{global, userdata, items, databases}; use crate::router::{global, userdata, items, databases};
@@ -13,9 +13,23 @@ pub fn routes(cfg: &mut web::ServiceConfig) {
); );
} }
const VARIABLE_MISSIONS: [[i64; 2]; 5] = [[1153001, 1153019], [1105001, 1105017], [1101001, 1101030], [1121001, 1121019], [1112001, 1112033]];
async fn mission(req: HttpRequest) -> impl Responder { async fn mission(req: HttpRequest) -> impl Responder {
let key = global::get_login(req.headers(), ""); let key = global::get_login(req.headers(), "");
let missions = userdata::get_acc_missions(&key); let user = userdata::get_acc(&key);
let step = user["tutorial_step"].as_i64().unwrap_or(0);
if (1..130).contains(&step) {
return global::api(&req, Some(object!{
"mission_list": array![]
}));
}
let mut missions = userdata::get_acc_missions(&key);
if items::refresh_dailies(&mut missions, global::timestamp()) {
userdata::save_acc_missions(&key, missions.clone());
}
global::api(&req, Some(object!{ global::api(&req, Some(object!{
"mission_list": missions "mission_list": missions
@@ -24,69 +38,154 @@ async fn mission(req: HttpRequest) -> impl Responder {
async fn clear(req: HttpRequest, body: String) -> impl Responder { async fn clear(req: HttpRequest, body: String) -> impl Responder {
let key = global::get_login(req.headers(), &body); let key = global::get_login(req.headers(), &body);
let mut missions = userdata::get_acc_missions(&key); let mut missions = userdata::get_acc_missions(&key);
let body = jzon::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap(); let body = jzon::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let mut cleared = array![];
for id in body["master_mission_ids"].members() { for id in body["master_mission_ids"].members() {
items::update_mission_status(id.as_i64().unwrap(), 0, true, true, 1, &mut missions); let mission = items::get_mission_status(id.as_i64().unwrap(), &missions);
if mission.is_empty() || mission["status"].as_i32().unwrap_or(0) >= 2 {
continue;
}
items::update_mission_status(id.as_i64().unwrap(), 0, true, false, 1, &mut missions);
cleared.push(id.clone()).unwrap();
} }
userdata::save_acc_missions(&key, missions); userdata::save_acc_missions(&key, missions);
global::api(&req, Some(object!{ global::api(&req, Some(object!{
"clear_mission_ids": body["master_mission_ids"].clone() "clear_mission_ids": cleared
})) }))
} }
async fn receive(req: HttpRequest, body: String) -> impl Responder { async fn receive(req: HttpRequest, body: String) -> impl Responder {
let key = global::get_login(req.headers(), &body); let key = global::get_login(req.headers(), &body);
let body = jzon::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap(); let body = jzon::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
let uid = global::get_uid(req.headers());
let now = global::timestamp();
let mut missions = userdata::get_acc_missions(&key); let mut missions = userdata::get_acc_missions(&key);
let mut user = userdata::get_acc(&key); let mut user = userdata::get_acc(&key);
let mut chats = userdata::get_acc_chats(&key); let mut chats = userdata::get_acc_chats(&key);
let mut rewards = array![]; let mut rewards = array![];
let mut mission_list = array![];
let mut touched_gem = false;
let mut touched_coin = false;
let mut touched_items = array![];
for mission in body["master_mission_ids"].members() { for mission in body["master_mission_ids"].members() {
let mission_info = databases::MISSION_LIST[mission.to_string()].clone(); let mid = mission.as_i64().unwrap();
let mut gift = databases::MISSION_REWARD[mission_info["masterMissionRewardId"].to_string()].clone(); let mission_info = databases::MISSION_LIST[mid.to_string()].clone();
gift["reward_type"] = gift["type"].clone(); let master = databases::MISSION_REWARD[mission_info["masterMissionRewardId"].to_string()].clone();
gift["amount"] = gift["amount"].as_i64().unwrap().into(); let reward_type = master["type"].as_i64().unwrap();
items::give_gift(&gift, &mut user, &mut missions, &mut array![], &mut chats);
rewards.push(gift).unwrap(); rewards.push(object!{
give_type: master["giveType"].clone(),
let variable_missions = array![[1153001, 1153019], [1105001, 1105017], [1101001, 1101030], [1121001, 1121019], [1112001, 1112033]]; type: master["type"].clone(),
value: master["value"].clone(),
level: master["level"].clone(),
amount: master["amount"].clone()
}).unwrap();
items::give_gift(&object!{
reward_type: reward_type,
value: master["value"].clone(),
amount: master["amount"].clone()
}, &mut user, &mut missions, &mut array![], &mut chats);
match reward_type {
1 => touched_gem = true,
4 => touched_coin = true,
_ => { touched_items.push(master["value"].clone()).unwrap(); }
}
let mut variable = false; let mut variable = false;
for id in variable_missions.members() { for range in VARIABLE_MISSIONS {
if mission.as_i64().unwrap() >= id[0].as_i64().unwrap() && mission.as_i64().unwrap() < id[1].as_i64().unwrap() { if mid >= range[0] && mid < range[1] {
items::change_mission_id(mission.as_i64().unwrap(), mission.as_i64().unwrap() + 1, &mut missions); items::change_mission_id(mid, mid + 1, &mut missions);
items::advance_variable_mission(id[0].as_i64().unwrap(), id[1].as_i64().unwrap(), 0, &mut missions); let next = databases::MISSION_LIST[(mid + 1).to_string()]["conditionNumber"].as_i64().unwrap_or(0);
for m in missions.members_mut() {
if m["master_mission_id"].as_i64() == Some(mid + 1) {
let progress = m["progress"].as_i64().unwrap_or(0);
m["status"] = if progress >= next { 2 } else { 1 }.into();
mission_list.push(m.clone()).unwrap();
break;
}
}
variable = true; variable = true;
break; break;
} }
} }
if mission.as_i64().unwrap() >= 1158001 && mission.as_i64().unwrap() <= 1158039 { if !variable && (1158001..=1158039).contains(&mid) {
items::change_mission_id(mission.as_i64().unwrap(), mission.as_i64().unwrap() + 39, &mut missions); items::change_mission_id(mid, mid + 39, &mut missions);
items::update_mission_status(mission.as_i64().unwrap() + 39, 0, false, false, 0, &mut missions); items::update_mission_status(mid + 39, 0, false, false, 0, &mut missions);
for m in missions.members_mut() {
if m["master_mission_id"].as_i64() == Some(mid + 39) {
mission_list.push(m.clone()).unwrap();
break;
}
}
variable = true; variable = true;
} }
if !variable { if !variable {
items::update_mission_status(mission.as_i64().unwrap(), 0, true, true, 0, &mut missions); for m in missions.members_mut() {
if m["master_mission_id"].as_i64() == Some(mid) {
m["status"] = (3).into();
break;
}
}
let m = items::get_mission_status(mid, &missions);
let expire = m["expire_date_time"].as_u64().unwrap_or(0);
mission_list.push(object!{
user_id: uid,
master_mission_id: mid,
status: 3,
progress: if expire != 0 { m["progress"].clone() } else { JsonValue::Null },
expire_date: if expire != 0 { global::format_datetime(expire).into() } else { JsonValue::Null },
received_date: global::format_datetime(now)
}).unwrap();
} }
} }
userdata::save_acc(&key, user.clone()); userdata::save_acc(&key, user.clone());
userdata::save_acc_chats(&key, chats); userdata::save_acc_chats(&key, chats);
userdata::save_acc_missions(&key, missions.clone()); userdata::save_acc_missions(&key, missions);
let mut updated_value_list = object!{};
if touched_gem {
updated_value_list["gem"] = user["gem"].clone();
}
if !touched_items.is_empty() {
let mut item_list = array![];
for id in touched_items.members() {
for item in user["item_list"].members() {
if item["master_item_id"] == *id {
item_list.push(item.clone()).unwrap();
break;
}
}
}
updated_value_list["item_list"] = item_list;
}
if touched_coin {
let mut point_list = array![];
for point in user["point_list"].members() {
if point["type"].as_i64() == Some(1) {
point_list.push(object!{
type: 1,
amount: point["amount"].clone()
}).unwrap();
break;
}
}
updated_value_list["point_list"] = point_list;
}
global::api(&req, Some(object!{ global::api(&req, Some(object!{
"reward_list": rewards, "reward_list": rewards,
"updated_value_list": { "gift_list": array![],
"gem": user["gem"].clone(), "updated_value_list": updated_value_list,
"item_list": user["item_list"].clone(), "mission_list": mission_list
"point_list": user["point_list"].clone()
},
"mission_list": missions
})) }))
} }

View File

@@ -16,7 +16,7 @@ async fn tutorial(req: HttpRequest, body: String) -> impl Responder {
if user["tutorial_step"].as_i32().unwrap() < 130 { if user["tutorial_step"].as_i32().unwrap() < 130 {
user["tutorial_step"] = body["step"].clone(); user["tutorial_step"] = body["step"].clone();
user["stamina"]["stamina"] = (100).into(); user["stamina"]["stamina"] = (100).into();
user["stamina"]["last_updated_time"] = global::set_time(global::timestamp(), user["user"]["id"].as_i64().unwrap(), false).into(); user["stamina"]["last_updated_time"] = global::timestamp().into();
userdata::save_acc(&key, user); userdata::save_acc(&key, user);
} }