Skip to main content

Hook

Struct Hook 

Source
pub struct Hook<F: FnPtr> { /* private fields */ }
Expand description

A mod’s link for one game function: its detour and the slot through which it reaches the rest of the chain.

Declared with detour! or #[hook], registered with Load::hook.

§Examples

enshwick::detour! {
    /// Counts upgrades.
    static UPGRADE: unsafe extern "system" fn(ctx: *mut u64) = upgrade;
}

fn upgrade(next: enshwick::Next<unsafe extern "system" fn(*mut u64)>, ctx: *mut u64) {
    // SAFETY: the original takes the same context.
    unsafe { next.get()(ctx) }
}

assert_eq!(UPGRADE.name(), "UPGRADE");

Implementations§

Source§

impl<F: FnPtr> Hook<F>

Source

pub const fn new( name: &'static str, detour: F, priority: i32, flags: HookFlags, ) -> Self

A link whose entry point is detour; used by detour!.

§Examples

See Hook.

Source

pub const fn name(&self) -> &'static str

The name the link was declared with, used in log lines.

§Examples

See Hook.

Source

pub const fn entry(&self) -> F

The entry point the loader links into the chain: the detour with its panic guard, as the game calls it.

§Examples
enshwick::detour! {
    static TICK: extern "system" fn() = tick;
}

fn tick(next: enshwick::Next<extern "system" fn()>) {
    next.get()();
}

let entry: extern "system" fn() = TICK.entry();
Source

pub fn next(&'static self) -> Next<F>

The rest of the chain: the next link or the original function.

§Examples

See Hook.

Source

pub fn after_next<R>(&self, work: impl FnOnce() -> R) -> Option<R>

Runs work that a detour does after calling next, so that a panic in it turns the mod off without running the rest of the chain again.

A panic in the body falls through to the rest of the chain, which is right before next and wrong after it: the game’s function would run twice. Work after next belongs in here. A panic in work reports a fault, as a panic in the body does, and gives None; the detour then returns what next gave. The guard costs nothing until a panic.

§Examples
use std::sync::atomic::{AtomicU32, Ordering};

static RAISED: AtomicU32 = AtomicU32::new(0);

enshwick::detour! {
    static RAISE: extern "system" fn(level: u32) -> u32 = raise;
}

fn raise(next: enshwick::Next<extern "system" fn(u32) -> u32>, level: u32) -> u32 {
    let raised = next.get()(level);
    let _counted = RAISE.after_next(|| RAISED.fetch_add(raised - level, Ordering::Relaxed));
    raised
}

Trait Implementations§

Source§

impl<F: Debug + FnPtr> Debug for Hook<F>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<F> !Freeze for Hook<F>

§

impl<F> RefUnwindSafe for Hook<F>
where F: RefUnwindSafe,

§

impl<F> Send for Hook<F>

§

impl<F> Sync for Hook<F>

§

impl<F> Unpin for Hook<F>
where F: Unpin,

§

impl<F> UnsafeUnpin for Hook<F>
where F: UnsafeUnpin,

§

impl<F> UnwindSafe for Hook<F>
where F: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.