using pointer types now for every coreuobject type
This commit is contained in:
parent
724939e5da
commit
f8f183c420
|
@ -1,6 +1,6 @@
|
||||||
use std::{ops::Index, ptr::NonNull, sync::RwLock};
|
use std::{ops::Index, ptr::NonNull, sync::RwLock};
|
||||||
|
|
||||||
use crate::core_types::FName;
|
use crate::fname::FName;
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref GNAMES: RwLock<GNames> = RwLock::new(GNames::new());
|
pub static ref GNAMES: RwLock<GNames> = RwLock::new(GNames::new());
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use std::{ops::Index, ptr::NonNull, sync::RwLock};
|
use std::{cell::UnsafeCell, ops::Index, ptr::NonNull, sync::RwLock};
|
||||||
|
|
||||||
use rayon::prelude::ParallelIterator;
|
use rayon::prelude::ParallelIterator;
|
||||||
|
|
||||||
use crate::types;
|
use crate::v2_types::{
|
||||||
|
self,
|
||||||
|
traits::{AsUObject, UObjectTrait},
|
||||||
|
};
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref GOBJECTS: RwLock<GObjects> = RwLock::new(GObjects::new());
|
pub static ref GOBJECTS: RwLock<GObjects> = RwLock::new(GObjects::new());
|
||||||
|
@ -10,7 +13,7 @@ lazy_static::lazy_static! {
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct GObjects {
|
pub struct GObjects {
|
||||||
objects: Option<NonNull<ObjectArray>>,
|
objects: Option<NonNull<UnsafeCell<ObjectArray>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GObjects {
|
impl GObjects {
|
||||||
|
@ -19,11 +22,12 @@ impl GObjects {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_objects(&mut self, objects: NonNull<ObjectArray>) {
|
pub fn set_objects(&mut self, objects: NonNull<ObjectArray>) {
|
||||||
self.objects = Some(objects);
|
self.objects = Some(objects.cast());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_objects(&self) -> Option<&ObjectArray> {
|
pub fn as_objects(&self) -> Option<&ObjectArray> {
|
||||||
self.objects.map(|objects| unsafe { objects.as_ref() })
|
self.objects
|
||||||
|
.map(|objects| unsafe { &*objects.as_ref().get() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +37,7 @@ unsafe impl Sync for GObjects {}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ObjectArrayItem {
|
pub struct ObjectArrayItem {
|
||||||
object: Option<NonNull<crate::core_types::UObject>>,
|
object: Option<v2_types::UObject>,
|
||||||
sn: u32,
|
sn: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +45,8 @@ unsafe impl Send for ObjectArrayItem {}
|
||||||
unsafe impl Sync for ObjectArrayItem {}
|
unsafe impl Sync for ObjectArrayItem {}
|
||||||
|
|
||||||
impl ObjectArrayItem {
|
impl ObjectArrayItem {
|
||||||
pub fn object(&self) -> Option<types::UObject> {
|
pub fn object(&self) -> Option<v2_types::UObject> {
|
||||||
types::UObject::maybe_new(self.object)
|
self.object
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,22 +237,28 @@ pub mod par_iter {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FindClass {
|
pub trait FindClass {
|
||||||
fn find_class<S>(&self, class_name: S) -> Option<types::UClass>
|
fn find_class<S>(&self, class_name: S) -> Option<v2_types::UClass>
|
||||||
where
|
where
|
||||||
S: Into<String>;
|
S: Into<String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FindClass for ObjectArray {
|
impl FindClass for ObjectArray {
|
||||||
fn find_class<S>(&self, class_name: S) -> Option<types::UClass>
|
fn find_class<S>(&self, class_name: S) -> Option<v2_types::UClass>
|
||||||
where
|
where
|
||||||
S: Into<String>,
|
S: Into<String>,
|
||||||
{
|
{
|
||||||
|
use crate::v2_types::traits::UObjectNonConst;
|
||||||
let class_name = class_name.into();
|
let class_name = class_name.into();
|
||||||
|
|
||||||
self.iter()
|
self.iter()
|
||||||
.filter_map(|item| item.object())
|
.filter_map(|item| item.object())
|
||||||
.filter(|object| object.get_full_name().unwrap() == class_name)
|
.filter(|object| {
|
||||||
.map(|object| types::UClass::new(unsafe { object.cast() }))
|
object
|
||||||
|
.get_full_name()
|
||||||
|
.map(|name| name == class_name)
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|object| (unsafe { object.cast() }))
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
43
src/lib.rs
43
src/lib.rs
|
@ -1,10 +1,10 @@
|
||||||
#![feature(const_trait_impl, const_ptr_as_ref, const_nonnull_new)]
|
#![feature(const_trait_impl, const_ptr_as_ref, const_nonnull_new)]
|
||||||
|
|
||||||
mod core_types;
|
// mod core_types;
|
||||||
pub mod fname;
|
pub mod fname;
|
||||||
pub mod global_tables;
|
pub mod global_tables;
|
||||||
pub mod tarray;
|
pub mod tarray;
|
||||||
pub mod types;
|
// pub mod types;
|
||||||
pub mod v2_types;
|
pub mod v2_types;
|
||||||
|
|
||||||
pub mod sdk {
|
pub mod sdk {
|
||||||
|
@ -19,17 +19,12 @@ pub mod sdk {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
global_tables::objects::{FindClass, GOBJECTS},
|
global_tables::objects::{FindClass, GOBJECTS},
|
||||||
types::{traits::AsUObject, UAnyType, UClass, UEnum, UObject},
|
v2_types::{
|
||||||
|
traits::{AsUObject, UEnumTrait, UObjectNonConst, UObjectTrait},
|
||||||
|
UAnyType, UClass, UEnum, UObject,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const UOBJECT: &'static str = "Class CoreUObject.Object";
|
|
||||||
pub const UCLASS: &'static str = "Class CoreUObject.Class";
|
|
||||||
pub const UFUNCTION: &'static str = "Class CoreUObject.Function";
|
|
||||||
pub const UFIELD: &'static str = "Class CoreUObject.Field";
|
|
||||||
pub const UENUM: &'static str = "Class CoreUObject.Enum";
|
|
||||||
pub const USTRUCT: &'static str = "Class CoreUObject.Struct";
|
|
||||||
pub const USCRIPTSTRUCT: &'static str = "Class CoreUObject.ScriptStruct";
|
|
||||||
|
|
||||||
struct ClassCache {
|
struct ClassCache {
|
||||||
classes: Mutex<HashMap<String, UClass>>,
|
classes: Mutex<HashMap<String, UClass>>,
|
||||||
}
|
}
|
||||||
|
@ -41,24 +36,6 @@ pub mod sdk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identify_uobject(&self, object: UObject) -> UAnyType {
|
|
||||||
if object.is_a(&self.find_class(UENUM).expect("uenum")) {
|
|
||||||
UAnyType::UEnum(object.into())
|
|
||||||
} else if object.is_a(&self.find_class(UFIELD).expect("ufield")) {
|
|
||||||
UAnyType::UField(object.into())
|
|
||||||
} else if object.is_a(&self.find_class(USTRUCT).expect("ustruct")) {
|
|
||||||
UAnyType::UStruct(object.into())
|
|
||||||
} else if object.is_a(&self.find_class(UFUNCTION).expect("ufunction")) {
|
|
||||||
UAnyType::UFunction(object.into())
|
|
||||||
} else if object.is_a(&self.find_class(UCLASS).expect("uclass")) {
|
|
||||||
UAnyType::UClass(object.into())
|
|
||||||
} else if object.is_a(&self.find_class(USCRIPTSTRUCT).expect("uscriptstruct")) {
|
|
||||||
UAnyType::UScriptStruct(object.into())
|
|
||||||
} else {
|
|
||||||
UAnyType::UObject(object)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cache_class(&mut self, class: UClass) -> anyhow::Result<()> {
|
pub fn cache_class(&mut self, class: UClass) -> anyhow::Result<()> {
|
||||||
let name = class.get_full_name()?;
|
let name = class.get_full_name()?;
|
||||||
self.classes.lock().unwrap().insert(name, class);
|
self.classes.lock().unwrap().insert(name, class);
|
||||||
|
@ -109,7 +86,7 @@ pub mod sdk {
|
||||||
// ensure item contains object
|
// ensure item contains object
|
||||||
.filter_map(|item| item.object())
|
.filter_map(|item| item.object())
|
||||||
// get package object
|
// get package object
|
||||||
.filter_map(|obj| obj.outermost().map(|pkg| (pkg, obj)))
|
.map(|obj| (obj.package_object(), obj))
|
||||||
.fold(
|
.fold(
|
||||||
HashMap::<UObject, Vec<UObject>>::new(),
|
HashMap::<UObject, Vec<UObject>>::new(),
|
||||||
|mut acc, (pkg, obj)| {
|
|mut acc, (pkg, obj)| {
|
||||||
|
@ -153,7 +130,7 @@ pub mod sdk {
|
||||||
.cache_class(object.class().expect("object had no class?"))
|
.cache_class(object.class().expect("object had no class?"))
|
||||||
.context("object not of any base type?")?;
|
.context("object not of any base type?")?;
|
||||||
|
|
||||||
let ty = cache.identify_uobject(object);
|
let ty = UAnyType::from_uobject(object.as_uobject());
|
||||||
log::debug!("ty: {ty:?}");
|
log::debug!("ty: {ty:?}");
|
||||||
|
|
||||||
match ty {
|
match ty {
|
||||||
|
@ -161,13 +138,11 @@ pub mod sdk {
|
||||||
UAnyType::UClass(_) => {}
|
UAnyType::UClass(_) => {}
|
||||||
UAnyType::UField(_) => {}
|
UAnyType::UField(_) => {}
|
||||||
UAnyType::UScriptStruct(_) => {}
|
UAnyType::UScriptStruct(_) => {}
|
||||||
UAnyType::UProperty(_) => {}
|
|
||||||
UAnyType::UEnum(obj) => {
|
UAnyType::UEnum(obj) => {
|
||||||
let enm = Self::process_enum(obj)?;
|
let enm = Self::process_enum(obj)?;
|
||||||
log::info!("enum: {enm}");
|
log::info!("enum: {enm}");
|
||||||
}
|
}
|
||||||
UAnyType::UStruct(_) => {}
|
UAnyType::UStruct(_) => {}
|
||||||
UAnyType::UFunction(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +152,7 @@ pub mod sdk {
|
||||||
fn process_enum(enm: UEnum) -> anyhow::Result<Enum> {
|
fn process_enum(enm: UEnum) -> anyhow::Result<Enum> {
|
||||||
// get all the variants
|
// get all the variants
|
||||||
let values = enm
|
let values = enm
|
||||||
.get_names()
|
.names()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
// canonicalize the names into valid rust
|
// canonicalize the names into valid rust
|
||||||
|
|
|
@ -6,7 +6,13 @@
|
||||||
//! that the contents might very well change under its feet (which they might).
|
//! that the contents might very well change under its feet (which they might).
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use std::{cell::UnsafeCell, marker::PhantomData, ptr::NonNull};
|
use std::{
|
||||||
|
cell::UnsafeCell,
|
||||||
|
fmt::{Debug, Display},
|
||||||
|
hash::Hash,
|
||||||
|
marker::PhantomData,
|
||||||
|
ptr::NonNull,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -178,14 +184,33 @@ define_utypes!(
|
||||||
UEnumProperty where UFieldTrait, UStructTrait, UPropertyTrait,UEnumPropertyTrait => "EnumProperty"
|
UEnumProperty where UFieldTrait, UStructTrait, UPropertyTrait,UEnumPropertyTrait => "EnumProperty"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl Hash for UObject {
|
||||||
|
fn hash<H: ~const std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.0.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for UObject {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "UObject {{")?;
|
||||||
|
writeln!(f, "\tvtbl: {:?}", self.vtbl())?;
|
||||||
|
writeln!(f, "\tobject_flags{:?}", self.object_flags())?;
|
||||||
|
writeln!(f, "\tinternal_index{:?}", self.internal_index())?;
|
||||||
|
writeln!(f, "\tclass{:?}", self.class())?;
|
||||||
|
writeln!(f, "\tname{:?}", &self.get_name_or_default())?;
|
||||||
|
writeln!(f, "\touter{:?}", self.outer())?;
|
||||||
|
writeln!(f, "}}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl UObject {
|
impl UObject {
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
const fn raw_ptr(&self) -> *const () {
|
const fn raw_ptr(&self) -> *const u8 {
|
||||||
unsafe { self.0.as_ref().get() as _ }
|
unsafe { self.0.as_ref().get() as _ }
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn raw_mut(&self) -> *mut () {
|
const fn raw_mut(&self) -> *mut u8 {
|
||||||
unsafe { self.0.as_ref().get() as _ }
|
unsafe { self.0.as_ref().get() as _ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,8 +341,61 @@ impl<'a> Iterator for ChildIter<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum UAnyType {
|
||||||
|
UObject(UObject),
|
||||||
|
UClass(UClass),
|
||||||
|
UField(UField),
|
||||||
|
UScriptStruct(UScriptStruct),
|
||||||
|
UEnum(UEnum),
|
||||||
|
UStruct(UStruct),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UAnyType {
|
||||||
|
pub fn from_uobject(uobject: UObject) -> Self {
|
||||||
|
// remember to order this from most specialized to least.
|
||||||
|
// specifically: a UClass is also a UStruct, so check for UClass first,
|
||||||
|
// then for any other subtypes of UStruct, then for UStruct
|
||||||
|
if uobject.is_a(&UEnum::static_class()) {
|
||||||
|
Self::UEnum(unsafe { uobject.cast() })
|
||||||
|
} else if uobject.is_a(&UClass::static_class()) {
|
||||||
|
Self::UClass(unsafe { uobject.cast() })
|
||||||
|
} else if uobject.is_a(&UScriptStruct::static_class()) {
|
||||||
|
Self::UScriptStruct(unsafe { uobject.cast() })
|
||||||
|
} else if uobject.is_a(&UStruct::static_class()) {
|
||||||
|
Self::UStruct(unsafe { uobject.cast() })
|
||||||
|
} else if uobject.is_a(&UField::static_class()) {
|
||||||
|
Self::UField(unsafe { uobject.cast() })
|
||||||
|
} else {
|
||||||
|
Self::UObject(uobject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsUObject for UAnyType {
|
||||||
|
fn as_uobject(&self) -> self::UObject {
|
||||||
|
match self {
|
||||||
|
UAnyType::UObject(obj) => obj.as_uobject(),
|
||||||
|
UAnyType::UClass(obj) => obj.as_uobject(),
|
||||||
|
UAnyType::UField(obj) => obj.as_uobject(),
|
||||||
|
UAnyType::UScriptStruct(obj) => obj.as_uobject(),
|
||||||
|
UAnyType::UEnum(obj) => obj.as_uobject(),
|
||||||
|
UAnyType::UStruct(obj) => obj.as_uobject(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_raw(raw: *mut ()) -> Option<Self> {
|
||||||
|
UObject::from_raw(raw).map(|obj| Self::from_uobject(obj))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_nonnull(raw: NonNull<UnsafeCell<()>>) -> Self {
|
||||||
|
Self::from_uobject(UObject::from_nonnull(raw))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use traits::*;
|
use traits::*;
|
||||||
mod traits {
|
pub mod traits {
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
@ -338,17 +416,13 @@ mod traits {
|
||||||
static CLASS: OnceCell<super::UClass> = OnceCell::new();
|
static CLASS: OnceCell<super::UClass> = OnceCell::new();
|
||||||
|
|
||||||
*CLASS.get_or_init(|| {
|
*CLASS.get_or_init(|| {
|
||||||
super::UClass(
|
GOBJECTS
|
||||||
GOBJECTS
|
.read()
|
||||||
.read()
|
.unwrap()
|
||||||
.unwrap()
|
.as_objects()
|
||||||
.as_objects()
|
.unwrap()
|
||||||
.unwrap()
|
.find_class(Self::static_class_name())
|
||||||
.find_class(Self::static_class_name())
|
.expect("static class not found!")
|
||||||
.expect("static class not found!")
|
|
||||||
.inner
|
|
||||||
.cast(),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue