feat: add feature to allow FAILED to take precedence over lamps

I don't know why you would want this, but an ALL JUSTICE showing as FAILED is funny.
This commit is contained in:
beerpiss 2023-11-15 18:39:13 +07:00
parent 70f85e7418
commit 6c3fbe3378
4 changed files with 46 additions and 27 deletions

View File

@ -3,6 +3,8 @@
enable = true
# Whether the hook should export your class medals and emblems or not.
export_class = true
# Whether FAILED should override FULL COMBO and ALL JUSTICE.
fail_over_lamp = false
# Timeout for web requests, in milliseconds
timeout = 3000

View File

@ -28,8 +28,13 @@ impl Configuration {
pub struct GeneralConfiguration {
#[serde(default = "default_true")]
pub enable: bool,
#[serde(default)]
#[serde(default = "default_true")]
pub export_class: bool,
#[serde(default = "default_false")]
pub fail_over_lamp: bool,
#[serde(default = "default_timeout")]
pub timeout: u64,
}
@ -38,6 +43,10 @@ fn default_true() -> bool {
true
}
fn default_false() -> bool {
false
}
fn default_timeout() -> u64 {
3000
}

View File

@ -14,7 +14,7 @@ use winapi::{
};
use crate::{
helpers::{call_tachi, read_hinternet_url, read_potentially_deflated_buffer, self},
helpers::{call_tachi, read_hinternet_url, read_potentially_deflated_buffer, request_tachi},
types::{
game::UpsertUserAllRequest,
tachi::{ClassEmblem, Import, ImportClasses, ImportScore},
@ -33,7 +33,7 @@ pub fn hook_init() -> Result<()> {
return Ok(());
}
let resp: serde_json::Value = helpers::request_tachi("GET", TACHI_STATUS_URL.as_str(), None::<()>)?;
let resp: serde_json::Value = request_tachi("GET", TACHI_STATUS_URL.as_str(), None::<()>)?;
let user_id = resp["body"]["whoami"]
.as_u64()
.ok_or(anyhow::anyhow!("Couldn't parse user from Tachi response"))?;
@ -47,14 +47,13 @@ pub fn hook_init() -> Result<()> {
};
unsafe {
DetourWriteData.initialize(winhttpwritedata, move |a, b, c, d| {
winhttpwritedata_hook(a, b, c, d)
})?;
DetourWriteData.enable()?;
DetourWriteData
.initialize(winhttpwritedata, winhttpwritedata_hook)?
.enable()?;
};
info!("Hook successfully initialized");
Ok(())
}
@ -68,7 +67,7 @@ pub fn hook_release() -> Result<()> {
Ok(())
}
unsafe fn winhttpwritedata_hook(
fn winhttpwritedata_hook(
h_request: HINTERNET,
lp_buffer: LPCVOID,
dw_number_of_bytes_to_write: DWORD,
@ -76,12 +75,14 @@ unsafe fn winhttpwritedata_hook(
) -> BOOL {
debug!("hit winhttpwritedata");
let orig = || DetourWriteData.call(
h_request,
lp_buffer,
dw_number_of_bytes_to_write,
lpdw_number_of_bytes_written,
);
let orig = || unsafe {
DetourWriteData.call(
h_request,
lp_buffer,
dw_number_of_bytes_to_write,
lpdw_number_of_bytes_written,
)
};
let url = match read_hinternet_url(h_request) {
Ok(url) => url,
@ -92,10 +93,12 @@ unsafe fn winhttpwritedata_hook(
};
debug!("winhttpwritedata URL: {url}");
let request_body = match read_potentially_deflated_buffer(
lp_buffer as *const u8,
dw_number_of_bytes_to_write as usize,
) {
let request_body = match unsafe {
read_potentially_deflated_buffer(
lp_buffer as *const u8,
dw_number_of_bytes_to_write as usize,
)
} {
Ok(data) => data,
Err(err) => {
error!("There was an error reading the request body: {:#}", err);
@ -141,7 +144,9 @@ unsafe fn winhttpwritedata_hook(
.user_playlog_list
.into_iter()
.filter_map(|playlog| {
if let Ok(score) = ImportScore::try_from(playlog) {
if let Ok(score) =
ImportScore::try_from_playlog(playlog, CONFIGURATION.general.fail_over_lamp)
{
if score.difficulty.as_str() == "WORLD'S END" {
return None;
}
@ -157,7 +162,10 @@ unsafe fn winhttpwritedata_hook(
return orig();
}
if classes.clone().is_some_and(|v| v.dan.is_none() && v.emblem.is_none()) {
if classes
.clone()
.is_some_and(|v| v.dan.is_none() && v.emblem.is_none())
{
return orig();
}
}

View File

@ -1,4 +1,4 @@
use anyhow::anyhow;
use anyhow::{anyhow, Result};
use chrono::{FixedOffset, NaiveDateTime, TimeZone};
use num_enum::TryFromPrimitive;
use serde::{Deserialize, Serialize};
@ -107,11 +107,11 @@ pub struct OptionalMetrics {
pub max_combo: u32,
}
impl TryFrom<UserPlaylog> for ImportScore {
type Error = anyhow::Error;
fn try_from(p: UserPlaylog) -> Result<ImportScore, Self::Error> {
let lamp = if p.is_all_justice {
impl ImportScore {
pub fn try_from_playlog(p: UserPlaylog, fail_over_lamp: bool) -> Result<ImportScore> {
let lamp = if !p.is_clear && fail_over_lamp {
TachiLamp::Failed
} else if p.is_all_justice {
if p.judge_justice + p.judge_attack + p.judge_guilty == 0 {
TachiLamp::AllJusticeCritical
} else {