pub mod cheats;
pub mod incoming;
use crate::bitbuf::BitWriter;
use sdk_raw::bitbuf::BfWrite;
use sdk_raw::test_support::{mock_vtable, unexpected_call};
use std::cell::{Cell, RefCell};
use std::ptr::NonNull;
thread_local! {
static ACCEPTS: Cell<bool> = const { Cell::new(true) };
static SENT: RefCell<Vec<(BitWriter, bool)>> = const { RefCell::new(Vec::new()) };
}
pub struct MockChannel {
channel: *mut sys::INetChannel,
}
impl MockChannel {
pub fn new() -> Self {
let vtable = unsafe {
mock_vtable::<sys::INetChannel__bindgen_vtable>(
unexpected_call as *const (),
|vtable| {
(&raw mut (*vtable).INetChannel_SendData).write(record_send_data);
},
)
};
let channel = Box::into_raw(Box::new(sys::INetChannel {
vtable_: Box::into_raw(vtable),
}));
SENT.set(Vec::new());
ACCEPTS.set(true);
Self { channel }
}
pub const fn as_ptr(&self) -> *mut sys::INetChannel {
self.channel
}
#[cfg(test)]
pub(crate) fn channel(&self) -> crate::net::NetChannel<'_> {
unsafe { crate::net::NetChannel::from_raw(NonNull::new(self.channel).unwrap()) }
}
pub fn refuse(&self) {
ACCEPTS.set(false);
}
pub fn take_sent(&self) -> Vec<(BitWriter, bool)> {
SENT.take()
}
}
impl Default for MockChannel {
fn default() -> Self {
Self::new()
}
}
unsafe extern "C" fn record_send_data(
_: *mut sys::INetChannel,
buffer: *mut sys::bf_write,
reliable: bool,
) -> bool {
let bits = unsafe { BfWrite::read_back(NonNull::new(buffer.cast()).unwrap()) }
.map(BitWriter::from)
.expect("a readable buffer");
SENT.with_borrow_mut(|sent| sent.push((bits, reliable)));
ACCEPTS.get()
}