use core::ffi::c_void;
use core::sync::atomic::{AtomicU32, AtomicUsize};
pub const ABI_MAJOR: u16 = 2;
pub const ABI_MINOR: u16 = 68;
#[must_use]
pub const fn is_valid_id(id: &str) -> bool {
let bytes = id.as_bytes();
if bytes.is_empty() || bytes.len() > 64 {
return false;
}
let mut i = 0;
while i < bytes.len() {
let b = bytes[i];
if !(b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'-') {
return false;
}
i += 1;
}
true
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Header {
pub size: u32,
pub abi_major: u16,
pub abi_minor: u16,
}
impl Header {
#[must_use]
pub const fn of<T>() -> Self {
let size = size_of::<T>();
assert!(size <= u32::MAX as usize, "an ABI struct fits in u32");
#[expect(
clippy::cast_possible_truncation,
reason = "checked by the assert above"
)]
Self {
size: size as u32,
abi_major: ABI_MAJOR,
abi_minor: ABI_MINOR,
}
}
#[must_use]
pub const fn covers(self, end: usize) -> bool {
end <= self.size as usize
}
}
#[must_use]
pub unsafe fn read_headed<T: Copy>(raw: *const T, required: usize) -> Option<T> {
if raw.is_null() {
return None;
}
let header = unsafe { raw.cast::<Header>().read_unaligned() };
if !header.covers(required.max(size_of::<Header>())) {
return None;
}
let known = (header.size as usize).min(size_of::<T>());
let mut out = core::mem::MaybeUninit::<T>::zeroed();
unsafe { core::ptr::copy_nonoverlapping(raw.cast::<u8>(), out.as_mut_ptr().cast(), known) };
Some(unsafe { out.assume_init() })
}
#[must_use]
pub unsafe fn write_headed<T: Copy>(out: *mut T, value: T) -> bool {
if out.is_null() {
return false;
}
let room = unsafe { out.cast::<Header>().read_unaligned() }.size as usize;
if room < size_of::<Header>() {
return false;
}
let known = room.min(size_of::<T>());
unsafe {
core::ptr::copy_nonoverlapping((&raw const value).cast::<u8>(), out.cast(), known);
};
let size = u32::try_from(known).unwrap_or(u32::MAX);
unsafe { out.cast::<u32>().write_unaligned(size) };
true
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Str {
ptr: *const u8,
len: usize,
}
unsafe impl Send for Str {}
unsafe impl Sync for Str {}
impl Str {
pub const EMPTY: Self = Self::new("");
#[must_use]
pub const fn new(text: &str) -> Self {
Self {
ptr: text.as_ptr(),
len: text.len(),
}
}
#[must_use]
pub const fn len(&self) -> usize {
self.len
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.len == 0
}
#[must_use]
pub unsafe fn as_str<'a>(&self) -> Option<&'a str> {
if self.len == 0 {
return Some("");
}
if self.ptr.is_null() || isize::try_from(self.len).is_err() {
return None;
}
let bytes = unsafe { core::slice::from_raw_parts(self.ptr, self.len) };
core::str::from_utf8(bytes).ok()
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Status(pub u32);
impl Status {
pub const OK: Self = Self(0);
pub const MISSING: Self = Self(1);
pub const AMBIGUOUS: Self = Self(2);
pub const REFUSED: Self = Self(3);
pub const BAD_ARGS: Self = Self(4);
pub const TOO_LATE: Self = Self(5);
pub const FAULTED: Self = Self(6);
pub const WRONG_THREAD: Self = Self(7);
#[must_use]
pub const fn is_ok(self) -> bool {
self.0 == Self::OK.0
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Side(pub u8);
impl Side {
pub const SERVER: Self = Self(1);
pub const CLIENT: Self = Self(2);
pub const BOTH: Self = Self(3);
#[must_use]
pub const fn includes(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Level(pub u8);
impl Level {
pub const ERROR: Self = Self(0);
pub const WARN: Self = Self(1);
pub const INFO: Self = Self(2);
pub const DEBUG: Self = Self(3);
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::ERROR => "error",
Self::WARN => "warn",
Self::INFO => "info",
_ => "debug",
}
}
}
impl Default for Level {
fn default() -> Self {
Self::INFO
}
}
impl core::str::FromStr for Level {
type Err = ParseLevelError;
fn from_str(name: &str) -> Result<Self, Self::Err> {
match name {
"error" => Ok(Self::ERROR),
"warn" => Ok(Self::WARN),
"info" => Ok(Self::INFO),
"debug" => Ok(Self::DEBUG),
_ => Err(ParseLevelError),
}
}
}
impl serde::Serialize for Level {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.name())
}
}
impl<'de> serde::Deserialize<'de> for Level {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let name = <std::borrow::Cow<'de, str>>::deserialize(deserializer)?;
name.parse().map_err(serde::de::Error::custom)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Event(pub u32);
impl Event {
pub const SETTINGS_CHANGED: Self = Self(1);
pub const LOADER_SETTINGS_CHANGED: Self = Self(2);
pub const TICKED: Self = Self(3);
pub const WORLD_LOADED: Self = Self(4);
pub const WORLD_SAVED: Self = Self(5);
pub const PLAYER_JOINED: Self = Self(6);
pub const PLAYER_LEFT: Self = Self(7);
pub const SHUTDOWN_STARTED: Self = Self(8);
pub const BUILDING_PLACED: Self = Self(9);
pub const BUILDING_REMOVED: Self = Self(10);
pub const JOIN_REFUSED: Self = Self(11);
pub const ALTARS_CHANGED: Self = Self(12);
pub const DAY_STARTED: Self = Self(13);
pub const NIGHT_STARTED: Self = Self(14);
pub const KNOWLEDGE_CHANGED: Self = Self(15);
pub const QUEST_COMPLETED: Self = Self(16);
pub const CHUNK_LOADED: Self = Self(17);
pub const CHUNK_UNLOADED: Self = Self(18);
pub const SETTINGS_REPLACED: Self = Self(19);
pub const PLAYER_DIED: Self = Self(20);
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PlayerDeathData {
pub header: Header,
pub entity: u32,
pub cause: u32,
pub key: u64,
pub position: [f32; 3],
pub killer: [u8; 16],
pub deadly_shroud: u8,
pub drowned: u8,
pub reserved: u16,
pub killer_entity: u32,
pub reserved_tail: u32,
}
impl PlayerDeathData {
pub const HIT: u32 = 0;
pub const FALL: u32 = 1;
pub const SHROUD: u32 = 2;
pub const SUFFOCATED: u32 = 3;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct KnowledgeData {
pub header: Header,
pub entity: u32,
pub id: u32,
pub value: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct QuestData {
pub header: Header,
pub entity: u32,
pub quest: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct KnowledgeInput {
pub header: Header,
pub player: u32,
pub id: u32,
pub kind: u8,
pub scope: u8,
pub reserved: u16,
pub value: u32,
pub refusal: u32,
pub allowed: u32,
}
impl KnowledgeInput {
pub const NO_SCOPE: u8 = 0xff;
pub const ALLOWED: u32 = 0;
pub const UNKNOWN: u32 = 1;
pub const KIND: u32 = 2;
pub const WORLD: u32 = 3;
pub const COUNTER: u32 = 4;
pub const FLAG_BIT: u32 = 5;
pub const EXPERIENCE: u32 = 6;
pub const SKILL_POINTS: u32 = 7;
pub const QUEST: u32 = 8;
}
pub type KnowledgeInputFn =
unsafe extern "system" fn(call: *const KnowledgeInput, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ChunkData {
pub header: Header,
pub index: u32,
pub x: u32,
pub z: u32,
pub size: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct BuildingData {
pub header: Header,
pub entity: u32,
pub player: u32,
pub item: u32,
pub kind: u8,
pub replay: u8,
pub template: [u8; 16],
pub position: [f32; 3],
}
impl BuildingData {
pub const PLACED: u8 = 0;
pub const PICKED_UP: u8 = 1;
pub const TORN_DOWN: u8 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct PlayerInfo {
pub header: Header,
pub slot: u32,
pub entity: u32,
pub key: u64,
pub permissions: u8,
pub name_len: u8,
pub name: [u8; 64],
}
impl PlayerInfo {
pub const CAN_KICK_BAN: u8 = 1;
pub const CAN_ACCESS_INVENTORIES: u8 = 1 << 1;
pub const CAN_EDIT_BASE: u8 = 1 << 2;
pub const CAN_EDIT_WORLD: u8 = 1 << 3;
pub const CAN_EXTEND_BASE: u8 = 1 << 4;
pub const CAN_RECEIVE_EXP: u8 = 1 << 5;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct TickData {
pub header: Header,
pub step: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct PlayerData {
pub header: Header,
pub slot: u32,
pub entity: u32,
pub key: u64,
}
pub type EventFn = unsafe extern "system" fn(event: Event, data: *const c_void, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ActionCall {
pub header: Header,
pub kind: u32,
pub language: u32,
pub player: PlayerInfo,
pub action: Str,
pub args: Str,
}
impl ActionCall {
pub const SHEET: u32 = 0;
pub const RUN: u32 = 1;
pub const HINTS: u32 = 2;
pub const CONSOLE: u32 = 3;
}
pub type ActionFn =
unsafe extern "system" fn(call: *const ActionCall, user: *mut c_void, reply: *mut Str);
pub type StatusFn = unsafe extern "system" fn(user: *mut c_void, out: *mut Str);
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct RenameCall {
pub header: Header,
pub entity: u32,
pub known: u8,
pub player: PlayerInfo,
pub text: Str,
}
pub type RenameCallFn = unsafe extern "system" fn(call: *const RenameCall, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ResourceKey {
pub guid: [u8; 16],
pub type_hash: u32,
pub part: u32,
}
pub type ResourcePatchFn = unsafe extern "system" fn(
base: *const u8,
base_len: usize,
user: *mut c_void,
out: *mut *const u8,
out_len: *mut usize,
) -> Status;
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
#[error("a log level is one of \"error\", \"warn\", \"info\" or \"debug\"")]
pub struct ParseLevelError;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Fingerprint {
pub guid: [u8; 16],
pub age: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BuildInfo {
pub header: Header,
pub side: Side,
pub base: u64,
pub fingerprint: Fingerprint,
pub table: BuildTable,
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct BuildTable(pub u8);
impl BuildTable {
pub const EXACT: Self = Self(0);
pub const PATTERNS: Self = Self(1);
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Symbol {
pub name: Str,
pub rva: u64,
}
#[must_use]
pub const fn guid(hex: &str) -> [u8; 16] {
let bytes = hex.as_bytes();
assert!(bytes.len() == 32, "a GUID is 32 hex digits");
let mut out = [0u8; 16];
let mut i = 0;
while i < 16 {
out[i] = (digit(bytes[2 * i]) << 4) | digit(bytes[2 * i + 1]);
i += 1;
}
out
}
#[expect(
clippy::panic,
reason = "used in const evaluation, where a bad literal fails the build"
)]
const fn digit(c: u8) -> u8 {
match c {
b'0'..=b'9' => c - b'0',
b'a'..=b'f' => c - b'a' + 10,
_ => panic!("a GUID is lowercase hex"),
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct BuildRow {
pub side: Side,
pub fingerprint: Fingerprint,
pub symbols: *const Symbol,
pub symbol_count: usize,
pub constants: *const Symbol,
pub constant_count: usize,
}
unsafe impl Sync for BuildRow {}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Relation(pub u8);
impl Relation {
pub const REQUIRES: Self = Self(0);
pub const AFTER: Self = Self(1);
pub const BREAKS: Self = Self(2);
pub const RECOMMENDS: Self = Self(3);
pub const REPLACES: Self = Self(4);
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Dependency {
pub id: Str,
pub range: Str,
pub relation: Relation,
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ManifestFlags(pub u32);
impl ManifestFlags {
pub const NONE: Self = Self(0);
pub const JOIN: Self = Self(1);
pub const RELOAD: Self = Self(2);
#[must_use]
pub const fn contains(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Manifest {
pub header: Header,
pub id: Str,
pub version: Str,
pub side: Side,
pub flags: ManifestFlags,
pub dependencies: *const Dependency,
pub dependency_count: usize,
pub builds: *const BuildRow,
pub build_count: usize,
pub name: Str,
pub description: Str,
pub authors: *const Str,
pub author_count: usize,
pub license: Str,
pub homepage: Str,
}
unsafe impl Sync for Manifest {}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct HookFlags(pub u32);
impl HookFlags {
pub const NONE: Self = Self(0);
pub const EXCLUSIVE: Self = Self(1);
pub const CALLER_FRAME: Self = Self(2);
#[must_use]
pub const fn contains(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct HookSpec {
pub target: u64,
pub detour: usize,
pub next: *const AtomicUsize,
pub priority: i32,
pub flags: HookFlags,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct CallerFrame {
pub rsp: u64,
pub rbx: u64,
pub rbp: u64,
pub rdi: u64,
pub rsi: u64,
pub r12: u64,
pub r13: u64,
pub r14: u64,
pub r15: u64,
}
impl CallerFrame {
#[must_use]
pub const fn stack(&self) -> u64 {
self.rsp + 8
}
#[must_use]
pub unsafe fn return_address(&self) -> u64 {
unsafe { (self.rsp as *const u64).read_unaligned() }
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ModInfo {
pub header: Header,
pub id: Str,
pub version: Str,
pub side: Side,
pub flags: ManifestFlags,
pub off: u8,
pub file: Str,
pub name: Str,
pub description: Str,
pub authors: *const Str,
pub author_count: usize,
pub license: Str,
pub homepage: Str,
pub replaced_by: Str,
}
impl ModInfo {
pub const EMPTY: Self = Self {
header: Header::of::<Self>(),
id: Str::EMPTY,
version: Str::EMPTY,
side: Side(0),
flags: ManifestFlags::NONE,
off: 0,
file: Str::EMPTY,
name: Str::EMPTY,
description: Str::EMPTY,
authors: core::ptr::null(),
author_count: 0,
license: Str::EMPTY,
homepage: Str::EMPTY,
replaced_by: Str::EMPTY,
};
}
unsafe impl Send for ModInfo {}
unsafe impl Sync for ModInfo {}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ModHandle(pub usize);
impl ModHandle {
pub const NONE: Self = Self(0);
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Registers {
pub rax: u64,
pub rcx: u64,
pub rdx: u64,
pub rbx: u64,
pub rsp: u64,
pub rbp: u64,
pub rsi: u64,
pub rdi: u64,
pub r8: u64,
pub r9: u64,
pub r10: u64,
pub r11: u64,
pub r12: u64,
pub r13: u64,
pub r14: u64,
pub r15: u64,
pub rflags: u64,
}
pub type MidHookFn = unsafe extern "system" fn(registers: *mut Registers, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct MidHookSpec {
pub address: u64,
pub handler: MidHookFn,
pub user: *mut c_void,
pub priority: i32,
pub flags: HookFlags,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct InventoryOp {
pub kind: u32,
pub flags: u32,
pub target: u64,
pub other: u64,
pub item: u32,
pub count: u32,
}
impl InventoryOp {
pub const GIVE: u32 = 1;
pub const TAKE: u32 = 2;
pub const DESTROY_SLOT: u32 = 3;
pub const MOVE_SLOT: u32 = 4;
pub const MOVE_ALL: u32 = 5;
pub const INCLUDE_SPECIAL: u32 = 1;
pub const RENEW: u32 = 6;
pub const FILLED: u32 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct InventoryRequest {
pub header: Header,
pub flags: u32,
pub actor: u32,
pub ops: *const InventoryOp,
pub op_count: u32,
pub reserved: u32,
}
impl InventoryRequest {
pub const ALLOW_PARTIAL: u32 = 1;
pub const NOTIFY: u32 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct InventoryOpResult {
pub error: u32,
pub remaining: u32,
}
impl InventoryOpResult {
pub const NOT_RUN: u32 = 0x100;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct InventoryResult {
pub header: Header,
pub outcome: u32,
pub op_count: u32,
pub ops: *const InventoryOpResult,
}
impl InventoryResult {
pub const COMMITTED: u32 = 0;
pub const ROLLED_BACK: u32 = 1;
pub const UNAVAILABLE: u32 = 2;
pub const TIMED_OUT: u32 = 3;
}
pub type InventoryResultFn =
unsafe extern "system" fn(result: *const InventoryResult, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ItemData {
pub header: Header,
pub id: u32,
pub max_stack: u16,
pub category: u8,
pub rarity: u8,
pub flags: u32,
}
impl ItemData {
pub const HAS_PIDE: u32 = 1 << 1;
pub const IS_CONTAINER: u32 = 1 << 2;
pub const IS_BLUEPRINT: u32 = 1 << 3;
pub const USES_FUEL: u32 = 1 << 13;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct Bounds {
pub min: [i64; 3],
pub max: [i64; 3],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AltarInfo {
pub header: Header,
pub entity: u32,
pub level: u8,
pub tilted: u8,
pub level_count: u8,
pub reserved: u8,
pub zone: Bounds,
pub levels: [Bounds; 16],
pub position: [f64; 3],
}
impl AltarInfo {
pub const EMPTY: Self = Self {
header: Header::of::<Self>(),
entity: 0,
level: 0,
tilted: 0,
level_count: 0,
reserved: 0,
zone: Bounds {
min: [0; 3],
max: [0; 3],
},
levels: [Bounds {
min: [0; 3],
max: [0; 3],
}; 16],
position: [0.0; 3],
};
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct AltarZoneSize {
pub altar: u32,
pub level: u8,
pub reserved: [u8; 3],
pub grow: i64,
pub height: i64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ZoneCheck {
pub header: Header,
pub zones: *const Bounds,
pub zone_count: usize,
pub object: Bounds,
pub margin: i64,
}
pub type ZoneCheckFn = unsafe extern "system" fn(check: *const ZoneCheck, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct SurvivorLookup {
pub header: Header,
pub survivor: u32,
pub vanilla: u32,
pub purpose: u32,
pub entity: u32,
pub cell: [i64; 3],
pub bed_of: Option<unsafe extern "system" fn(token: *mut c_void, entity: u32) -> u32>,
pub token: *mut c_void,
}
impl SurvivorLookup {
pub const UNIQUENESS: u32 = 1;
pub const SPAWN: u32 = 2;
pub const BED_OWNER: u32 = 3;
pub const ASSIGN_BED: u32 = 4;
pub const PREVIOUS_OCCUPANT: u32 = 5;
pub const ROAMING: u32 = 6;
pub const BED_BINDING: u32 = 7;
pub const CURSOR: u32 = 8;
}
pub type SurvivorLookupFn =
unsafe extern "system" fn(call: *const SurvivorLookup, user: *mut c_void, out: *mut u32) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct BedCheck {
pub header: Header,
pub survivor: u32,
pub entity: u32,
pub bed: u32,
pub home: [i64; 3],
pub bed_at: [i64; 3],
}
pub type BedCheckFn = unsafe extern "system" fn(check: *const BedCheck, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Summon {
pub header: Header,
pub item: u32,
pub ammo: u32,
pub template: [u8; 16],
pub target: [i64; 3],
pub slot: u64,
pub pide: u32,
pub meter: [u16; 2],
pub consumed: u8,
pub reserved: [u8; 3],
}
impl Summon {
pub const TAKE: u8 = 1;
pub const REFUSE: u8 = 2;
}
pub type SummonFn = unsafe extern "system" fn(summon: *const Summon, user: *mut c_void) -> u8;
pub type SurvivorStatusFn = unsafe extern "system" fn(
survivor: u32,
statuses: *const u8,
count: usize,
user: *mut c_void,
) -> u32;
pub const SURVIVOR_STATUS_SET: u32 = 0x100;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Interaction {
pub header: Header,
pub kind: u32,
pub player: u32,
pub target: u32,
pub item: u32,
pub known: u8,
pub reserved: [u8; 3],
pub position: [f64; 3],
}
impl Interaction {
pub const OPEN: u32 = 1;
pub const MOVE: u32 = 2;
pub const SORT: u32 = 3;
pub const STOCK: u32 = 4;
pub const DISMANTLE: u32 = 5;
pub const QUICK_STASH: u32 = 6;
pub const UPGRADE: u32 = 7;
}
pub type InteractionFn =
unsafe extern "system" fn(call: *const Interaction, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct SkillCheck {
pub header: Header,
pub node: u32,
pub gate: u32,
pub unlocked: u8,
pub reserved: [u8; 3],
}
impl SkillCheck {
pub const OTHER: u32 = 0;
pub const FLY_MODE: u32 = 1;
pub const VANILLA: u8 = 0;
pub const UNLOCKED: u8 = 1;
pub const LOCKED: u8 = 2;
}
pub type SkillCheckFn =
unsafe extern "system" fn(check: *const SkillCheck, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Comfort {
pub header: Header,
pub category: u32,
pub value: i32,
pub position: [f32; 3],
}
pub type ComfortFn = unsafe extern "system" fn(comfort: *const Comfort, user: *mut c_void) -> i32;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct ExperienceRow {
pub entity: u32,
pub level: u32,
pub progress: u32,
pub need: u32,
pub gained: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ExperiencePass {
pub header: Header,
pub rows: *mut ExperienceRow,
pub row_count: usize,
pub level_cap: u32,
pub need_for: Option<unsafe extern "system" fn(token: *mut c_void, level: u32) -> u32>,
pub token: *mut c_void,
}
pub type ExperiencePassFn = unsafe extern "system" fn(pass: *mut ExperiencePass, user: *mut c_void);
pub type AltarLimitFn = unsafe extern "system" fn(flame_level: u32, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct GameEventData {
pub header: Header,
pub type_hash: u32,
pub size: u32,
pub data: *const u8,
}
pub type GameEventFn = unsafe extern "system" fn(event: *const GameEventData, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct EntityPlace {
pub entity: u32,
pub reserved: u32,
pub position: [i64; 3],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct TeleportRequest {
pub header: Header,
pub entity: u32,
pub flags: u32,
pub position: [i64; 3],
pub orientation: [f32; 4],
}
impl TeleportRequest {
pub const BEST_SPAWN: u32 = 1;
pub const ORIENTED: u32 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SpawnRequest {
pub header: Header,
pub template: [u8; 16],
pub position: [i64; 3],
pub orientation: [f32; 4],
pub level: u32,
pub reserved: u32,
pub lifetime_ns: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct CraftCheck {
pub header: Header,
pub player: u32,
pub station: u32,
pub recipe: u32,
pub amount: u32,
}
pub type CraftCheckFn = unsafe extern "system" fn(call: *const CraftCheck, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BuildCheck {
pub header: Header,
pub player: u32,
pub item: u32,
pub position: [i64; 3],
}
pub type BuildCheckFn = unsafe extern "system" fn(call: *const BuildCheck, user: *mut c_void) -> u8;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct NetMessage {
pub header: Header,
pub channel: u32,
pub reserved: u32,
pub peer: u64,
pub data: *const u8,
pub size: u32,
pub reserved_tail: u32,
}
impl NetMessage {
pub const SERVER: u64 = u64::MAX;
}
pub type NetMessageFn = unsafe extern "system" fn(message: *const NetMessage, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DaytimeInfo {
pub header: Header,
pub time: i64,
pub day_start: i64,
pub day_end: i64,
pub day_length: i64,
pub night_length: i64,
pub speed: f32,
pub flags: u32,
}
impl DaytimeInfo {
pub const DAY: u32 = 1;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DamageCheck {
pub header: Header,
pub cause: u32,
pub target: u32,
pub source: u32,
pub attacker: u32,
pub amounts: [f32; 13],
pub total: f32,
}
impl DamageCheck {
pub const HIT: u32 = 0;
pub const FALL: u32 = 1;
pub const SHROUD: u32 = 2;
pub const SHROUD_DEATH: u32 = 3;
pub const DROWNING: u32 = 4;
pub const DROWNING_DEATH: u32 = 5;
pub const FREEZING: u32 = 6;
pub const ADMIN_KILL: u32 = 7;
}
pub type DamageFilterFn = unsafe extern "system" fn(check: *mut DamageCheck, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct StatDefData {
pub header: Header,
pub ty: u8,
pub format: u8,
pub reserved: u16,
pub default: f32,
pub min: f32,
pub max: f32,
pub text: Str,
}
impl StatDefData {
pub const ADDITIVE: u8 = 0;
pub const MULTIPLICATIVE: u8 = 1;
pub const FLAG: u8 = 2;
pub const NUMBER: u8 = 0;
pub const SIGNED: u8 = 1;
pub const PERCENT: u8 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct StatRef {
pub index: u32,
pub key: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct StatModifierData {
pub stat: u32,
pub op: u8,
pub reserved: [u8; 3],
pub value: f32,
}
impl StatModifierData {
pub const ADD: u8 = 0;
pub const MULTIPLY: u8 = 1;
pub const MAX: u8 = 2;
pub const OVERRIDE: u8 = 3;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct StatModify {
pub header: Header,
pub entity: u32,
pub key: u32,
pub modifier: StatModifierData,
pub flags: u32,
pub duration_ms: u64,
}
impl StatModify {
pub const REMOVE: u32 = 1;
pub const SAVED: u32 = 1 << 1;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct StatChange {
pub header: Header,
pub entity: u32,
pub stat: StatRef,
pub old: f32,
pub new: f32,
pub reserved: u32,
}
pub type StatChangeFn = unsafe extern "system" fn(change: *const StatChange, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct StatSource {
pub kind: u8,
pub op: u8,
pub reserved: u16,
pub stat: u32,
pub value: f32,
pub id: u32,
pub owner: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct AffixDefData {
pub header: Header,
pub text: Str,
pub group: Str,
pub modifiers: *const AffixModifierData,
pub modifier_count: u32,
pub weight: u32,
pub categories: u32,
pub rarity: u8,
pub reserved: [u8; 3],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct AffixModifierData {
pub stat: u32,
pub op: u8,
pub reserved: [u8; 3],
pub min: f32,
pub max: f32,
pub step: f32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AffixRoll {
pub header: Header,
pub pide: u32,
pub item: u32,
pub min: u8,
pub max: u8,
pub max_rarity: u8,
pub flags: u8,
pub seed: u64,
}
impl AffixRoll {
pub const ONCE: u8 = 1;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct ItemLine {
pub modifier: StatModifierData,
pub affix: u32,
}
impl StatSource {
pub const ITEM: u8 = 0;
pub const BUFF: u8 = 1;
pub const ENTITY: u8 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BuffTypeInfo {
pub header: Header,
pub id: u32,
pub slot: u16,
pub flags: u16,
pub name: u32,
pub duration: i64,
}
impl BuffTypeInfo {
pub const FOOD: u16 = 0;
pub const BUFF: u16 = 1;
pub const DEBUFF: u16 = 2;
pub const RESTED: u16 = 3;
pub const TERRAIN: u16 = 4;
pub const SAVED: u16 = 1;
pub const HIDDEN: u16 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ActiveBuff {
pub header: Header,
pub id: u32,
pub entity: u32,
pub slot: u32,
pub level: u32,
pub duration: i64,
pub remaining: i64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BuffRequest {
pub header: Header,
pub entity: u32,
pub id: u32,
pub level: u32,
pub reserved: u32,
pub duration: i64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct KnowledgeInfo {
pub header: Header,
pub id: u32,
pub kind: u8,
pub scope: u8,
pub reserved: u16,
pub value: u32,
pub flags: u32,
}
impl KnowledgeInfo {
pub const BOOL: u8 = 0;
pub const COUNTER: u8 = 1;
pub const FLAGS: u8 = 2;
pub const WORLD: u8 = 0;
pub const PLAYER: u8 = 1;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct WeatherFront {
pub header: Header,
pub layer: u32,
pub effect: u32,
pub position: [i64; 3],
pub radius: f32,
pub reserved: u32,
pub remaining: i64,
}
impl WeatherFront {
pub const NONE: u32 = 0;
pub const RAIN: u32 = 1;
pub const BLIZZARD: u32 = 2;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TerrainMaterialInfo {
pub header: Header,
pub id: u8,
pub flags: u8,
pub hardness: u8,
pub reserved: u8,
pub item: u32,
pub health: i32,
}
impl TerrainMaterialInfo {
pub const FLATTENS: u8 = 1;
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct TerrainEdit {
pub header: Header,
pub kind: u32,
pub shape: u32,
pub flags: u32,
pub material: u32,
pub position: [f32; 3],
pub radius: f32,
pub height: f32,
pub protect: [u8; 16],
}
impl TerrainEdit {
pub const ADD: u32 = 0;
pub const DIG: u32 = 1;
pub const FLATTEN: u32 = 2;
pub const ROUND: u32 = 0;
pub const SQUARE: u32 = 1;
pub const DRY_RUN: u32 = 1;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct UiFrame {
pub header: Header,
pub token: u64,
pub screen: u32,
pub reserved: u32,
}
impl UiFrame {
pub const MENU: u32 = 0;
pub const LOADING: u32 = 1;
pub const IN_GAME: u32 = 2;
}
pub type UiFrameFn = unsafe extern "system" fn(frame: *const UiFrame, user: *mut c_void);
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct UiWidget {
pub header: Header,
pub kind: u32,
pub flags: u32,
pub style: u32,
pub steps: u32,
pub text: Str,
pub detail: Str,
pub options: *const Str,
pub option_count: u32,
pub index: u32,
pub value: f32,
pub min: f32,
pub max: f32,
pub result: u32,
pub anchor: u32,
pub reserved: u32,
}
impl UiWidget {
pub const WINDOW: u32 = 1;
pub const END: u32 = 2;
pub const LABEL: u32 = 3;
pub const BUTTON: u32 = 4;
pub const TOGGLE: u32 = 5;
pub const SLIDER: u32 = 6;
pub const DROPDOWN: u32 = 7;
pub const PROGRESS: u32 = 8;
pub const SOUND: u32 = 9;
pub const READ_ONLY: u32 = 1;
pub const WRAP: u32 = 2;
pub const CENTER: u32 = 4;
pub const STYLE_BODY: u32 = 0;
pub const STYLE_SECONDARY: u32 = 1;
pub const STYLE_H1: u32 = 2;
pub const STYLE_H2: u32 = 3;
pub const STYLE_H3: u32 = 4;
pub const STYLE_WARNING: u32 = 5;
pub const STYLE_POSITIVE: u32 = 6;
pub const STYLE_NEGATIVE: u32 = 7;
pub const SOUND_CLICK: u32 = 0;
pub const SOUND_CONFIRM: u32 = 1;
pub const SOUND_BACK: u32 = 2;
pub const SOUND_ERROR: u32 = 3;
pub const EMPTY: Self = Self {
header: Header::of::<Self>(),
kind: 0,
flags: 0,
style: 0,
steps: 0,
text: Str::EMPTY,
detail: Str::EMPTY,
options: core::ptr::null(),
option_count: 0,
index: 0,
value: 0.0,
min: 0.0,
max: 0.0,
result: 0,
anchor: 0,
reserved: 0,
};
pub const TOP_LEFT: u32 = 0;
pub const TOP_CENTER: u32 = 1;
pub const TOP_RIGHT: u32 = 2;
pub const BOTTOM_LEFT: u32 = 3;
pub const BOTTOM_CENTER: u32 = 4;
pub const BOTTOM_RIGHT: u32 = 5;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct UiMarker {
pub header: Header,
pub position: [i64; 3],
pub label: Str,
pub color: u32,
pub reserved: u32,
}
impl UiMarker {
pub const WHITE: u32 = 0;
pub const RED: u32 = 1;
pub const GREEN: u32 = 2;
pub const BLUE: u32 = 3;
pub const YELLOW: u32 = 4;
pub const PURPLE: u32 = 5;
pub const TURQUOISE: u32 = 6;
pub const BLACK: u32 = 7;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct UiDialog {
pub header: Header,
pub title: Str,
pub message: Str,
pub detail: Str,
pub buttons: u32,
pub flags: u32,
}
impl UiDialog {
pub const RETRY: u32 = 0;
pub const DISABLE: u32 = 1;
pub const ERASE: u32 = 2;
pub const RESET: u32 = 3;
pub const OVERWRITE: u32 = 5;
pub const CANCEL: u32 = 6;
pub const OK: u32 = 7;
pub const IGNORE: u32 = 8;
pub const BUTTONS: u32 = 0x1ef;
pub const CLOSED: u32 = u32::MAX;
pub const WAITING: u32 = 1;
}
pub type UiAnswerFn = unsafe extern "system" fn(answer: u32, user: *mut c_void);
pub type ConfigCheckFn =
unsafe extern "system" fn(text: Str, why: *mut Str, user: *mut c_void) -> Status;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct HostApi {
pub header: Header,
pub host_version: Str,
pub build: extern "system" fn(out: *mut BuildInfo),
pub symbol: extern "system" fn(me: ModHandle, name: Str, out: *mut u64) -> Status,
pub system: extern "system" fn(name: Str, out: *mut u64) -> Status,
pub field_offset: extern "system" fn(type_name: Str, field: Str, out: *mut u64) -> Status,
pub type_size: extern "system" fn(type_name: Str, out: *mut u32) -> Status,
pub hook: extern "system" fn(me: ModHandle, spec: *const HookSpec) -> Status,
pub caller_frame: extern "system" fn(out: *mut CallerFrame),
pub fault: extern "system" fn(me: ModHandle, reason: Str),
pub log: extern "system" fn(me: ModHandle, level: Level, message: Str),
pub settings: extern "system" fn(me: ModHandle, defaults: Str, out: *mut Str) -> Status,
pub publish: extern "system" fn(me: ModHandle, spec: *const ServiceSpec) -> Status,
pub service: extern "system" fn(
me: ModHandle,
wanted: *const ServiceSpec,
out: *mut ServiceFound,
) -> Status,
pub constant: extern "system" fn(me: ModHandle, name: Str, out: *mut u64) -> Status,
pub data_dir: extern "system" fn(me: ModHandle, out: *mut Str) -> Status,
pub log_level: extern "system" fn(me: ModHandle) -> Level,
pub subscribe: extern "system" fn(
me: ModHandle,
event: Event,
callback: EventFn,
user: *mut c_void,
) -> Status,
pub type_hash: extern "system" fn(type_name: Str, out: *mut u32) -> Status,
pub component: extern "system" fn(
me: ModHandle,
entity: u32,
type_hash: u32,
out: *mut *const c_void,
) -> Status,
pub entity_template:
extern "system" fn(me: ModHandle, entity: u32, out: *mut [u8; 16]) -> Status,
pub player: extern "system" fn(me: ModHandle, entity: u32, out: *mut PlayerInfo) -> Status,
pub players: extern "system" fn(
me: ModHandle,
out: *mut PlayerInfo,
capacity: u32,
count: *mut u32,
) -> Status,
pub serve_resource: extern "system" fn(
me: ModHandle,
key: *const ResourceKey,
base: *const ResourceKey,
patch: ResourcePatchFn,
user: *mut c_void,
) -> Status,
pub add_text: extern "system" fn(me: ModHandle, id: u32, language: u32, text: Str) -> Status,
pub mods: extern "system" fn(
me: ModHandle,
out: *mut ModInfo,
entry_size: u32,
capacity: u32,
count: *mut u32,
) -> Status,
pub sync: extern "system" fn(me: ModHandle, synced: Str, out: *mut Str) -> Status,
pub code_range: extern "system" fn(start: *mut u64, len: *mut u64) -> Status,
pub patch_code: extern "system" fn(
me: ModHandle,
address: u64,
expected: *const u8,
replacement: *const u8,
len: usize,
) -> Status,
pub workshop_recipes: extern "system" fn() -> u32,
pub hosting: extern "system" fn() -> u8,
pub server_world: extern "system" fn() -> u64,
pub retired_command: extern "system" fn(me: ModHandle) -> Status,
pub chat: extern "system" fn(me: ModHandle, to: u64, text: Str) -> Status,
pub set_label: extern "system" fn(me: ModHandle, entity: u32, text: Str) -> Status,
pub rename_filter:
extern "system" fn(me: ModHandle, callback: RenameCallFn, user: *mut c_void) -> Status,
pub join_missing: extern "system" fn(
me: ModHandle,
out: *mut ModInfo,
entry_size: u32,
capacity: u32,
count: *mut u32,
) -> Status,
pub hook_at: extern "system" fn(me: ModHandle, spec: *const MidHookSpec) -> Status,
pub inventory_open: extern "system" fn(me: ModHandle) -> Status,
pub item_info: extern "system" fn(me: ModHandle, item: u32, out: *mut ItemData) -> Status,
pub inventory_submit: extern "system" fn(
me: ModHandle,
request: *const InventoryRequest,
done: InventoryResultFn,
user: *mut c_void,
) -> Status,
pub status: extern "system" fn(me: ModHandle, callback: StatusFn, user: *mut c_void) -> Status,
pub run_console: extern "system" fn(me: ModHandle, line: Str, out: *mut Str) -> Status,
pub altars_open: extern "system" fn(me: ModHandle) -> Status,
pub altars: extern "system" fn(
me: ModHandle,
out: *mut AltarInfo,
entry_size: u32,
capacity: u32,
count: *mut u32,
) -> Status,
pub altar_zones_control: extern "system" fn(me: ModHandle) -> Status,
pub set_altar_zones:
extern "system" fn(me: ModHandle, sizes: *const AltarZoneSize, count: usize) -> Status,
pub zone_check_filter:
extern "system" fn(me: ModHandle, callback: ZoneCheckFn, user: *mut c_void) -> Status,
pub survivor_lookup:
extern "system" fn(me: ModHandle, callback: SurvivorLookupFn, user: *mut c_void) -> Status,
pub survivor_bed_check:
extern "system" fn(me: ModHandle, callback: BedCheckFn, user: *mut c_void) -> Status,
pub summon_filter:
extern "system" fn(me: ModHandle, callback: SummonFn, user: *mut c_void) -> Status,
pub summon_item: extern "system" fn(me: ModHandle, item: u32, survivor: u32) -> Status,
pub survivor_status:
extern "system" fn(me: ModHandle, callback: SurvivorStatusFn, user: *mut c_void) -> Status,
pub interaction_filter:
extern "system" fn(me: ModHandle, callback: InteractionFn, user: *mut c_void) -> Status,
pub skill_override: extern "system" fn(
me: ModHandle,
node: u32,
callback: SkillCheckFn,
user: *mut c_void,
) -> Status,
pub comfort_filter:
extern "system" fn(me: ModHandle, callback: ComfortFn, user: *mut c_void) -> Status,
pub experience_filter:
extern "system" fn(me: ModHandle, callback: ExperiencePassFn, user: *mut c_void) -> Status,
pub altar_limit:
extern "system" fn(me: ModHandle, callback: AltarLimitFn, user: *mut c_void) -> Status,
pub raise_base_limit: extern "system" fn(me: ModHandle) -> Status,
pub base_zones: extern "system" fn(me: ModHandle, zones: *mut u32, bases: *mut u32) -> Status,
pub game_event: extern "system" fn(
me: ModHandle,
type_hash: u32,
callback: GameEventFn,
user: *mut c_void,
) -> Status,
pub entities: extern "system" fn(
me: ModHandle,
type_hash: u32,
out: *mut EntityPlace,
capacity: u32,
count: *mut u32,
) -> Status,
pub destroy: extern "system" fn(me: ModHandle, entity: u32) -> Status,
pub save_world: extern "system" fn(me: ModHandle) -> Status,
pub world_key: extern "system" fn(me: ModHandle, out: *mut Str) -> Status,
pub component_write: extern "system" fn(
me: ModHandle,
entity: u32,
type_hash: u32,
out: *mut *mut c_void,
) -> Status,
pub emit:
extern "system" fn(me: ModHandle, type_hash: u32, data: *const u8, size: u32) -> Status,
pub teleport: extern "system" fn(me: ModHandle, request: *const TeleportRequest) -> Status,
pub spawn:
extern "system" fn(me: ModHandle, request: *const SpawnRequest, out: *mut u32) -> Status,
pub craft_filter:
extern "system" fn(me: ModHandle, callback: CraftCheckFn, user: *mut c_void) -> Status,
pub build_filter:
extern "system" fn(me: ModHandle, callback: BuildCheckFn, user: *mut c_void) -> Status,
pub net_channel: extern "system" fn(
me: ModHandle,
name: Str,
callback: NetMessageFn,
user: *mut c_void,
out: *mut u32,
) -> Status,
pub net_send: extern "system" fn(
me: ModHandle,
channel: u32,
peer: u64,
data: *const u8,
size: u32,
) -> Status,
pub net_ready: extern "system" fn(me: ModHandle, peer: u64) -> Status,
pub notify: extern "system" fn(me: ModHandle, key: u64, text: Str) -> Status,
pub time_of_day: extern "system" fn(me: ModHandle, out: *mut DaytimeInfo) -> Status,
pub set_time_of_day: extern "system" fn(me: ModHandle, time: i64) -> Status,
pub time_speed_control: extern "system" fn(me: ModHandle) -> Status,
pub set_time_speed: extern "system" fn(me: ModHandle, factor: f32) -> Status,
pub game_settings:
extern "system" fn(me: ModHandle, out: *mut u8, size: u32, preset: *mut u32) -> Status,
pub set_game_settings: extern "system" fn(me: ModHandle, data: *const u8, size: u32) -> Status,
pub damage_filter:
extern "system" fn(me: ModHandle, callback: DamageFilterFn, user: *mut c_void) -> Status,
pub buff_types: extern "system" fn(
me: ModHandle,
out: *mut BuffTypeInfo,
capacity: u32,
count: *mut u32,
) -> Status,
pub buffs: extern "system" fn(
me: ModHandle,
entity: u32,
out: *mut ActiveBuff,
capacity: u32,
count: *mut u32,
) -> Status,
pub apply_buff: extern "system" fn(me: ModHandle, request: *const BuffRequest) -> Status,
pub remove_buff:
extern "system" fn(me: ModHandle, entity: u32, id: u32, removed: *mut u8) -> Status,
pub knowledge:
extern "system" fn(me: ModHandle, entity: u32, id: u32, out: *mut KnowledgeInfo) -> Status,
pub grant_knowledge:
extern "system" fn(me: ModHandle, entity: u32, id: u32, kind: u32, value: u32) -> Status,
pub quests:
extern "system" fn(me: ModHandle, out: *mut u32, capacity: u32, count: *mut u32) -> Status,
pub weather_at:
extern "system" fn(me: ModHandle, position: *const [i64; 3], out: *mut [f32; 4]) -> Status,
pub weather_fronts: extern "system" fn(
me: ModHandle,
out: *mut WeatherFront,
capacity: u32,
count: *mut u32,
) -> Status,
pub set_weather: extern "system" fn(me: ModHandle, effect: u32, duration: i64) -> Status,
pub terrain_materials: extern "system" fn(
me: ModHandle,
out: *mut TerrainMaterialInfo,
capacity: u32,
count: *mut u32,
) -> Status,
pub terrain_edit:
extern "system" fn(me: ModHandle, edit: *const TerrainEdit, amount: *mut f32) -> Status,
pub config_schema: extern "system" fn(me: ModHandle, schema: Str) -> Status,
pub summoned:
extern "system" fn(me: ModHandle, callback: SummonFn, user: *mut c_void) -> Status,
pub item_data_open: extern "system" fn(me: ModHandle, id: Str, out: *mut u32) -> Status,
pub item_data_get: extern "system" fn(
me: ModHandle,
kind: u32,
pide: u32,
item: u32,
out: *mut u8,
capacity: u32,
len: *mut u32,
) -> Status,
pub item_data_set: extern "system" fn(
me: ModHandle,
kind: u32,
pide: u32,
item: u32,
data: *const u8,
len: u32,
) -> Status,
pub ui_frame:
extern "system" fn(me: ModHandle, callback: UiFrameFn, user: *mut c_void) -> Status,
pub ui_widget: extern "system" fn(me: ModHandle, frame: u64, widget: *mut UiWidget) -> Status,
pub ui_dialog: extern "system" fn(
me: ModHandle,
dialog: *const UiDialog,
callback: UiAnswerFn,
user: *mut c_void,
) -> Status,
pub ui_hud: extern "system" fn(me: ModHandle, callback: UiFrameFn, user: *mut c_void) -> Status,
pub ui_markers:
extern "system" fn(me: ModHandle, markers: *const UiMarker, count: u32) -> Status,
pub config_check:
extern "system" fn(me: ModHandle, callback: ConfigCheckFn, user: *mut c_void) -> Status,
pub texts: extern "system" fn(me: ModHandle, toml: Str) -> Status,
pub content_serve:
extern "system" fn(me: ModHandle, data: *const u8, len: u32, out: *mut [u32; 4]) -> Status,
pub content_read: extern "system" fn(
me: ModHandle,
hash: *const [u32; 4],
out: *mut u8,
capacity: u32,
len: *mut u32,
) -> Status,
pub icons_ready: extern "system" fn(me: ModHandle) -> Status,
pub stat_open: extern "system" fn(
me: ModHandle,
id: Str,
def: *const StatDefData,
out: *mut StatRef,
) -> Status,
pub stat_info:
extern "system" fn(me: ModHandle, stat: u32, def: *mut StatDefData, id: *mut Str) -> Status,
pub stat_value:
extern "system" fn(me: ModHandle, entity: u32, stat: u32, out: *mut f32) -> Status,
pub stat_modify: extern "system" fn(me: ModHandle, request: *const StatModify) -> Status,
pub stat_buff: extern "system" fn(
me: ModHandle,
buff: u32,
modifiers: *const StatModifierData,
count: u32,
) -> Status,
pub stats_changed:
extern "system" fn(me: ModHandle, callback: StatChangeFn, user: *mut c_void) -> Status,
pub stat_sources: extern "system" fn(
me: ModHandle,
entity: u32,
stat: u32,
out: *mut StatSource,
capacity: u32,
count: *mut u32,
) -> Status,
pub stat_watch: extern "system" fn(me: ModHandle, entity: u32, watch: u8) -> Status,
pub define_event:
extern "system" fn(me: ModHandle, spec: *const EventSpec, out: *mut u32) -> Status,
pub subscribe_event: extern "system" fn(
me: ModHandle,
spec: *const EventSpec,
callback: ModEventFn,
user: *mut c_void,
) -> Status,
pub send_event: extern "system" fn(me: ModHandle, event: u32, data: *const c_void) -> Status,
pub affix_open: extern "system" fn(
me: ModHandle,
id: Str,
def: *const AffixDefData,
out: *mut StatRef,
) -> Status,
pub affix_roll:
extern "system" fn(me: ModHandle, roll: *const AffixRoll, count: *mut u32) -> Status,
pub item_lines: extern "system" fn(
me: ModHandle,
pide: u32,
item: u32,
out: *mut ItemLine,
capacity: u32,
count: *mut u32,
) -> Status,
pub affix_info:
extern "system" fn(me: ModHandle, affix: u32, text: *mut Str, rarity: *mut u8) -> Status,
pub migrate: extern "system" fn(me: ModHandle, set: *const MigrationSet) -> Status,
pub declare_content: extern "system" fn(me: ModHandle, id: Str, out: *mut [u8; 16]) -> Status,
pub entity_data_open:
extern "system" fn(me: ModHandle, id: Str, flags: EntityDataFlags, out: *mut u32) -> Status,
pub replaced: extern "system" fn(
me: ModHandle,
out: *mut ModInfo,
entry_size: u32,
capacity: u32,
count: *mut u32,
) -> Status,
pub knowledge_input_filter:
extern "system" fn(me: ModHandle, callback: KnowledgeInputFn, user: *mut c_void) -> Status,
pub language: extern "system" fn(me: ModHandle) -> u32,
pub keep_game_settings:
extern "system" fn(me: ModHandle, data: *const u8, mask: *const u8, size: u32) -> Status,
pub forget_game_settings: extern "system" fn(me: ModHandle) -> Status,
pub revoke_knowledge:
extern "system" fn(me: ModHandle, entity: u32, id: u32, kind: u32, value: u32) -> Status,
pub account_knowledge: extern "system" fn(
me: ModHandle,
key: u64,
id: u32,
kind: u32,
value: u32,
revoke: u32,
) -> Status,
pub resource_read: extern "system" fn(
me: ModHandle,
key: *const ResourceKey,
out: *mut u8,
capacity: u32,
len: *mut u32,
) -> Status,
pub game_text:
extern "system" fn(me: ModHandle, id: u32, language: u32, out: *mut Str) -> Status,
pub rebuild_resource: extern "system" fn(me: ModHandle, key: *const ResourceKey) -> Status,
pub recipe_rule:
extern "system" fn(me: ModHandle, kind: RecipeRuleKind, name: Str, disable: u32) -> Status,
pub recipe_disabled: extern "system" fn(me: ModHandle, recipe: u32, out: *mut u32) -> Status,
pub define_point:
extern "system" fn(me: ModHandle, spec: *const PointSpec, out: *mut PointHandle) -> Status,
pub attach_point: extern "system" fn(
me: ModHandle,
link: *const PointLink,
callback: PointFn,
user: *mut c_void,
) -> Status,
pub run_point: extern "system" fn(
me: ModHandle,
point: u32,
input: *const c_void,
value: *mut c_void,
verdict: *mut PointVerdict,
) -> Status,
pub actions: extern "system" fn(me: ModHandle, callback: ActionFn, user: *mut c_void) -> Status,
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RecipeRuleKind(pub u32);
impl RecipeRuleKind {
pub const RECIPE: Self = Self(0);
pub const OUTPUT: Self = Self(1);
pub const WORKSHOP: Self = Self(2);
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct EntityDataFlags(pub u32);
impl EntityDataFlags {
pub const NONE: Self = Self(0);
pub const SENT: Self = Self(1);
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct MigrationStep {
pub kind: u32,
pub from: Str,
pub to: Str,
pub from_guid: [u8; 16],
pub to_guid: [u8; 16],
}
impl MigrationStep {
pub const RENAME_SETTING: u32 = 1;
pub const MAP_SETTING: u32 = 2;
pub const REMOVE_SETTING: u32 = 3;
pub const RENAME_STORE: u32 = 4;
pub const MAP_STORE: u32 = 5;
pub const RENAME_CONTENT: u32 = 6;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Migration {
pub id: Str,
pub steps: *const MigrationStep,
pub count: u32,
}
pub type MigrateFn = unsafe extern "system" fn(
user: *mut c_void,
migration: u32,
step: u32,
input: Str,
out: *mut Str,
) -> Status;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct MigrationSet {
pub header: Header,
pub migrations: *const Migration,
pub count: u32,
pub map: MigrateFn,
pub user: *mut c_void,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct LayoutField {
pub name: Str,
pub hash: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Layout {
pub fields: *const LayoutField,
pub count: u32,
pub size: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ServiceSpec {
pub header: Header,
pub name: Str,
pub major: u32,
pub layout: Layout,
pub table: *const c_void,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ServiceFound {
pub header: Header,
pub table: *const c_void,
pub fields: u32,
pub owner: Str,
pub owner_version: Str,
pub reason: Str,
}
impl ServiceFound {
pub const EMPTY: Self = Self {
header: Header::of::<Self>(),
table: core::ptr::null(),
fields: 0,
owner: Str::EMPTY,
owner_version: Str::EMPTY,
reason: Str::EMPTY,
};
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct EventSpec {
pub header: Header,
pub name: Str,
pub layout: Layout,
}
pub type ModEventFn = unsafe extern "system" fn(data: *const c_void, user: *mut c_void);
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct PointMode(pub u32);
impl PointMode {
pub const OBSERVE: Self = Self(0);
pub const ADVISE: Self = Self(1);
pub const OVERRIDE: Self = Self(2);
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct PointFlags(pub u32);
impl PointFlags {
pub const NONE: Self = Self(0);
pub const REFUSE: Self = Self(1);
#[must_use]
pub const fn contains(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct PointSpec {
pub header: Header,
pub name: Str,
pub mode: PointMode,
pub flags: PointFlags,
pub input: Layout,
pub output: Layout,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct PointLink {
pub header: Header,
pub point: *const PointSpec,
pub before: *const Str,
pub after: *const Str,
pub before_count: u32,
pub after_count: u32,
pub priority: i32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct PointHandle {
pub header: Header,
pub id: u32,
pub live: *const AtomicU32,
}
impl PointHandle {
pub const EMPTY: Self = Self {
header: Header::of::<Self>(),
id: 0,
live: core::ptr::null(),
};
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct PointVerdict(pub u32);
impl PointVerdict {
pub const PASS: Self = Self(0);
pub const SET: Self = Self(1);
pub const REFUSE: Self = Self(2);
pub const PANICKED: Self = Self(3);
}
pub type PointFn = unsafe extern "system" fn(
input: *const c_void,
value: *mut c_void,
user: *mut c_void,
) -> PointVerdict;
pub mod exports {
pub const ABI: &str = "enshwick_mod_abi";
pub const QUERY: &str = "enshwick_mod_query";
pub const INIT: &str = "enshwick_mod_init";
pub const READY: &str = "enshwick_mod_ready";
pub const SHUTDOWN: &str = "enshwick_mod_shutdown";
}
const _: () = {
assert!(size_of::<Header>() == 8);
assert!(size_of::<Str>() == 16);
assert!(size_of::<Status>() == 4);
assert!(size_of::<Fingerprint>() == 20);
assert!(size_of::<Symbol>() == 24);
assert!(core::mem::offset_of!(Manifest, header) == 0);
assert!(core::mem::offset_of!(Manifest, id) == 8);
assert!(core::mem::offset_of!(Manifest, version) == 24);
assert!(core::mem::offset_of!(Manifest, side) == 40);
assert!(core::mem::offset_of!(Manifest, flags) == 44);
assert!(core::mem::offset_of!(Manifest, dependencies) == 48);
assert!(core::mem::offset_of!(HookSpec, target) == 0);
assert!(core::mem::offset_of!(HookSpec, next) == 16);
assert!(core::mem::offset_of!(HookSpec, flags) == 28);
assert!(core::mem::offset_of!(HostApi, header) == 0);
assert!(core::mem::offset_of!(HostApi, host_version) == 8);
assert!(core::mem::offset_of!(HostApi, build) == 24);
assert!(core::mem::offset_of!(HostApi, service) == 24 + 11 * 8);
assert!(core::mem::offset_of!(HostApi, constant) == 24 + 12 * 8);
assert!(core::mem::offset_of!(HostApi, data_dir) == 24 + 13 * 8);
assert!(core::mem::offset_of!(HostApi, log_level) == 24 + 14 * 8);
assert!(core::mem::offset_of!(HostApi, subscribe) == 24 + 15 * 8);
assert!(core::mem::offset_of!(HostApi, players) == 24 + 20 * 8);
assert!(core::mem::offset_of!(HostApi, serve_resource) == 24 + 21 * 8);
assert!(core::mem::offset_of!(HostApi, add_text) == 24 + 22 * 8);
assert!(core::mem::offset_of!(HostApi, mods) == 24 + 23 * 8);
assert!(core::mem::offset_of!(HostApi, sync) == 24 + 24 * 8);
assert!(core::mem::offset_of!(HostApi, code_range) == 24 + 25 * 8);
assert!(core::mem::offset_of!(HostApi, workshop_recipes) == 24 + 27 * 8);
assert!(core::mem::offset_of!(HostApi, hosting) == 24 + 28 * 8);
assert!(core::mem::offset_of!(HostApi, server_world) == 24 + 29 * 8);
assert!(core::mem::offset_of!(HostApi, retired_command) == 24 + 30 * 8);
assert!(core::mem::offset_of!(HostApi, rename_filter) == 24 + 33 * 8);
assert!(core::mem::offset_of!(HostApi, join_missing) == 24 + 34 * 8);
assert!(core::mem::offset_of!(HostApi, hook_at) == 24 + 35 * 8);
assert!(core::mem::offset_of!(HostApi, inventory_open) == 24 + 36 * 8);
assert!(core::mem::offset_of!(HostApi, inventory_submit) == 24 + 38 * 8);
assert!(core::mem::offset_of!(HostApi, affix_open) == 24 + 118 * 8);
assert!(size_of::<AffixDefData>() == 8 + 32 + 8 + 16);
assert!(size_of::<AffixModifierData>() == 20);
assert!(size_of::<ItemLine>() == 16);
assert!(size_of::<AffixRoll>() == 8 + 12 + 4 + 8);
assert!(core::mem::offset_of!(HostApi, stat_open) == 24 + 107 * 8);
assert!(size_of::<StatDefData>() == 8 + 16 + 16);
assert!(size_of::<StatRef>() == 8);
assert!(size_of::<StatModifierData>() == 12);
assert!(size_of::<StatSource>() == 20);
assert!(size_of::<StatModify>() == 8 + 8 + 12 + 4 + 8);
assert!(size_of::<StatChange>() == 8 + 24);
assert!(core::mem::offset_of!(HostApi, language) == 24 + 127 * 8);
assert!(size_of::<HostApi>() == 24 + 141 * 8);
assert!(core::mem::offset_of!(HostApi, recipe_rule) == 24 + 135 * 8);
assert!(core::mem::offset_of!(HostApi, recipe_disabled) == 24 + 136 * 8);
assert!(core::mem::offset_of!(HostApi, rebuild_resource) == 24 + 134 * 8);
assert!(core::mem::offset_of!(HostApi, game_text) == 24 + 133 * 8);
assert!(core::mem::offset_of!(HostApi, account_knowledge) == 24 + 131 * 8);
assert!(core::mem::offset_of!(HostApi, replaced) == 24 + 125 * 8);
assert!(core::mem::offset_of!(HostApi, entity_data_open) == 24 + 124 * 8);
assert!(core::mem::offset_of!(HostApi, knowledge_input_filter) == 24 + 126 * 8);
assert!(core::mem::offset_of!(HostApi, forget_game_settings) == 24 + 129 * 8);
assert!(size_of::<KnowledgeInput>() == 8 + 24);
assert!(core::mem::offset_of!(HostApi, migrate) == 24 + 122 * 8);
assert!(core::mem::offset_of!(HostApi, declare_content) == 24 + 123 * 8);
assert!(size_of::<MigrationStep>() == 8 + 16 + 16 + 16 + 16);
assert!(size_of::<Migration>() == 16 + 8 + 8);
assert!(size_of::<MigrationSet>() == 8 + 8 + 8 + 8 + 8);
assert!(core::mem::offset_of!(HostApi, define_event) == 24 + 115 * 8);
assert!(core::mem::offset_of!(HostApi, define_point) == 24 + 137 * 8);
assert!(size_of::<PointSpec>() == 8 + 16 + 4 + 4 + 16 + 16);
assert!(size_of::<PointLink>() == 8 + 3 * 8 + 3 * 4 + 4);
assert!(size_of::<PointHandle>() == 8 + 8 + 8);
assert!(size_of::<LayoutField>() == 24);
assert!(size_of::<Layout>() == 16);
assert!(size_of::<ServiceSpec>() == 8 + 16 + 8 + 16 + 8);
assert!(size_of::<ServiceFound>() == 8 + 8 + 8 + 3 * 16);
assert!(size_of::<EventSpec>() == 8 + 16 + 16);
assert!(core::mem::offset_of!(HostApi, config_schema) == 24 + 92 * 8);
assert!(core::mem::offset_of!(HostApi, time_of_day) == 24 + 73 * 8);
assert!(core::mem::offset_of!(HostApi, set_time_speed) == 24 + 76 * 8);
assert!(size_of::<DaytimeInfo>() == 8 + 5 * 8 + 8);
assert!(core::mem::offset_of!(HostApi, game_settings) == 24 + 77 * 8);
assert!(core::mem::offset_of!(HostApi, damage_filter) == 24 + 79 * 8);
assert!(size_of::<DamageCheck>() == 8 + 16 + 13 * 4 + 4);
assert!(core::mem::offset_of!(HostApi, buff_types) == 24 + 80 * 8);
assert!(core::mem::offset_of!(HostApi, remove_buff) == 24 + 83 * 8);
assert!(size_of::<BuffTypeInfo>() == 8 + 12 + 4 + 8);
assert!(size_of::<ActiveBuff>() == 8 + 16 + 16);
assert!(size_of::<BuffRequest>() == 8 + 16 + 8);
assert!(core::mem::offset_of!(HostApi, knowledge) == 24 + 84 * 8);
assert!(core::mem::offset_of!(HostApi, quests) == 24 + 86 * 8);
assert!(size_of::<KnowledgeInfo>() == 8 + 16);
assert!(size_of::<KnowledgeData>() == 8 + 12);
assert!(size_of::<PlayerDeathData>() == 8 + 8 + 8 + 12 + 16 + 4 + 8);
assert!(size_of::<QuestData>() == 8 + 8);
assert!(core::mem::offset_of!(HostApi, weather_at) == 24 + 87 * 8);
assert!(core::mem::offset_of!(HostApi, set_weather) == 24 + 89 * 8);
assert!(size_of::<WeatherFront>() == 8 + 8 + 24 + 8 + 8);
assert!(size_of::<ChunkData>() == 8 + 16);
assert!(core::mem::offset_of!(HostApi, terrain_materials) == 24 + 90 * 8);
assert!(size_of::<TerrainMaterialInfo>() == 8 + 12);
assert!(size_of::<TerrainEdit>() == 8 + 16 + 12 + 8 + 16);
assert!(size_of::<InventoryOp>() == 32);
assert!(size_of::<InventoryRequest>() == 32);
assert!(size_of::<InventoryOpResult>() == 8);
assert!(size_of::<InventoryResult>() == 24);
assert!(size_of::<ItemData>() == 20);
assert!(size_of::<PlayerInfo>() == 96);
assert!(core::mem::offset_of!(PlayerInfo, name) == 26);
assert!(size_of::<Registers>() == 17 * 8);
assert!(core::mem::offset_of!(Registers, rsp) == 4 * 8);
assert!(core::mem::offset_of!(Registers, rflags) == 16 * 8);
assert!(size_of::<MidHookSpec>() == 32);
assert!(core::mem::offset_of!(HostApi, status) == 24 + 39 * 8);
assert!(core::mem::offset_of!(HostApi, run_console) == 24 + 40 * 8);
assert!(core::mem::offset_of!(HostApi, actions) == 24 + 140 * 8);
assert!(size_of::<ActionCall>() == 8 + 8 + 96 + 16 + 16);
assert!(core::mem::offset_of!(HostApi, altars_open) == 24 + 41 * 8);
assert!(core::mem::offset_of!(HostApi, zone_check_filter) == 24 + 45 * 8);
assert!(core::mem::offset_of!(HostApi, survivor_lookup) == 24 + 46 * 8);
assert!(core::mem::offset_of!(HostApi, survivor_status) == 24 + 50 * 8);
assert!(core::mem::offset_of!(HostApi, interaction_filter) == 24 + 51 * 8);
assert!(core::mem::offset_of!(HostApi, skill_override) == 24 + 52 * 8);
assert!(core::mem::offset_of!(HostApi, experience_filter) == 24 + 54 * 8);
assert!(core::mem::offset_of!(HostApi, base_zones) == 24 + 57 * 8);
assert!(core::mem::offset_of!(HostApi, game_event) == 24 + 58 * 8);
assert!(core::mem::offset_of!(HostApi, world_key) == 24 + 62 * 8);
assert!(core::mem::offset_of!(HostApi, component_write) == 24 + 63 * 8);
assert!(core::mem::offset_of!(HostApi, teleport) == 24 + 65 * 8);
assert!(size_of::<TeleportRequest>() == 8 + 8 + 24 + 16);
assert!(core::mem::offset_of!(HostApi, spawn) == 24 + 66 * 8);
assert!(size_of::<SpawnRequest>() == 8 + 16 + 24 + 16 + 8 + 8);
assert!(core::mem::offset_of!(HostApi, build_filter) == 24 + 68 * 8);
assert!(size_of::<CraftCheck>() == 8 + 16);
assert!(size_of::<BuildCheck>() == 8 + 8 + 24);
assert!(core::mem::offset_of!(HostApi, net_ready) == 24 + 71 * 8);
assert!(size_of::<NetMessage>() == 8 + 8 + 8 + 8 + 8);
assert!(core::mem::offset_of!(HostApi, notify) == 24 + 72 * 8);
assert!(core::mem::offset_of!(HostApi, ui_dialog) == 24 + 99 * 8);
assert!(size_of::<UiFrame>() == 24);
assert!(size_of::<UiWidget>() == 8 + 16 + 32 + 8 + 32);
assert!(size_of::<UiMarker>() == 8 + 24 + 16 + 8);
assert!(core::mem::offset_of!(HostApi, texts) == 24 + 103 * 8);
assert!(core::mem::offset_of!(HostApi, config_check) == 24 + 102 * 8);
assert!(size_of::<UiDialog>() == 8 + 48 + 8);
assert!(size_of::<GameEventData>() == 24);
assert!(size_of::<EntityPlace>() == 32);
assert!(size_of::<SkillCheck>() == 20);
assert!(size_of::<Comfort>() == 28);
assert!(size_of::<ExperienceRow>() == 20);
assert!(size_of::<ExperiencePass>() == 48);
assert!(size_of::<Interaction>() == 8 + 16 + 8 + 24);
assert!(size_of::<SurvivorLookup>() == 8 + 16 + 24 + 16);
assert!(size_of::<BedCheck>() == 8 + 12 + 4 + 48);
assert!(size_of::<Summon>() == 8 + 8 + 16 + 24 + 8 + 4 + 4 + 4 + 4);
assert!(size_of::<Bounds>() == 48);
assert!(size_of::<AltarInfo>() == 16 + 17 * 48 + 24);
assert!(size_of::<AltarZoneSize>() == 24);
assert!(size_of::<ZoneCheck>() == 8 + 16 + 48 + 8);
assert!(core::mem::offset_of!(Manifest, name) == 80);
assert!(size_of::<Manifest>() == 80 + 16 * 4 + 16);
assert!(size_of::<ResourceKey>() == 24);
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_null_or_impossible_text_reads_as_none() {
let null = Str {
ptr: core::ptr::null(),
len: 5,
};
let huge = Str {
ptr: c"x".as_ptr().cast(),
len: usize::MAX,
};
let (null, huge) = (unsafe { null.as_str() }, unsafe { huge.as_str() });
assert_eq!((null, huge), (None, None));
}
}