mirror of
https://github.com/project-slippi/slippi-rust-extensions.git
synced 2025-10-05 23:22:40 +02:00
refactor: update time and cpal && upgrade to 1.88 and edition 2024 (#21)
* chore: update time and cpal + cargo update * update to 1.88 and 2024 * use unsafe as needed * update cbindgen * ignore error in ReportSendErrorKind * explicit dead_code attributes and update doc string * jukebox: keep existing offset locator behavior while abiding by rust 2024 return-position impl rules * minor doc comment adjustment --------- Co-authored-by: Ryan McGrath <ryan@rymc.io> Co-authored-by: Daryl Pinto <daryl.j.pinto@gmail.com>
This commit is contained in:
1517
Cargo.lock
generated
1517
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
16
Cargo.toml
@@ -24,7 +24,7 @@ debug = true
|
||||
panic = "abort"
|
||||
|
||||
[workspace.dependencies]
|
||||
time = { version = "0.3.20", default-features = false, features = ["formatting", "parsing", "local-offset", "macros", "serde", "std"] }
|
||||
time = { version = "0.3.41", default-features = false, features = ["formatting", "parsing", "local-offset", "macros", "serde", "std"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = { version = "1" }
|
||||
serde_repr = { version = "0.1" }
|
||||
@@ -35,16 +35,4 @@ tracing = { version = "0.1", default-features = false, features = ["std"] }
|
||||
|
||||
ureq = { version = "2.9.1", features = ["json"] }
|
||||
|
||||
[patch.crates-io]
|
||||
# We need to patch this dependency to fix a bug in Windows where a crash can occur
|
||||
# due to a lurking `assert` in cpal's wasapi device handling. This can be removed once
|
||||
# the fix is merged upstream.
|
||||
#
|
||||
# See the following links for more info:
|
||||
#
|
||||
# - https://github.com/RustAudio/cpal/issues/796
|
||||
# - https://github.com/project-slippi/cpal/commit/b0058fc99e324e919cba099077f43db90ddada94
|
||||
#
|
||||
# We have also added some extra logging ourselves to try to track down the source of the issue.
|
||||
#
|
||||
cpal = { git = "https://github.com/project-slippi/cpal.git", ref="1ec6b46495d702b067e5574cbda0cae2fc9dbae3" }
|
||||
cpal = { version = "0.16.0" }
|
||||
|
@@ -6,7 +6,7 @@ authors = [
|
||||
"Slippi Team",
|
||||
"Ryan McGrath <ryan@rymc.io>"
|
||||
]
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
//! Typically you can just import the `Dolphin` struct and use that as a namespace for accessing
|
||||
//! all functionality at once.
|
||||
|
||||
use std::ffi::{c_char, CString};
|
||||
use std::ffi::{CString, c_char};
|
||||
|
||||
mod logger;
|
||||
pub use logger::Log;
|
||||
|
@@ -9,7 +9,7 @@ use time::OffsetDateTime;
|
||||
use tracing::{Level, Metadata};
|
||||
use tracing_subscriber::Layer;
|
||||
|
||||
use super::{ForeignLoggerFn, Log, LOG_CONTAINERS};
|
||||
use super::{ForeignLoggerFn, LOG_CONTAINERS, Log};
|
||||
|
||||
/// Corresponds to Dolphin's `LogTypes::LOG_LEVELS::LNOTICE` value.
|
||||
#[allow(dead_code)]
|
||||
|
@@ -7,14 +7,14 @@
|
||||
//!
|
||||
//! Ultimately this should mean no log fragmentation or confusion.
|
||||
|
||||
use std::ffi::{c_char, c_int, CStr};
|
||||
use std::ffi::{CStr, c_char, c_int};
|
||||
use std::sync::{Arc, Once, OnceLock, RwLock};
|
||||
|
||||
use tracing::Level;
|
||||
use tracing_subscriber::prelude::*;
|
||||
|
||||
mod layer;
|
||||
use layer::{convert_dolphin_log_level_to_tracing_level, DolphinLoggerLayer};
|
||||
use layer::{DolphinLoggerLayer, convert_dolphin_log_level_to_tracing_level};
|
||||
|
||||
/// A type that mirrors a function over on the C++ side; because the library exists as
|
||||
/// a dylib, it can't depend on any functions from the host application - but we _can_
|
||||
@@ -86,7 +86,9 @@ pub fn init(logger_fn: ForeignLoggerFn) {
|
||||
// know if something else, somehow, registered before us.
|
||||
LOGGER.call_once(|| {
|
||||
// We do this so that full backtrace's are emitted on any crashes.
|
||||
std::env::set_var("RUST_BACKTRACE", "full");
|
||||
unsafe {
|
||||
std::env::set_var("RUST_BACKTRACE", "full");
|
||||
}
|
||||
|
||||
tracing_subscriber::registry().with(DolphinLoggerLayer::new(logger_fn)).init();
|
||||
});
|
||||
|
@@ -6,7 +6,7 @@ authors = [
|
||||
"Slippi Team",
|
||||
"Ryan McGrath <ryan@rymc.io>"
|
||||
]
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
|
@@ -7,14 +7,14 @@ authors = [
|
||||
"Ryan McGrath <ryan@rymc.io>"
|
||||
]
|
||||
repository = ""
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.24.3"
|
||||
cbindgen = "0.29.0"
|
||||
|
||||
[features]
|
||||
default = ["ishiiruka"]
|
||||
|
@@ -377,5 +377,5 @@ char *slprs_user_direct_codes_get_code_at_index(uintptr_t exi_device_instance_pt
|
||||
void slprs_user_direct_codes_free_code(char *code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@@ -43,7 +43,7 @@ pub struct SlippiRustEXIConfig {
|
||||
/// down (at whatever point) via the corresponding `slprs_exi_device_destroy` function.
|
||||
///
|
||||
/// The returned pointer from this should *not* be used after calling `slprs_exi_device_destroy`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_create(config: SlippiRustEXIConfig) -> usize {
|
||||
dolphin_integrations::ffi::osd::set_global_hook(config.osd_add_msg_fn);
|
||||
|
||||
@@ -73,7 +73,7 @@ pub extern "C" fn slprs_exi_device_create(config: SlippiRustEXIConfig) -> usize
|
||||
|
||||
/// The C++ (Dolphin) side of things should call this to notify the Rust side that it
|
||||
/// can safely shut down and clean up.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_destroy(exi_device_instance_ptr: usize) {
|
||||
tracing::warn!(
|
||||
target: Log::SlippiOnline,
|
||||
@@ -94,7 +94,7 @@ pub extern "C" fn slprs_exi_device_destroy(exi_device_instance_ptr: usize) {
|
||||
/// the Dolphin side, corresponding to:
|
||||
///
|
||||
/// `virtual void DMAWrite(u32 _uAddr, u32 _uSize);`
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_dma_write(exi_device_instance_ptr: usize, address: *const u8, size: *const u8) {
|
||||
// Coerce the instance back from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `exi_device_instance_ptr` pointer is only owned
|
||||
@@ -111,7 +111,7 @@ pub extern "C" fn slprs_exi_device_dma_write(exi_device_instance_ptr: usize, add
|
||||
/// the Dolphin side, corresponding to:
|
||||
///
|
||||
/// `virtual void DMARead(u32 _uAddr, u32 _uSize);`
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_dma_read(exi_device_instance_ptr: usize, address: *const u8, size: *const u8) {
|
||||
// Coerce the instance from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `exi_device_instance_ptr` pointer is only owned
|
||||
@@ -129,7 +129,7 @@ pub extern "C" fn slprs_exi_device_dma_read(exi_device_instance_ptr: usize, addr
|
||||
/// will then add it to the processing pipeline.
|
||||
///
|
||||
/// The reporter will manage the actual... reporting.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_log_game_report(instance_ptr: usize, game_report_instance_ptr: usize) {
|
||||
// Coerce the instances from the pointers. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the pointers are only owned
|
||||
@@ -148,7 +148,7 @@ pub extern "C" fn slprs_exi_device_log_game_report(instance_ptr: usize, game_rep
|
||||
}
|
||||
|
||||
/// Calls through to `SlippiGameReporter::start_new_session`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_start_new_reporter_session(instance_ptr: usize) {
|
||||
// Coerce the instances from the pointers. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the pointers are only owned
|
||||
@@ -163,7 +163,7 @@ pub extern "C" fn slprs_exi_device_start_new_reporter_session(instance_ptr: usiz
|
||||
|
||||
/// Calls through to the `SlippiGameReporter` on the EXI device to report a
|
||||
/// match completion event.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_report_match_completion(instance_ptr: usize, match_id: *const c_char, end_mode: u8) {
|
||||
// Coerce the instances from the pointers. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the pointers are only owned
|
||||
@@ -181,7 +181,7 @@ pub extern "C" fn slprs_exi_device_report_match_completion(instance_ptr: usize,
|
||||
|
||||
/// Calls through to the `SlippiGameReporter` on the EXI device to report a
|
||||
/// match abandon event.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_report_match_abandonment(instance_ptr: usize, match_id: *const c_char) {
|
||||
// Coerce the instances from the pointers. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the pointers are only owned
|
||||
@@ -198,7 +198,7 @@ pub extern "C" fn slprs_exi_device_report_match_abandonment(instance_ptr: usize,
|
||||
}
|
||||
|
||||
/// Calls through to `SlippiGameReporter::push_replay_data`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_reporter_push_replay_data(instance_ptr: usize, data: *const u8, length: u32) {
|
||||
// Convert our pointer to a Rust slice so that the game reporter
|
||||
// doesn't need to deal with anything C-ish.
|
||||
@@ -218,7 +218,7 @@ pub extern "C" fn slprs_exi_device_reporter_push_replay_data(instance_ptr: usize
|
||||
/// Configures the Jukebox process. This needs to be called after the EXI device is created
|
||||
/// in order for certain pieces of Dolphin to be properly initalized; this may change down
|
||||
/// the road though and is not set in stone.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_exi_device_configure_jukebox(
|
||||
exi_device_instance_ptr: usize,
|
||||
is_enabled: bool,
|
||||
|
@@ -25,7 +25,7 @@ pub enum SlippiMatchmakingOnlinePlayMode {
|
||||
/// Creates a new Player Report and leaks it, returning the pointer.
|
||||
///
|
||||
/// This should be passed on to a GameReport for processing.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_player_report_create(
|
||||
uid: *const c_char,
|
||||
slot_type: u8,
|
||||
@@ -59,7 +59,7 @@ pub extern "C" fn slprs_player_report_create(
|
||||
///
|
||||
/// This is expected to ultimately be passed to the game reporter, which will handle
|
||||
/// destruction and cleanup.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_game_report_create(
|
||||
uid: *const c_char,
|
||||
play_key: *const c_char,
|
||||
@@ -109,7 +109,7 @@ pub extern "C" fn slprs_game_report_create(
|
||||
|
||||
/// Takes ownership of the `PlayerReport` at the specified pointer, adding it to the
|
||||
/// `GameReport` at the corresponding pointer.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_game_report_add_player_report(instance_ptr: usize, player_report_instance_ptr: usize) {
|
||||
// Coerce the instance from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `game_report_instance_ptr` is only owned
|
||||
|
@@ -2,7 +2,7 @@ use slippi_exi_device::SlippiEXIDevice;
|
||||
use slippi_jukebox::VolumeControl;
|
||||
|
||||
/// Calls through to `Jukebox::start_song`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_jukebox_start_song(exi_device_instance_ptr: usize, hps_offset: u64, hps_length: usize) {
|
||||
// Coerce the instance from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `exi_device_instance_ptr` is only owned
|
||||
@@ -18,7 +18,7 @@ pub extern "C" fn slprs_jukebox_start_song(exi_device_instance_ptr: usize, hps_o
|
||||
}
|
||||
|
||||
/// Calls through to `Jukebox::stop_music`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_jukebox_stop_music(exi_device_instance_ptr: usize) {
|
||||
// Coerce the instance from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `exi_device_instance_ptr` is only owned
|
||||
@@ -34,7 +34,7 @@ pub extern "C" fn slprs_jukebox_stop_music(exi_device_instance_ptr: usize) {
|
||||
}
|
||||
|
||||
/// Calls through to `Jukebox::set_volume` with the Melee volume control.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_jukebox_set_melee_music_volume(exi_device_instance_ptr: usize, volume: u8) {
|
||||
// Coerce the instance from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `exi_device_instance_ptr` is only owned
|
||||
@@ -50,7 +50,7 @@ pub extern "C" fn slprs_jukebox_set_melee_music_volume(exi_device_instance_ptr:
|
||||
}
|
||||
|
||||
/// Calls through to `Jukebox::set_volume` with the DolphinSystem volume control.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_jukebox_set_dolphin_system_volume(exi_device_instance_ptr: usize, volume: u8) {
|
||||
// Coerce the instance from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `exi_device_instance_ptr` is only owned
|
||||
@@ -66,7 +66,7 @@ pub extern "C" fn slprs_jukebox_set_dolphin_system_volume(exi_device_instance_pt
|
||||
}
|
||||
|
||||
/// Calls through to `Jukebox::set_volume` with the DolphinMusic volume control.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_jukebox_set_dolphin_music_volume(exi_device_instance_ptr: usize, volume: u8) {
|
||||
// Coerce the instance from the pointer. This is theoretically safe since we control
|
||||
// the C++ side and can guarantee that the `exi_device_instance_ptr` is only owned
|
||||
|
@@ -5,7 +5,7 @@
|
||||
//! This library auto-generates C headers on build, and Slippi Dolphin is pre-configured
|
||||
//! to locate these headers and link the entire dylib.
|
||||
|
||||
use std::ffi::{c_char, CStr};
|
||||
use std::ffi::{CStr, c_char};
|
||||
|
||||
use dolphin_integrations::Log;
|
||||
|
||||
|
@@ -11,7 +11,7 @@ use std::ffi::{c_char, c_int};
|
||||
/// ```
|
||||
/// void Log(level, log_type, msg);
|
||||
/// ```
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_logging_init(logger_fn: unsafe extern "C" fn(c_int, c_int, *const c_char)) {
|
||||
dolphin_integrations::ffi::logger::init(logger_fn);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ pub extern "C" fn slprs_logging_init(logger_fn: unsafe extern "C" fn(c_int, c_in
|
||||
/// Registers a log container, which mirrors a Dolphin `LogContainer` (`RustLogContainer`).
|
||||
///
|
||||
/// See `dolphin_logger::register_container` for more information.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_logging_register_container(
|
||||
kind: *const c_char,
|
||||
log_type: c_int,
|
||||
@@ -32,7 +32,7 @@ pub extern "C" fn slprs_logging_register_container(
|
||||
/// Updates the configuration for a registered logging container.
|
||||
///
|
||||
/// For more information, see `dolphin_logger::update_container`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_logging_update_container(kind: *const c_char, enabled: bool, level: c_int) {
|
||||
dolphin_integrations::ffi::logger::update_container(kind, enabled, level);
|
||||
}
|
||||
@@ -40,7 +40,7 @@ pub extern "C" fn slprs_logging_update_container(kind: *const c_char, enabled: b
|
||||
/// Updates the configuration for registered logging container on mainline
|
||||
///
|
||||
/// For more information, see `dolphin_logger::update_container`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_mainline_logging_update_log_level(level: c_int) {
|
||||
dolphin_integrations::ffi::logger::mainline_update_log_level(level);
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use std::ffi::{c_char, c_int, CString};
|
||||
use std::ffi::{CString, c_char, c_int};
|
||||
|
||||
use slippi_exi_device::SlippiEXIDevice;
|
||||
|
||||
@@ -6,14 +6,14 @@ use crate::{c_str_to_string, with, with_returning};
|
||||
|
||||
/// Instructs the `UserManager` on the EXI Device at the provided pointer to attempt
|
||||
/// authentication. This runs synchronously on whatever thread it's called on.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_attempt_login(exi_device_instance_ptr: usize) -> bool {
|
||||
with_returning::<SlippiEXIDevice, _, _>(exi_device_instance_ptr, |device| device.user_manager.attempt_login())
|
||||
}
|
||||
|
||||
/// Instructs the `UserManager` on the EXI Device at the provided pointer to try to
|
||||
/// open the login page in a system-provided browser view.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_open_login_page(exi_device_instance_ptr: usize) {
|
||||
with::<SlippiEXIDevice, _>(exi_device_instance_ptr, |device| {
|
||||
device.user_manager.open_login_page();
|
||||
@@ -22,7 +22,7 @@ pub extern "C" fn slprs_user_open_login_page(exi_device_instance_ptr: usize) {
|
||||
|
||||
/// Instructs the `UserManager` on the EXI Device at the provided pointer to attempt
|
||||
/// to initiate the older update flow.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_update_app(exi_device_instance_ptr: usize) -> bool {
|
||||
with_returning::<SlippiEXIDevice, _, _>(exi_device_instance_ptr, |device| device.user_manager.update_app())
|
||||
}
|
||||
@@ -30,7 +30,7 @@ pub extern "C" fn slprs_user_update_app(exi_device_instance_ptr: usize) -> bool
|
||||
/// Instructs the `UserManager` on the EXI Device at the provided pointer to start watching
|
||||
/// for the presence of a `user.json` file. The `UserManager` should have the requisite path
|
||||
/// already from EXI device instantiation.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_listen_for_login(exi_device_instance_ptr: usize) {
|
||||
with::<SlippiEXIDevice, _>(exi_device_instance_ptr, |device| {
|
||||
device.user_manager.watch_for_login();
|
||||
@@ -39,7 +39,7 @@ pub extern "C" fn slprs_user_listen_for_login(exi_device_instance_ptr: usize) {
|
||||
|
||||
/// Instructs the `UserManager` on the EXI Device at the provided pointer to sign the user out.
|
||||
/// This will delete the `user.json` file from the underlying filesystem.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_logout(exi_device_instance_ptr: usize) {
|
||||
with::<SlippiEXIDevice, _>(exi_device_instance_ptr, |device| {
|
||||
device.user_manager.logout();
|
||||
@@ -48,7 +48,7 @@ pub extern "C" fn slprs_user_logout(exi_device_instance_ptr: usize) {
|
||||
|
||||
/// Hooks through the `UserManager` on the EXI Device at the provided pointer to overwrite the
|
||||
/// latest version field on the current user.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_overwrite_latest_version(exi_device_instance_ptr: usize, version: *const c_char) {
|
||||
let version = c_str_to_string(version, "slprs_user_overwrite_latest_version", "version");
|
||||
|
||||
@@ -59,7 +59,7 @@ pub extern "C" fn slprs_user_overwrite_latest_version(exi_device_instance_ptr: u
|
||||
|
||||
/// Hooks through the `UserManager` on the EXI Device at the provided pointer to determine
|
||||
/// authentication status.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_get_is_logged_in(exi_device_instance_ptr: usize) -> bool {
|
||||
with_returning::<SlippiEXIDevice, _, _>(exi_device_instance_ptr, |device| device.user_manager.is_logged_in())
|
||||
}
|
||||
@@ -84,7 +84,7 @@ pub struct RustUserInfo {
|
||||
/// This involves slightly more allocations than ideal, so this shouldn't be called in a hot path.
|
||||
/// Over time this issue will not matter as once Matchmaking is moved to Rust we can share things
|
||||
/// quite easily.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_get_info(exi_device_instance_ptr: usize) -> *mut RustUserInfo {
|
||||
with_returning::<SlippiEXIDevice, _, _>(exi_device_instance_ptr, |device| {
|
||||
let user_info = device.user_manager.get(|user| {
|
||||
@@ -124,7 +124,7 @@ pub extern "C" fn slprs_user_get_info(exi_device_instance_ptr: usize) -> *mut Ru
|
||||
/// When the C/C++ side grabs `UserInfo`, it needs to ensure that it's passed back to Rust
|
||||
/// to ensure that the memory layout matches - do _not_ call `free` on `UserInfo`, pass it here
|
||||
/// instead.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_free_info(ptr: *mut RustUserInfo) {
|
||||
if ptr.is_null() {
|
||||
// Log here~?
|
||||
@@ -188,7 +188,7 @@ impl RustChatMessages {
|
||||
/// Returns a C-compatible struct containing the chat message options for the current user.
|
||||
///
|
||||
/// The return value of this _must_ be passed back to `slprs_user_free_messages` to free memory.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_get_messages(exi_device_instance_ptr: usize) -> *mut RustChatMessages {
|
||||
with_returning::<SlippiEXIDevice, _, _>(exi_device_instance_ptr, |device| {
|
||||
let messages = device.user_manager.get(|user| {
|
||||
@@ -205,7 +205,7 @@ pub extern "C" fn slprs_user_get_messages(exi_device_instance_ptr: usize) -> *mu
|
||||
/// Returns a C-compatible struct containing the default chat message options.
|
||||
///
|
||||
/// The return value of this _must_ be passed back to `slprs_user_free_messages` to free memory.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_get_default_messages(exi_device_instance_ptr: usize) -> *mut RustChatMessages {
|
||||
with_returning::<SlippiEXIDevice, _, _>(exi_device_instance_ptr, |_device| {
|
||||
let messages = Box::new(RustChatMessages::from(&slippi_user::DEFAULT_CHAT_MESSAGES));
|
||||
@@ -215,7 +215,7 @@ pub extern "C" fn slprs_user_get_default_messages(exi_device_instance_ptr: usize
|
||||
|
||||
/// Takes back ownership of a `RustChatMessages` instance and frees the underlying data
|
||||
/// by converting it into the proper Rust types.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_free_messages(ptr: *mut RustChatMessages) {
|
||||
if ptr.is_null() {
|
||||
// Log here~?
|
||||
@@ -244,7 +244,7 @@ pub enum DirectCodeKind {
|
||||
}
|
||||
|
||||
/// Passes along a direct code to add or update.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_direct_codes_add_or_update(
|
||||
exi_device_instance_ptr: usize,
|
||||
kind: DirectCodeKind,
|
||||
@@ -264,7 +264,7 @@ pub extern "C" fn slprs_user_direct_codes_add_or_update(
|
||||
}
|
||||
|
||||
/// Gets the length of the current direct codes stack for the given `kind`.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_direct_codes_get_length(exi_device_instance_ptr: usize, kind: DirectCodeKind) -> u32 {
|
||||
with_returning::<SlippiEXIDevice, _, _>(exi_device_instance_ptr, move |device| match kind {
|
||||
DirectCodeKind::DirectCodes => device.user_manager.direct_codes.len() as u32,
|
||||
@@ -278,7 +278,7 @@ pub extern "C" fn slprs_user_direct_codes_get_length(exi_device_instance_ptr: us
|
||||
/// this will go away over time. Just be aware it's doing more allocations than is perhaps
|
||||
/// ideal... but this area of code isn't performance sensitive anyway as it's not core
|
||||
/// gameplay.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_direct_codes_get_code_at_index(
|
||||
exi_device_instance_ptr: usize,
|
||||
kind: DirectCodeKind,
|
||||
@@ -296,7 +296,7 @@ pub extern "C" fn slprs_user_direct_codes_get_code_at_index(
|
||||
|
||||
/// As the allocator on the C++ could be different, we need to provide a `free` method
|
||||
/// that the C++ side will call when it's handled everything it needs to do.
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn slprs_user_direct_codes_free_code(code: *mut c_char) {
|
||||
unsafe {
|
||||
if !code.is_null() {
|
||||
|
@@ -3,7 +3,7 @@ name = "slippi-game-reporter"
|
||||
description = "Implements the game reporter service."
|
||||
authors = ["Slippi Team", "Ryan McGrath <ryan@rymc.io>"]
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
|
@@ -2,9 +2,9 @@
|
||||
//! not to rewrite the universe.
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
use std::thread;
|
||||
|
||||
use dolphin_integrations::Log;
|
||||
|
@@ -7,9 +7,9 @@ use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use flate2::write::GzEncoder;
|
||||
use flate2::Compression;
|
||||
use serde_json::{json, Value};
|
||||
use flate2::write::GzEncoder;
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use dolphin_integrations::{Color, Dolphin, Duration as OSDDuration, Log};
|
||||
use slippi_gg_api::APIClient;
|
||||
@@ -263,11 +263,18 @@ fn process_reports(queue: &GameReporterQueue, event: ProcessingEvent) {
|
||||
}
|
||||
|
||||
/// The true inner error, minus any metadata.
|
||||
/// the compiler thinks the fields are unused, but they're not.
|
||||
/// debug impls will render them over the Dolphin logging interface
|
||||
/// and the compiler just doesn't see that.
|
||||
#[derive(Debug)]
|
||||
enum ReportSendErrorKind {
|
||||
#[allow(dead_code)]
|
||||
Net(slippi_gg_api::Error),
|
||||
#[allow(dead_code)]
|
||||
JSON(serde_json::Error),
|
||||
#[allow(dead_code)]
|
||||
GraphQL(String),
|
||||
#[allow(dead_code)]
|
||||
NotSuccessful(String),
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@ authors = [
|
||||
"Slippi Team",
|
||||
"Daryl Pinto <daryl.j.pinto@gmail.com>"
|
||||
]
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
exclude = ["/test-data"]
|
||||
|
||||
|
@@ -49,7 +49,12 @@ pub(crate) fn get_iso_kind(iso: &mut File) -> Result<IsoKind> {
|
||||
/// let get_true_offset = create_offset_locator_fn(&mut iso)?;
|
||||
/// let offset = get_true_offset(0x424);
|
||||
/// ```
|
||||
pub(crate) fn create_offset_locator_fn(iso: &mut File) -> Result<impl Fn(u64) -> Option<u64>> {
|
||||
///
|
||||
/// Technical note:
|
||||
/// The returned function does not capture any references which is why it is
|
||||
/// marked as 'static. This must be explicit in the 2024 edition:
|
||||
/// https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules/
|
||||
pub(crate) fn create_offset_locator_fn(iso: &mut File) -> Result<impl Fn(u64) -> Option<u64> + 'static> {
|
||||
// Get the ciso header (block size and block map) of the provided file.
|
||||
// If the file is not a ciso, this will be `None`
|
||||
let ciso_header = ciso::get_ciso_header(iso)?;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::Debug;
|
||||
use std::fs::File;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||
|
||||
use dolphin_integrations::{Color, Dolphin, Duration as OSDDuration, Log};
|
||||
use hps_decode::Hps;
|
||||
@@ -10,11 +10,11 @@ use rodio::{OutputStream, Sink};
|
||||
use crate::Message::*;
|
||||
|
||||
mod errors;
|
||||
pub use errors::JukeboxError;
|
||||
use JukeboxError::*;
|
||||
pub use errors::JukeboxError;
|
||||
|
||||
mod disc;
|
||||
use disc::{get_iso_kind, IsoKind};
|
||||
use disc::{IsoKind, get_iso_kind};
|
||||
|
||||
mod utils;
|
||||
use utils::copy_bytes_from_file;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "1.70.0"
|
||||
channel = "1.88.0"
|
||||
components = ["rustfmt", "rustc-dev"]
|
||||
profile = "minimal"
|
||||
|
@@ -7,7 +7,7 @@ authors = [
|
||||
"Ryan McGrath <ryan@rymc.io>"
|
||||
]
|
||||
repository = ""
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
@@ -6,7 +6,7 @@ authors = [
|
||||
"Ryan McGrath <ryan@rymc.io>"
|
||||
]
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
|
@@ -8,8 +8,8 @@
|
||||
//! unix timestamp handling code.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::macros::format_description;
|
||||
use time::OffsetDateTime;
|
||||
use time::macros::format_description;
|
||||
|
||||
/// Serializes a timestamp as a unix timestamp (`i64`).
|
||||
pub fn serialize<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
@@ -132,7 +132,7 @@ impl DirectCodes {
|
||||
let mut codes = self.codes.lock().expect("Unable to lock codes for autocomplete");
|
||||
|
||||
let mut found = false;
|
||||
for mut entry in codes.iter_mut() {
|
||||
for entry in codes.iter_mut() {
|
||||
if entry.connect_code == code {
|
||||
found = true;
|
||||
entry.last_played = last_played;
|
||||
|
@@ -6,7 +6,7 @@ use std::time::Duration;
|
||||
|
||||
use slippi_gg_api::APIClient;
|
||||
|
||||
use super::{attempt_login, UserInfo};
|
||||
use super::{UserInfo, attempt_login};
|
||||
|
||||
/// This type manages access to user information, as well as any background thread watching
|
||||
/// for `user.json` file existence.
|
||||
@@ -50,16 +50,18 @@ impl UserInfoWatcher {
|
||||
|
||||
let watcher_thread = thread::Builder::new()
|
||||
.name("SlippiUserJSONWatcherThread".into())
|
||||
.spawn(move || loop {
|
||||
if !should_watch.load(Ordering::Relaxed) {
|
||||
return;
|
||||
}
|
||||
.spawn(move || {
|
||||
loop {
|
||||
if !should_watch.load(Ordering::Relaxed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if attempt_login(&api_client, &user, &user_json_path, &slippi_semver) {
|
||||
return;
|
||||
}
|
||||
if attempt_login(&api_client, &user, &user_json_path, &slippi_semver) {
|
||||
return;
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_millis(500));
|
||||
thread::sleep(Duration::from_millis(500));
|
||||
}
|
||||
})
|
||||
.expect("Failed to spawn SlippiUserJSONWatcherThread");
|
||||
|
||||
|
Reference in New Issue
Block a user