mirror of
https://github.com/beerpiss/saekawa.git
synced 2024-11-24 07:10:13 +01:00
Merge branch 'trunk' into feat/encryption
This commit is contained in:
commit
27d4438e88
@ -29,8 +29,13 @@ impl Configuration {
|
|||||||
pub struct GeneralConfiguration {
|
pub struct GeneralConfiguration {
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
pub enable: bool,
|
pub enable: bool,
|
||||||
#[serde(default)]
|
|
||||||
|
#[serde(default = "default_true")]
|
||||||
pub export_class: bool,
|
pub export_class: bool,
|
||||||
|
|
||||||
|
#[serde(default = "default_false")]
|
||||||
|
pub fail_over_lamp: bool,
|
||||||
|
|
||||||
#[serde(default = "default_timeout")]
|
#[serde(default = "default_timeout")]
|
||||||
pub timeout: u64,
|
pub timeout: u64,
|
||||||
}
|
}
|
||||||
@ -39,6 +44,10 @@ fn default_true() -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_false() -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn default_timeout() -> u64 {
|
fn default_timeout() -> u64 {
|
||||||
3000
|
3000
|
||||||
}
|
}
|
||||||
|
0
src/crypto.rs
Normal file
0
src/crypto.rs
Normal file
@ -129,7 +129,6 @@ pub fn read_hinternet_url(handle: HINTERNET) -> Result<String> {
|
|||||||
Err(anyhow!("Could not get URL from HINTERNET handle: {ec}"))
|
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>> {
|
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 slice = unsafe { std::slice::from_raw_parts(buf, len) };
|
||||||
let mut ret = Vec::with_capacity(len);
|
let mut ret = Vec::with_capacity(len);
|
||||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
types::{
|
types::{
|
||||||
game::UpsertUserAllRequest,
|
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,
|
CONFIGURATION, TACHI_IMPORT_URL, TACHI_STATUS_URL, UPSERT_USER_ALL_API_ENCRYPTED,
|
||||||
};
|
};
|
||||||
@ -41,6 +41,16 @@ pub fn hook_init() -> Result<()> {
|
|||||||
.as_u64()
|
.as_u64()
|
||||||
.ok_or(anyhow::anyhow!("Couldn't parse user from Tachi response"))?;
|
.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}");
|
info!("Logged in to Tachi with userID {user_id}");
|
||||||
|
|
||||||
let winhttpwritedata = unsafe {
|
let winhttpwritedata = unsafe {
|
||||||
@ -50,12 +60,13 @@ pub fn hook_init() -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
DetourWriteData.initialize(winhttpwritedata, winhttpwritedata_hook)?;
|
DetourWriteData
|
||||||
|
.initialize(winhttpwritedata, winhttpwritedata_hook)?
|
||||||
DetourWriteData.enable()?;
|
.enable()?;
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Hook successfully initialized");
|
info!("Hook successfully initialized");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,11 +202,13 @@ fn winhttpwritedata_hook(
|
|||||||
.user_playlog_list
|
.user_playlog_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|playlog| {
|
.filter_map(|playlog| {
|
||||||
if let Ok(score) = ImportScore::try_from(playlog) {
|
let result =
|
||||||
if score.difficulty.as_str() == "WORLD'S END" {
|
ImportScore::try_from_playlog(playlog, CONFIGURATION.general.fail_over_lamp);
|
||||||
return None;
|
if result
|
||||||
}
|
.as_ref()
|
||||||
Some(score)
|
.is_ok_and(|v| v.difficulty != Difficulty::WorldsEnd)
|
||||||
|
{
|
||||||
|
result.ok()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use anyhow::anyhow;
|
use anyhow::Result;
|
||||||
use chrono::{FixedOffset, NaiveDateTime, TimeZone};
|
use chrono::{FixedOffset, NaiveDateTime, TimeZone};
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -68,7 +68,7 @@ pub struct ImportScore {
|
|||||||
pub lamp: TachiLamp,
|
pub lamp: TachiLamp,
|
||||||
pub match_type: String,
|
pub match_type: String,
|
||||||
pub identifier: String,
|
pub identifier: String,
|
||||||
pub difficulty: String,
|
pub difficulty: Difficulty,
|
||||||
pub time_achieved: u128,
|
pub time_achieved: u128,
|
||||||
pub judgements: Judgements,
|
pub judgements: Judgements,
|
||||||
pub optional: OptionalMetrics,
|
pub optional: OptionalMetrics,
|
||||||
@ -93,6 +93,28 @@ pub enum TachiLamp {
|
|||||||
AllJusticeCritical = 4,
|
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)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct Judgements {
|
pub struct Judgements {
|
||||||
pub jcrit: u32,
|
pub jcrit: u32,
|
||||||
@ -107,11 +129,11 @@ pub struct OptionalMetrics {
|
|||||||
pub max_combo: u32,
|
pub max_combo: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<UserPlaylog> for ImportScore {
|
impl ImportScore {
|
||||||
type Error = anyhow::Error;
|
pub fn try_from_playlog(p: UserPlaylog, fail_over_lamp: bool) -> Result<ImportScore> {
|
||||||
|
let lamp = if !p.is_clear && fail_over_lamp {
|
||||||
fn try_from(p: UserPlaylog) -> Result<ImportScore, Self::Error> {
|
TachiLamp::Failed
|
||||||
let lamp = if p.is_all_justice {
|
} else if p.is_all_justice {
|
||||||
if p.judge_justice + p.judge_attack + p.judge_guilty == 0 {
|
if p.judge_justice + p.judge_attack + p.judge_guilty == 0 {
|
||||||
TachiLamp::AllJusticeCritical
|
TachiLamp::AllJusticeCritical
|
||||||
} else {
|
} else {
|
||||||
@ -133,23 +155,11 @@ impl TryFrom<UserPlaylog> for ImportScore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let rom_major_version = p.rom_version.split('.').next().unwrap_or("2");
|
let rom_major_version = p.rom_version.split('.').next().unwrap_or("2");
|
||||||
let difficulty = match p.level {
|
let difficulty = if rom_major_version == "1" && p.level == 4 {
|
||||||
0 => "BASIC",
|
Difficulty::WorldsEnd
|
||||||
1 => "ADVANCED",
|
} else {
|
||||||
2 => "EXPERT",
|
Difficulty::try_from(p.level)?
|
||||||
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 datetime = NaiveDateTime::parse_from_str(&p.user_play_date, "%Y-%m-%d %H:%M:%S")?;
|
let datetime = NaiveDateTime::parse_from_str(&p.user_play_date, "%Y-%m-%d %H:%M:%S")?;
|
||||||
let jst_offset =
|
let jst_offset =
|
||||||
|
Loading…
Reference in New Issue
Block a user