mirror of
https://github.com/adamaq01/mikado.git
synced 2025-02-17 18:39:17 +01:00
fix: read card id based on cardmng request instead of refid which is serverside implementation dependant
This commit is contained in:
parent
6ca06aaa82
commit
832fc3e344
@ -5,11 +5,23 @@ use anyhow::Result;
|
|||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
pub fn process_save(save: GameSave) -> Result<()> {
|
pub fn process_save(save: GameSave) -> Result<()> {
|
||||||
let card = save.ref_id;
|
if save.ref_id.is_none() {
|
||||||
if !CONFIGURATION.cards.whitelist.is_empty() && !CONFIGURATION.cards.whitelist.contains(&card) {
|
info!("Guest play, skipping class update");
|
||||||
info!("Card {} is not whitelisted, skipping class update", card);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
let card = if let Some(card) = helpers::get_current_card_id() {
|
||||||
|
if !CONFIGURATION.cards.whitelist.is_empty()
|
||||||
|
&& !CONFIGURATION.cards.whitelist.contains(&card)
|
||||||
|
{
|
||||||
|
info!("Card {} is not whitelisted, skipping class update", card);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
card
|
||||||
|
} else {
|
||||||
|
info!("Card ID is not set, skipping class update");
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
let import = Import {
|
let import = Import {
|
||||||
meta: Default::default(),
|
meta: Default::default(),
|
||||||
|
@ -6,11 +6,26 @@ use either::Either;
|
|||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
pub fn process_scores(scores: GameScores) -> Result<()> {
|
pub fn process_scores(scores: GameScores) -> Result<()> {
|
||||||
let card = scores.ref_id;
|
if scores.ref_id.is_none() {
|
||||||
if !CONFIGURATION.cards.whitelist.is_empty() && !CONFIGURATION.cards.whitelist.contains(&card) {
|
info!("Guest play, skipping score(s) submission");
|
||||||
info!("Card {} is not whitelisted, skipping score(s)", card);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
let card = if let Some(card) = helpers::get_current_card_id() {
|
||||||
|
if !CONFIGURATION.cards.whitelist.is_empty()
|
||||||
|
&& !CONFIGURATION.cards.whitelist.contains(&card)
|
||||||
|
{
|
||||||
|
info!(
|
||||||
|
"Card {} is not whitelisted, skipping score(s) submission",
|
||||||
|
card
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
card
|
||||||
|
} else {
|
||||||
|
info!("Card ID is not set, skipping score(s) submission");
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
let tracks = match scores.tracks {
|
let tracks = match scores.tracks {
|
||||||
Either::Left(track) => vec![track],
|
Either::Left(track) => vec![track],
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
use crate::mikado::CURRENT_CARD_ID;
|
||||||
use crate::sys::{property_node_refer, NodeType};
|
use crate::sys::{property_node_refer, NodeType};
|
||||||
use crate::CONFIGURATION;
|
use crate::CONFIGURATION;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use log::debug;
|
use log::{debug, error};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
@ -63,6 +64,15 @@ where
|
|||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_current_card_id() -> Option<String> {
|
||||||
|
let guard = CURRENT_CARD_ID.read().unwrap_or_else(|err| {
|
||||||
|
error!("Current card ID RwLock is poisoned: {:#}", err);
|
||||||
|
err.into_inner()
|
||||||
|
});
|
||||||
|
|
||||||
|
guard.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_node_str(node: *const (), path: *const u8, length: usize) -> Option<String> {
|
pub fn read_node_str(node: *const (), path: *const u8, length: usize) -> Option<String> {
|
||||||
let mut buffer = [0u8; 32];
|
let mut buffer = [0u8; 32];
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use bytes::Bytes;
|
||||||
|
use kbinxml::{CompressionType, Node, Options, Value};
|
||||||
|
use log::{debug, error, info, warn};
|
||||||
|
|
||||||
use crate::handlers::save::process_save;
|
use crate::handlers::save::process_save;
|
||||||
use crate::handlers::scores::process_scores;
|
use crate::handlers::scores::process_scores;
|
||||||
use crate::sys::{
|
use crate::sys::{
|
||||||
@ -6,13 +14,9 @@ use crate::sys::{
|
|||||||
};
|
};
|
||||||
use crate::types::game::Property;
|
use crate::types::game::Property;
|
||||||
use crate::{helpers, CONFIGURATION, TACHI_STATUS_URL};
|
use crate::{helpers, CONFIGURATION, TACHI_STATUS_URL};
|
||||||
use anyhow::Result;
|
|
||||||
use bytes::Bytes;
|
|
||||||
use kbinxml::{CompressionType, Node, Options, Value};
|
|
||||||
use log::{debug, error, info, warn};
|
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
|
||||||
|
|
||||||
static USER: AtomicU64 = AtomicU64::new(0);
|
pub static USER: AtomicU64 = AtomicU64::new(0);
|
||||||
|
pub static CURRENT_CARD_ID: RwLock<Option<String>> = RwLock::new(None);
|
||||||
|
|
||||||
pub fn hook_init(ea3_node: *const ()) -> Result<()> {
|
pub fn hook_init(ea3_node: *const ()) -> Result<()> {
|
||||||
if !CONFIGURATION.general.enable {
|
if !CONFIGURATION.general.enable {
|
||||||
@ -217,34 +221,39 @@ pub unsafe fn property_destroy_hook(property: *mut ()) -> i32 {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let game_node = property_search(property, std::ptr::null(), b"/call/game\0".as_ptr());
|
let node = property_search(property, std::ptr::null(), b"/call/game\0".as_ptr());
|
||||||
if game_node.is_null() {
|
let node = if node.is_null() {
|
||||||
|
property_search(property, std::ptr::null(), b"/call/cardmng\0".as_ptr())
|
||||||
|
} else {
|
||||||
|
node
|
||||||
|
};
|
||||||
|
if node.is_null() {
|
||||||
property_clear_error(property);
|
property_clear_error(property);
|
||||||
return call_original!(property);
|
return call_original!(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut buffer = [0u8; 256];
|
let mut buffer = [0u8; 256];
|
||||||
let result = property_node_name(game_node, buffer.as_mut_ptr(), buffer.len() as u32);
|
let result = property_node_name(node, buffer.as_mut_ptr(), buffer.len() as u32);
|
||||||
if result < 0 {
|
if result < 0 {
|
||||||
return call_original!(property);
|
return call_original!(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = {
|
let name = {
|
||||||
let result = std::str::from_utf8(&buffer[0..4]);
|
let result = std::str::from_utf8(&buffer[0..32]);
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
error!("Could not convert buffer to string: {:#}", err);
|
error!("Could not convert buffer to string: {:#}", err);
|
||||||
return call_original!(property);
|
return call_original!(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.unwrap()
|
result.unwrap().replace('\0', "")
|
||||||
};
|
};
|
||||||
if name != "game" {
|
if name != "game" && name != "cardmng" {
|
||||||
return call_original!(property);
|
return call_original!(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = property_node_refer(
|
let result = property_node_refer(
|
||||||
property,
|
property,
|
||||||
game_node,
|
node,
|
||||||
b"method@\0".as_ptr(),
|
b"method@\0".as_ptr(),
|
||||||
NodeType::NodeAttr,
|
NodeType::NodeAttr,
|
||||||
buffer.as_mut_ptr() as *mut (),
|
buffer.as_mut_ptr() as *mut (),
|
||||||
@ -263,7 +272,44 @@ pub unsafe fn property_destroy_hook(property: *mut ()) -> i32 {
|
|||||||
|
|
||||||
result.unwrap().replace('\0', "")
|
result.unwrap().replace('\0', "")
|
||||||
};
|
};
|
||||||
debug!("Intercepted Game Method: {}", method);
|
debug!("Intercepted '{}' method: {}", name, method);
|
||||||
|
|
||||||
|
if name == "cardmng" {
|
||||||
|
if method != "inquire" {
|
||||||
|
return call_original!(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = property_node_refer(
|
||||||
|
property,
|
||||||
|
node,
|
||||||
|
b"cardid@\0".as_ptr(),
|
||||||
|
NodeType::NodeAttr,
|
||||||
|
buffer.as_mut_ptr() as *mut (),
|
||||||
|
256,
|
||||||
|
);
|
||||||
|
if result < 0 {
|
||||||
|
return call_original!(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cardid = {
|
||||||
|
let result = std::str::from_utf8(&buffer[..32]);
|
||||||
|
if let Err(err) = result {
|
||||||
|
error!("Could not convert buffer to string: {:#}", err);
|
||||||
|
return call_original!(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.unwrap().replace('\0', "")
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(mut guard) = CURRENT_CARD_ID.write() {
|
||||||
|
debug!("Set current card id to {}", cardid);
|
||||||
|
*guard = Some(cardid);
|
||||||
|
} else {
|
||||||
|
warn!("Could not acquire write lock on current card id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_original!(property);
|
||||||
|
}
|
||||||
|
|
||||||
if CONFIGURATION.general.inject_cloud_pbs {
|
if CONFIGURATION.general.inject_cloud_pbs {
|
||||||
if method == "sv6_load_m" {
|
if method == "sv6_load_m" {
|
||||||
|
@ -14,8 +14,8 @@ pub struct CallStruct {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct GameScores {
|
pub struct GameScores {
|
||||||
#[serde(rename = "refid")]
|
#[serde(rename = "refid", default)]
|
||||||
pub ref_id: String,
|
pub ref_id: Option<String>,
|
||||||
#[serde(with = "either::serde_untagged", rename = "track")]
|
#[serde(with = "either::serde_untagged", rename = "track")]
|
||||||
pub tracks: Either<Track, Vec<Track>>,
|
pub tracks: Either<Track, Vec<Track>>,
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ pub struct Track {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct GameSave {
|
pub struct GameSave {
|
||||||
#[serde(rename = "refid")]
|
#[serde(rename = "refid", default)]
|
||||||
pub ref_id: String,
|
pub ref_id: Option<String>,
|
||||||
pub skill_level: u32,
|
pub skill_level: u32,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user