unreal-sdk/src/sdk/repr.rs

212 lines
5.2 KiB
Rust

use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use crate::v2_types::{
traits::{UObjectNonConst, UObjectTrait},
EFunctionFlags, EPropertyFlags, UObject,
};
impl UObject {
pub fn as_package_ref(&self) -> Option<PackageRef> {
if self.is_package_object() {
Some(PackageRef(*self.internal_index()))
} else {
None
}
}
pub fn object_ref(&self) -> ObjectRef {
ObjectRef {
package: PackageRef(*self.package_object().internal_index()),
object: *self.internal_index(),
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize)]
pub struct PackageRef(u32);
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize)]
pub struct ObjectRef {
pub package: PackageRef,
pub object: u32,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Sdk {
packages: BTreeMap<PackageRef, ProcessedPackage>,
}
/// A package represents some group of packages that are related to another,
/// examples in ARK are `Engine`, `ShooterGame`, `SlateCore` or
/// `Buff_Companion_HLNA`.
#[derive(Debug)]
pub struct Package {
/// the package object is the root object of the package.
pub package_object: UObject,
/// each package may contain other objects and classes which can be
/// referenced by an `ObjectRef`, which is a unique identifier for each
/// object.
pub children: Vec<UObject>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ProcessedPackage {
/// the package object ref.
pub package_object: PackageRef,
/// all types extracted from this package referenced by their `ObjectRef`.
pub types: BTreeMap<ObjectRef, UnrealType>,
/// All other packages that types in this package depend on directly.
pub dependencies: Vec<ObjectRef>,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum UnrealType {
Class(Class),
Struct(Class),
Actor(Class),
Enum(Enum),
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum StructKind {
Object,
Actor,
Struct,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Enum {
pub name: String,
pub full_name: String,
pub values: BTreeMap<u32, String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Class {
pub kind: StructKind,
pub size: u32,
pub name: String,
pub full_name: String,
pub super_class: Option<ObjectRef>,
pub properties_size: u32,
pub min_alignment: u32,
pub fields: Vec<ClassField>,
pub methods: Vec<ClassMethod>,
/// types this class depends on; includes super types, types of fields and
/// types of function parameters.
pub dependencies: Vec<ObjectRef>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ClassField {
pub offset: u32,
pub size: u32,
pub name: String,
pub flags: EPropertyFlags,
pub ty: Type,
}
impl ClassField {
pub fn is_return_param(&self) -> bool {
self.flags.contains(EPropertyFlags::ReturnParm)
}
pub fn is_param(&self) -> bool {
self.flags.contains(EPropertyFlags::Parm)
}
pub fn is_const_param(&self) -> bool {
self.flags.contains(EPropertyFlags::ConstParm)
}
pub fn is_out_param(&self) -> bool {
!self.is_const_param() && self.flags.contains(EPropertyFlags::OutParm)
}
pub fn is_rep(&self) -> bool {
!self.flags.contains(EPropertyFlags::RepSkip)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ClassMethod {
pub name: String,
pub full_name: String,
pub flags: EFunctionFlags,
pub parameters: Vec<ClassField>,
}
impl ClassMethod {
pub fn is_static(&self) -> bool {
self.flags.contains(EFunctionFlags::Static)
}
pub fn is_native(&self) -> bool {
self.flags.contains(EFunctionFlags::Native)
}
/// this function is replicated to the server, might be exploitable.
pub fn is_net_server(&self) -> bool {
self.flags.contains(EFunctionFlags::NetServer)
}
pub fn out_params(&self) -> Vec<&ClassField> {
self.parameters
.iter()
.filter(|&param| param.is_out_param() || param.is_return_param())
.collect::<Vec<_>>()
}
pub fn in_params(&self) -> Vec<&ClassField> {
self.parameters
.iter()
.filter(|param| param.is_param() && !(param.is_out_param() || param.is_return_param()))
.collect::<Vec<_>>()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PrimitiveType {
Bool {
byte_mask: u8,
field_mask: u8,
byte_offset: u8,
field_size: u8,
},
U8,
U16,
U32,
U64,
I8,
I16,
I32,
I64,
F32,
F64,
Custom(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Type {
Ptr(Box<Type>),
Ref(Box<Type>),
WeakPtr(ObjectRef),
SoftPtr(ObjectRef),
LazyPtr(ObjectRef),
AssetPtr(ObjectRef),
Array(Box<Type>),
Primitive(PrimitiveType),
RawArray {
ty: Box<Type>,
len: u32,
},
Name,
String,
Text,
Enum {
underlying: Box<Type>,
enum_type: ObjectRef,
},
Class(ObjectRef),
Struct(ObjectRef),
}