Merge branch 'trunk' into feat/encryption

This commit is contained in:
beerpsi 2023-11-16 03:37:30 +07:00 committed by GitHub
commit 27d4438e88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 35 deletions

View File

@ -29,8 +29,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,
}
@ -39,6 +44,10 @@ fn default_true() -> bool {
true
}
fn default_false() -> bool {
false
}
fn default_timeout() -> u64 {
3000
}

0
src/crypto.rs Normal file
View File

View File

@ -129,7 +129,6 @@ pub fn read_hinternet_url(handle: HINTERNET) -> Result<String> {
Err(anyhow!("Could not get URL from HINTERNET handle: {ec}"))
}
/// Read all bytes of a slice into a buffer.
pub fn read_slice(buf: *const u8, len: usize) -> Result<Vec<u8>> {
let mut slice = unsafe { std::slice::from_raw_parts(buf, len) };
let mut ret = Vec::with_capacity(len);

View File

@ -20,7 +20,7 @@ use crate::{
},
types::{
game::UpsertUserAllRequest,
tachi::{ClassEmblem, Import, ImportClasses, ImportScore},
tachi::{ClassEmblem, Difficulty, Import, ImportClasses, ImportScore},
},
CONFIGURATION, TACHI_IMPORT_URL, TACHI_STATUS_URL, UPSERT_USER_ALL_API_ENCRYPTED,
};
@ -41,6 +41,16 @@ pub fn hook_init() -> Result<()> {
.as_u64()
.ok_or(anyhow::anyhow!("Couldn't parse user from Tachi response"))?;
let mut permissions = resp["body"]["permissions"]
.as_array()
.ok_or(anyhow!("Couldn't parse permissions from Tachi response"))?
.into_iter()
.filter_map(|v| v.as_str());
if permissions.all(|v| v != "submit_score") {
return Err(anyhow!("API key has insufficient permission. The permission submit_score must be set."));
}
info!("Logged in to Tachi with userID {user_id}");
let winhttpwritedata = unsafe {
@ -50,12 +60,13 @@ pub fn hook_init() -> Result<()> {
};
unsafe {
DetourWriteData.initialize(winhttpwritedata, winhttpwritedata_hook)?;
DetourWriteData.enable()?;
DetourWriteData
.initialize(winhttpwritedata, winhttpwritedata_hook)?
.enable()?;
};
info!("Hook successfully initialized");
Ok(())
}
@ -191,11 +202,13 @@ fn winhttpwritedata_hook(
.user_playlog_list
.into_iter()
.filter_map(|playlog| {
if let Ok(score) = ImportScore::try_from(playlog) {
if score.difficulty.as_str() == "WORLD'S END" {
return None;
}
Some(score)
let result =
ImportScore::try_from_playlog(playlog, CONFIGURATION.general.fail_over_lamp);
if result
.as_ref()
.is_ok_and(|v| v.difficulty != Difficulty::WorldsEnd)
{
result.ok()
} else {
None
}

View File

@ -1,4 +1,4 @@
use anyhow::anyhow;
use anyhow::Result;
use chrono::{FixedOffset, NaiveDateTime, TimeZone};
use num_enum::TryFromPrimitive;
use serde::{Deserialize, Serialize};
@ -68,7 +68,7 @@ pub struct ImportScore {
pub lamp: TachiLamp,
pub match_type: String,
pub identifier: String,
pub difficulty: String,
pub difficulty: Difficulty,
pub time_achieved: u128,
pub judgements: Judgements,
pub optional: OptionalMetrics,
@ -93,6 +93,28 @@ pub enum TachiLamp {
AllJusticeCritical = 4,
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, TryFromPrimitive)]
#[repr(u32)]
pub enum Difficulty {
#[serde(rename = "BASIC")]
Basic = 0,
#[serde(rename = "ADVANCED")]
Advanced = 1,
#[serde(rename = "EXPERT")]
Expert = 2,
#[serde(rename = "MASTER")]
Master = 3,
#[serde(rename = "ULTIMA")]
Ultima = 4,
#[serde(rename = "WORLD'S END")]
WorldsEnd = 5,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Judgements {
pub jcrit: u32,
@ -107,11 +129,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 {
@ -133,23 +155,11 @@ impl TryFrom<UserPlaylog> for ImportScore {
};
let rom_major_version = p.rom_version.split('.').next().unwrap_or("2");
let difficulty = match p.level {
0 => "BASIC",
1 => "ADVANCED",
2 => "EXPERT",
3 => "MASTER",
4 => if rom_major_version == "2" {
"ULTIMA"
} else {
"WORLD'S END"
},
5 => if rom_major_version == "2" {
"WORLD'S END"
} else {
return Err(anyhow!("difficulty index '5' should not be possible on rom_version {rom_major_version}."));
},
_ => return Err(anyhow!("unknown difficulty index {level} on major version {rom_major_version}", level=p.level)),
}.to_string();
let difficulty = if rom_major_version == "1" && p.level == 4 {
Difficulty::WorldsEnd
} else {
Difficulty::try_from(p.level)?
};
let datetime = NaiveDateTime::parse_from_str(&p.user_play_date, "%Y-%m-%d %H:%M:%S")?;
let jst_offset =