removed old files/modules
This commit is contained in:
parent
b1bf442a27
commit
4af21ba271
|
@ -1,231 +0,0 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
use crate::tarray::{FString, TArray};
|
||||
use bitflags::bitflags;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct VTbl(NonNull<()>);
|
||||
|
||||
impl VTbl {}
|
||||
|
||||
bitflags! {
|
||||
#[repr(C)]
|
||||
pub struct EObjectFlags: u32 {
|
||||
const RF_NoFlags = 0x00000000;
|
||||
const RF_Public = 0x00000001;
|
||||
const RF_Standalone = 0x00000002;
|
||||
const RF_MarkAsNative = 0x00000004;
|
||||
const RF_Transactional = 0x00000008;
|
||||
const RF_ClassDefaultObject = 0x00000010;
|
||||
const RF_ArchetypeObject = 0x00000020;
|
||||
const RF_Transient = 0x00000040;
|
||||
const RF_MarkAsRootSet = 0x00000080;
|
||||
const RF_TagGarbageTemp = 0x00000100;
|
||||
const RF_NeedInitialization = 0x00000200;
|
||||
const RF_NeedLoad = 0x00000400;
|
||||
const RF_KeepForCooker = 0x00000800;
|
||||
const RF_NeedPostLoad = 0x00001000;
|
||||
const RF_NeedPostLoadSubobjects = 0x00002000;
|
||||
const RF_NewerVersionExists = 0x00004000;
|
||||
const RF_BeginDestroyed = 0x00008000;
|
||||
const RF_FinishDestroyed = 0x00010000;
|
||||
const RF_BeingRegenerated = 0x00020000;
|
||||
const RF_DefaultSubObject = 0x00040000;
|
||||
const RF_WasLoaded = 0x00080000;
|
||||
const RF_TextExportTransient = 0x00100000;
|
||||
const RF_LoadCompleted = 0x00200000;
|
||||
const RF_InheritableComponentTemplate = 0x00400000;
|
||||
const RF_DuplicateTransient = 0x00800000;
|
||||
const RF_StrongRefOnFrame = 0x01000000;
|
||||
const RF_NonPIEDuplicateTransient = 0x02000000;
|
||||
const RF_Dynamic = 0x04000000;
|
||||
const RF_WillBeLoaded = 0x08000000;
|
||||
const RF_HasExternalPackage = 0x10000000;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::global_tables::names::GNAMES;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UObject {
|
||||
pub vtbl: VTbl,
|
||||
pub object_flags: EObjectFlags, //EObjectFlags,
|
||||
pub internal_index: u32,
|
||||
pub class: Option<NonNull<UClass>>,
|
||||
pub name: FName,
|
||||
pub outer: Option<NonNull<UObject>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
|
||||
pub struct FName {
|
||||
pub comparison_index: u32,
|
||||
pub number: u32,
|
||||
}
|
||||
|
||||
impl FName {
|
||||
pub fn get_name(&self) -> anyhow::Result<String> {
|
||||
GNAMES
|
||||
.read()
|
||||
.unwrap()
|
||||
.as_names()
|
||||
.unwrap()
|
||||
.fname_to_string(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UField {
|
||||
pub uobject: UObject,
|
||||
pub next: Option<NonNull<UField>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UEnum {
|
||||
pub ufield: UField,
|
||||
pub cpp_type: FString,
|
||||
pub names: TArray<FName>,
|
||||
pub cpp_form: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UStruct {
|
||||
pub(crate) ufield: UField,
|
||||
pub(crate) super_field: Option<NonNull<UStruct>>,
|
||||
pub(crate) children: Option<NonNull<UField>>,
|
||||
pub(crate) property_size: u32,
|
||||
pub(crate) min_alignment: u32,
|
||||
padding1: [u8; 0x48],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UClass {
|
||||
pub(crate) ustruct: UStruct,
|
||||
padding1: [u8; 0xF8],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UProperty {
|
||||
pub(crate) ufield: UField,
|
||||
array_dim: i32,
|
||||
element_size: i32,
|
||||
property_flags: u64,
|
||||
rep_index: i16,
|
||||
rep_notify_function: FName,
|
||||
offset: i32,
|
||||
property_link_next: Option<NonNull<UProperty>>,
|
||||
next_ref: Option<NonNull<UProperty>>,
|
||||
destructor_link_next: Option<NonNull<UProperty>>,
|
||||
post_construct_link_next: Option<NonNull<UProperty>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UByteProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
uenum: Option<NonNull<UEnum>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UBoolProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
field_size: u8,
|
||||
byte_offset: u8,
|
||||
byte_mask: u8,
|
||||
field_mask: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UObjectProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
property_class: Option<NonNull<UClass>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UClassProperty {
|
||||
pub(crate) uobjectproperty: UObjectProperty,
|
||||
meta_class: Option<NonNull<UClass>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UAssetClassProperty {
|
||||
pub(crate) uobjectproperty: UObjectProperty,
|
||||
meta_class: Option<NonNull<UClass>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UInterfaceProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
interface_class: Option<NonNull<UClass>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UStructProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
ustruct: Option<NonNull<UStruct>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UArrayProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
inner: Option<NonNull<UProperty>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UMapProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
key_prop: Option<NonNull<UProperty>>,
|
||||
value_prop: Option<NonNull<UProperty>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UDelegateProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
signature_function: Option<NonNull<UFunction>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UMulticastDelegateProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
signature_function: Option<NonNull<UFunction>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UEnumProperty {
|
||||
pub(crate) uproperty: UProperty,
|
||||
underlying_type: Option<NonNull<UProperty>>,
|
||||
uenum: Option<NonNull<UEnum>>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct UFunction {
|
||||
pub(crate) ustruct: UStruct,
|
||||
function_flags: u32,
|
||||
rep_offset: u16,
|
||||
num_params: u8,
|
||||
params_size: u16,
|
||||
return_value_offset: u16,
|
||||
rpc_id: u16,
|
||||
rpc_response_id: u16,
|
||||
first_property_to_init: Option<NonNull<UProperty>>,
|
||||
function: Option<NonNull<()>>,
|
||||
}
|
22
src/lib.rs
22
src/lib.rs
|
@ -7,12 +7,10 @@
|
|||
if_let_guard
|
||||
)]
|
||||
|
||||
// mod core_types;
|
||||
pub mod fname;
|
||||
pub mod global_tables;
|
||||
pub mod helper_types;
|
||||
pub mod tarray;
|
||||
// pub mod types;
|
||||
pub mod v2_types;
|
||||
|
||||
pub mod sdk {
|
||||
|
@ -34,10 +32,10 @@ pub mod sdk {
|
|||
actor_static_class,
|
||||
any_type::{self, AnyField, AnyObject, AnyProperty, AnyStruct},
|
||||
traits::{
|
||||
AsUObject, StaticClass, UArrayPropertyTrait, UBoolPropertyTrait,
|
||||
UBytePropertyTrait, UEnumPropertyTrait, UEnumTrait, UFunctionTrait,
|
||||
UObjectNonConst, UObjectPropertyBaseTrait, UObjectTrait, UPropertyTrait,
|
||||
UStructNonConst, UStructPropertyTrait, UStructTrait,
|
||||
AsUObject, StaticClass, UArrayPropertyTrait, UBytePropertyTrait,
|
||||
UEnumPropertyTrait, UEnumTrait, UFunctionTrait, UObjectNonConst,
|
||||
UObjectPropertyBaseTrait, UObjectTrait, UPropertyTrait, UStructNonConst,
|
||||
UStructPropertyTrait, UStructTrait,
|
||||
},
|
||||
EFunctionFlags, EPropertyFlags, UBoolProperty, UClass, UEnum, UFunction, UObject,
|
||||
UStruct,
|
||||
|
@ -431,6 +429,7 @@ pub mod sdk {
|
|||
)
|
||||
),
|
||||
ty,
|
||||
flags: *prop.property_flags(),
|
||||
};
|
||||
|
||||
let param = if prop
|
||||
|
@ -469,6 +468,7 @@ pub mod sdk {
|
|||
full_name,
|
||||
is_native,
|
||||
is_static,
|
||||
flags: *func.function_flags(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -805,6 +805,14 @@ pub mod sdk {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeKind {
|
||||
Object,
|
||||
Actor,
|
||||
Enum,
|
||||
Struct,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClassField {
|
||||
pub offset: u32,
|
||||
|
@ -817,6 +825,7 @@ pub mod sdk {
|
|||
pub struct MethodParameter {
|
||||
pub name: String,
|
||||
pub ty: Type,
|
||||
pub flags: EPropertyFlags,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -827,6 +836,7 @@ pub mod sdk {
|
|||
pub is_static: bool,
|
||||
pub parameters: Vec<ParameterKind>,
|
||||
pub return_type: Option<MethodParameter>,
|
||||
pub flags: EFunctionFlags,
|
||||
}
|
||||
|
||||
impl ClassMethod {
|
||||
|
|
652
src/types.rs
652
src/types.rs
|
@ -1,652 +0,0 @@
|
|||
use anyhow::Context;
|
||||
use itertools::Itertools;
|
||||
use std::{hash::Hash, ptr::NonNull};
|
||||
|
||||
use crate::core_types::{self, FName};
|
||||
use crate::tarray::TArray;
|
||||
|
||||
use self::traits::{AsUObject, AsUStruct, FromRaw};
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UObject {
|
||||
inner: NonNull<core_types::UObject>,
|
||||
}
|
||||
|
||||
unsafe impl Send for UObject {}
|
||||
unsafe impl Sync for UObject {}
|
||||
|
||||
impl Eq for UObject {}
|
||||
|
||||
impl PartialEq for UObject {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe {
|
||||
self.inner.as_ref().internal_index == other.inner.as_ref().internal_index
|
||||
&& self.inner.as_ref().name == other.inner.as_ref().name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for UObject {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.internal_index().hash(state);
|
||||
self.name().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UClass {
|
||||
pub(crate) inner: NonNull<core_types::UClass>,
|
||||
}
|
||||
|
||||
impl Eq for UClass {}
|
||||
|
||||
impl PartialEq for UClass {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_uobject().eq(&other.as_uobject())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for UClass {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.as_uobject().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UField {
|
||||
inner: NonNull<core_types::UField>,
|
||||
}
|
||||
|
||||
impl Eq for UField {}
|
||||
|
||||
impl PartialEq for UField {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_uobject().eq(&other.as_uobject())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for UField {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.as_uobject().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl UObject {
|
||||
pub fn new(inner: NonNull<core_types::UObject>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn maybe_new(inner: Option<NonNull<core_types::UObject>>) -> Option<Self> {
|
||||
inner.map(|inner| Self { inner })
|
||||
}
|
||||
|
||||
pub fn to_inner(self) -> NonNull<core_types::UObject> {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub const unsafe fn cast<T>(self) -> NonNull<T> {
|
||||
self.inner.cast::<T>()
|
||||
}
|
||||
|
||||
/// returns a `Self` with the provided raw pointer, if the pointer is not null
|
||||
pub fn maybe_with_raw(raw: *mut core_types::UObject) -> Option<Self> {
|
||||
Self::maybe_new(NonNull::new(raw))
|
||||
}
|
||||
|
||||
pub fn class(&self) -> Option<UClass> {
|
||||
unsafe { self.inner.as_ref().class.map(|inner| UClass::new(inner)) }
|
||||
}
|
||||
|
||||
pub fn internal_index(&self) -> u32 {
|
||||
unsafe { self.inner.as_ref().internal_index }
|
||||
}
|
||||
|
||||
pub fn name(&self) -> core_types::FName {
|
||||
unsafe { self.inner.as_ref().name }
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> anyhow::Result<String> {
|
||||
let name = self.name();
|
||||
name.get_name()
|
||||
.map(|name_str| {
|
||||
if name.number > 0 {
|
||||
format!("{}_{}", name_str, name.number)
|
||||
} else {
|
||||
name_str
|
||||
}
|
||||
})
|
||||
.map(|name_str| {
|
||||
name_str
|
||||
.rfind("/")
|
||||
.map(|pos| name_str[(pos + 1)..].to_string())
|
||||
.unwrap_or_else(|| name_str)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_name_or_default(&self) -> String {
|
||||
self.get_name()
|
||||
.unwrap_or_else(|_| "DefaultObjectName".to_string())
|
||||
}
|
||||
|
||||
pub fn get_full_name(&self) -> anyhow::Result<String> {
|
||||
let tmp = self
|
||||
.iter_outer_objects()
|
||||
.map(|obj| obj.get_name())
|
||||
.fold_ok(String::new(), |acc, obj_name| {
|
||||
format!("{}.{}", obj_name, acc)
|
||||
})?;
|
||||
|
||||
Ok(format!(
|
||||
"{} {}{}",
|
||||
self.class()
|
||||
.context("invalid class pointer")?
|
||||
.as_uobject()
|
||||
.get_name_or_default(),
|
||||
tmp,
|
||||
self.get_name_or_default()
|
||||
))
|
||||
}
|
||||
|
||||
pub fn get_full_name_or_default(&self) -> String {
|
||||
self.get_full_name()
|
||||
.unwrap_or_else(|_| "DefaultObjectFullName".to_string())
|
||||
}
|
||||
|
||||
pub fn outer(&self) -> Option<UObject> {
|
||||
unsafe { self.inner.as_ref().outer.map(|inner| UObject::new(inner)) }
|
||||
}
|
||||
|
||||
/// returns the package object of this object
|
||||
pub fn outermost(&self) -> Option<UObject> {
|
||||
self.iter_outer_objects().last()
|
||||
}
|
||||
|
||||
pub fn is_package_object(&self) -> bool {
|
||||
unsafe { self.inner.as_ref().outer.is_none() }
|
||||
}
|
||||
|
||||
pub fn iter_outer_objects(&self) -> OuterObjectIterator {
|
||||
OuterObjectIterator::new(self.clone())
|
||||
}
|
||||
|
||||
pub fn is_a(&self, other: &UClass) -> bool {
|
||||
self.class()
|
||||
.map(|class| class.iter_super_classes().contains(other))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OuterObjectIterator {
|
||||
object: UObject,
|
||||
}
|
||||
|
||||
impl OuterObjectIterator {
|
||||
pub fn new(object: UObject) -> Self {
|
||||
Self { object }
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for OuterObjectIterator {
|
||||
type Item = UObject;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(outer) = self.object.outer() {
|
||||
self.object = outer.clone();
|
||||
|
||||
Some(outer)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UObject> for UClass {
|
||||
fn from(obj: UObject) -> Self {
|
||||
Self::new(obj.inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsUStruct for UClass {
|
||||
fn as_ustruct(&self) -> UStruct {
|
||||
UStruct::new(self.inner.clone().cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<core_types::UClass> for UClass {
|
||||
fn as_ref(&self) -> &core_types::UClass {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRaw<core_types::UClass> for UClass {
|
||||
fn from_non_null(inner: NonNull<core_types::UClass>) -> Self {
|
||||
Self::new(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl UClass {
|
||||
pub fn new(inner: NonNull<core_types::UClass>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
pub fn iter_super_classes(&self) -> SuperClassIter {
|
||||
SuperClassIter::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SuperClassIter {
|
||||
class: UClass,
|
||||
}
|
||||
|
||||
impl SuperClassIter {
|
||||
pub fn new(class: UClass) -> Self {
|
||||
Self { class }
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for SuperClassIter {
|
||||
type Item = UClass;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(next) = self.class.super_struct().map(|spr| spr.as_uobject().into()) {
|
||||
let item = core::mem::replace(&mut self.class, next);
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UObject> for UField {
|
||||
fn from(obj: UObject) -> Self {
|
||||
Self::new(obj.inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl UField {
|
||||
pub fn new(inner: NonNull<core_types::UField>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn maybe_new(inner: Option<NonNull<core_types::UField>>) -> Option<Self> {
|
||||
inner.map(|inner| Self { inner })
|
||||
}
|
||||
|
||||
pub fn maybe_with_raw(raw: *mut core_types::UField) -> Option<Self> {
|
||||
NonNull::new(raw).map(|inner| Self::new(inner))
|
||||
}
|
||||
|
||||
pub fn as_uobject(&self) -> UObject {
|
||||
UObject::new(self.inner.clone().cast())
|
||||
}
|
||||
|
||||
pub unsafe fn as_ref(&self) -> &core_types::UField {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
|
||||
pub fn next(&self) -> Option<Self> {
|
||||
Self::maybe_new(unsafe { self.as_ref().next })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UEnum {
|
||||
inner: NonNull<core_types::UEnum>,
|
||||
}
|
||||
|
||||
impl From<UObject> for UEnum {
|
||||
fn from(obj: UObject) -> Self {
|
||||
Self::new(obj.inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl UEnum {
|
||||
pub fn new(inner: NonNull<core_types::UEnum>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn maybe_new(inner: Option<NonNull<core_types::UEnum>>) -> Option<Self> {
|
||||
inner.map(|inner| Self { inner })
|
||||
}
|
||||
|
||||
pub fn maybe_with_raw(raw: *mut core_types::UEnum) -> Option<Self> {
|
||||
NonNull::new(raw).map(|inner| Self::new(inner))
|
||||
}
|
||||
|
||||
pub fn as_uobject(&self) -> UObject {
|
||||
UObject::new(self.inner.clone().cast())
|
||||
}
|
||||
|
||||
pub unsafe fn as_ref(&self) -> &core_types::UEnum {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
|
||||
pub fn get_names(&self) -> &TArray<FName> {
|
||||
unsafe { &self.as_ref().names }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UStruct {
|
||||
inner: NonNull<core_types::UStruct>,
|
||||
}
|
||||
|
||||
impl From<UObject> for UStruct {
|
||||
fn from(obj: UObject) -> Self {
|
||||
Self::new(obj.inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRaw<core_types::UStruct> for UStruct {
|
||||
fn from_non_null(inner: NonNull<core_types::UStruct>) -> Self {
|
||||
Self::new(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl UStruct {
|
||||
pub fn new(inner: NonNull<core_types::UStruct>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub unsafe fn as_raw(&self) -> &core_types::UStruct {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
|
||||
fn super_struct(&self) -> Option<Self> {
|
||||
Self::from_maybe_non_null(unsafe { self.as_raw().super_field })
|
||||
}
|
||||
|
||||
fn children(&self) -> Option<UField> {
|
||||
UField::maybe_new(unsafe { self.as_raw().children })
|
||||
}
|
||||
|
||||
fn iter_fields(&self) -> Option<UStructFieldIterator> {
|
||||
self.children()
|
||||
.map(|field| UStructFieldIterator::new(field))
|
||||
}
|
||||
}
|
||||
|
||||
impl traits::AsUStruct for UStruct {
|
||||
fn as_ustruct(&self) -> UStruct {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UStructFieldIterator {
|
||||
field: UField,
|
||||
}
|
||||
|
||||
impl UStructFieldIterator {
|
||||
pub fn new(field: UField) -> Self {
|
||||
Self { field }
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for UStructFieldIterator {
|
||||
type Item = UField;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(mut next) = self.field.next() {
|
||||
std::mem::swap(&mut self.field, &mut next);
|
||||
|
||||
Some(next)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UScriptStruct {
|
||||
inner: NonNull<core_types::UStruct>,
|
||||
}
|
||||
|
||||
impl From<UObject> for UScriptStruct {
|
||||
fn from(obj: UObject) -> Self {
|
||||
Self::new(obj.inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl UScriptStruct {
|
||||
pub fn new(inner: NonNull<core_types::UStruct>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn maybe_new(inner: Option<NonNull<core_types::UStruct>>) -> Option<Self> {
|
||||
inner.map(|inner| Self { inner })
|
||||
}
|
||||
|
||||
pub fn maybe_with_raw(raw: *mut core_types::UStruct) -> Option<Self> {
|
||||
NonNull::new(raw).map(|inner| Self::new(inner))
|
||||
}
|
||||
|
||||
pub fn as_uobject(&self) -> UObject {
|
||||
UObject::new(self.inner.clone().cast())
|
||||
}
|
||||
|
||||
pub unsafe fn as_ref(&self) -> &core_types::UStruct {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
|
||||
pub fn iter_fields(&self) -> Option<UStructFieldIterator> {
|
||||
UField::maybe_new(unsafe { self.as_ref().children })
|
||||
.map(|field| UStructFieldIterator::new(field))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UProperty {
|
||||
inner: NonNull<core_types::UProperty>,
|
||||
}
|
||||
|
||||
impl From<UObject> for UProperty {
|
||||
/// WARNING: There is no type check on this conversion, so it is most certainly unsafe
|
||||
fn from(obj: UObject) -> Self {
|
||||
Self::new(obj.inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl UProperty {
|
||||
pub fn new(inner: NonNull<core_types::UProperty>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn maybe_new(inner: Option<NonNull<core_types::UProperty>>) -> Option<Self> {
|
||||
inner.map(|inner| Self { inner })
|
||||
}
|
||||
|
||||
pub fn maybe_with_raw(raw: *mut core_types::UProperty) -> Option<Self> {
|
||||
NonNull::new(raw).map(|inner| Self::new(inner))
|
||||
}
|
||||
|
||||
pub fn as_uobject(&self) -> UObject {
|
||||
UObject::new(self.inner.clone().cast())
|
||||
}
|
||||
|
||||
pub unsafe fn as_ref(&self) -> &core_types::UProperty {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UFunction {
|
||||
inner: NonNull<core_types::UFunction>,
|
||||
}
|
||||
|
||||
impl From<UObject> for UFunction {
|
||||
/// WARNING: There is no type check on this conversion, so it is most certainly unsafe
|
||||
fn from(obj: UObject) -> Self {
|
||||
Self::new(obj.inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
impl UFunction {
|
||||
pub fn new(inner: NonNull<core_types::UFunction>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn maybe_new(inner: Option<NonNull<core_types::UFunction>>) -> Option<Self> {
|
||||
inner.map(|inner| Self { inner })
|
||||
}
|
||||
|
||||
pub fn maybe_with_raw(raw: *mut core_types::UFunction) -> Option<Self> {
|
||||
NonNull::new(raw).map(|inner| Self::new(inner))
|
||||
}
|
||||
|
||||
pub fn as_uobject(&self) -> UObject {
|
||||
UObject::new(self.inner.clone().cast())
|
||||
}
|
||||
|
||||
pub unsafe fn as_ref(&self) -> &core_types::UFunction {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum UAnyType {
|
||||
UObject(UObject),
|
||||
UClass(UClass),
|
||||
UField(UField),
|
||||
UScriptStruct(UScriptStruct),
|
||||
UProperty(UProperty),
|
||||
UEnum(UEnum),
|
||||
UStruct(UStruct),
|
||||
UFunction(UFunction),
|
||||
}
|
||||
|
||||
impl UAnyType {
|
||||
pub fn as_uobject(&self) -> UObject {
|
||||
match self {
|
||||
UAnyType::UObject(rep) => rep.clone(),
|
||||
UAnyType::UClass(rep) => rep.as_uobject(),
|
||||
UAnyType::UField(rep) => rep.as_uobject(),
|
||||
UAnyType::UScriptStruct(rep) => rep.as_uobject(),
|
||||
UAnyType::UProperty(rep) => rep.as_uobject(),
|
||||
UAnyType::UEnum(rep) => rep.as_uobject(),
|
||||
UAnyType::UStruct(rep) => rep.as_uobject(),
|
||||
UAnyType::UFunction(rep) => rep.as_uobject(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for UAnyType {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.as_uobject().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub mod traits {
|
||||
use crate::core_types::FName;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::{OuterObjectIterator, UClass, UField, UObject, UStruct, UStructFieldIterator};
|
||||
|
||||
pub unsafe fn null_ptr_cast<'a, T, U>(ptr: &'a NonNull<T>) -> &'a NonNull<U> {
|
||||
std::mem::transmute(ptr)
|
||||
}
|
||||
|
||||
pub trait AsUObject: Sized {
|
||||
fn as_uobject(&self) -> UObject;
|
||||
|
||||
fn class(&self) -> Option<UClass> {
|
||||
self.as_uobject().class()
|
||||
}
|
||||
|
||||
fn internal_index(&self) -> u32 {
|
||||
self.as_uobject().internal_index()
|
||||
}
|
||||
|
||||
fn name(&self) -> FName {
|
||||
self.as_uobject().name()
|
||||
}
|
||||
|
||||
fn get_name(&self) -> anyhow::Result<String> {
|
||||
self.as_uobject().get_name()
|
||||
}
|
||||
|
||||
fn get_name_or_default(&self) -> String {
|
||||
self.as_uobject().get_name_or_default()
|
||||
}
|
||||
|
||||
fn get_full_name(&self) -> anyhow::Result<String> {
|
||||
self.as_uobject().get_full_name()
|
||||
}
|
||||
|
||||
fn get_full_name_or_default(&self) -> String {
|
||||
self.as_uobject().get_full_name_or_default()
|
||||
}
|
||||
|
||||
fn outer(&self) -> Option<UObject> {
|
||||
self.as_uobject().outer()
|
||||
}
|
||||
|
||||
fn outermost(&self) -> Option<UObject> {
|
||||
self.as_uobject().outermost()
|
||||
}
|
||||
|
||||
fn is_package_object(&self) -> bool {
|
||||
self.as_uobject().is_package_object()
|
||||
}
|
||||
|
||||
fn iter_outer_objects(&self) -> OuterObjectIterator {
|
||||
OuterObjectIterator::new(self.as_uobject())
|
||||
}
|
||||
|
||||
fn is_a(&self, other: &UClass) -> bool {
|
||||
self.class()
|
||||
.map(|class| class.iter_super_classes().contains(other))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AsUStruct {
|
||||
fn as_ustruct(&self) -> UStruct;
|
||||
|
||||
#[inline]
|
||||
fn children(&self) -> Option<UField> {
|
||||
self.as_ustruct().children()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn super_struct(&self) -> Option<UStruct> {
|
||||
self.as_ustruct().super_struct()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn iter_fields(&self) -> Option<UStructFieldIterator> {
|
||||
self.children()
|
||||
.map(|field| UStructFieldIterator::new(field))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsUObject for T
|
||||
where
|
||||
T: AsUStruct,
|
||||
{
|
||||
fn as_uobject(&self) -> UObject {
|
||||
UObject::new(self.as_ustruct().inner.cast())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FromRaw<R> {
|
||||
fn from_non_null(inner: NonNull<R>) -> Self;
|
||||
|
||||
fn from_raw(raw: *mut R) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
NonNull::new(raw).map(|inner| Self::from_non_null(inner))
|
||||
}
|
||||
|
||||
fn from_maybe_non_null(inner: Option<NonNull<R>>) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
inner.map(|inner| Self::from_non_null(inner))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue