From b3106dd1767c3e728fc5c26295c6c6726ac1957d Mon Sep 17 00:00:00 2001 From: ShadelessFox Date: Mon, 19 Sep 2022 01:05:22 +0300 Subject: [PATCH] Attempt to read invalid core entries as the `RTTIRefObject` --- .../shade/decima/model/base/CoreBinary.java | 33 +++++++++---------- .../shade/decima/model/rtti/RTTIUtils.java | 20 +++++++++-- .../decima/ui/editor/core/CoreNodeEntry.java | 5 +-- .../decima/ui/editor/core/CoreNodeObject.java | 2 +- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/shade/decima/model/base/CoreBinary.java b/src/main/java/com/shade/decima/model/base/CoreBinary.java index c11c9e84c..9ef33b729 100644 --- a/src/main/java/com/shade/decima/model/base/CoreBinary.java +++ b/src/main/java/com/shade/decima/model/base/CoreBinary.java @@ -1,6 +1,5 @@ package com.shade.decima.model.base; -import com.shade.decima.model.rtti.RTTIType; import com.shade.decima.model.rtti.RTTIUtils; import com.shade.decima.model.rtti.objects.RTTIObject; import com.shade.decima.model.rtti.registry.RTTITypeRegistry; @@ -29,33 +28,31 @@ public static CoreBinary from(@NotNull byte[] data, @NotNull RTTITypeRegistry re final int size = buffer.getInt(); final ByteBuffer slice = buffer.slice(buffer.position(), size).order(ByteOrder.LITTLE_ENDIAN); - // It doesn't seem that this is the best place for handling the `lenient` option. - // We need to figure a better way to display unknown or incomplete entries in UI. + RTTITypeClass type; + RTTIObject entry; try { - final RTTIType type = registry.find(id); - final RTTIObject entry = (RTTIObject) type.read(registry, slice); - - if (slice.remaining() > 0) { - final Byte[] remaining = IOUtils.box(IOUtils.getBytesExact(slice, slice.remaining())); - entry.define("$Remaining", registry.find("Array"), remaining); - } - - entries.add(entry); + type = (RTTITypeClass) registry.find(id); + entry = type.read(registry, slice); } catch (Exception e) { if (!lenient) { throw e; } - final Byte[] remaining = IOUtils.box(IOUtils.getBytesExact(slice, slice.position(0).remaining())); - final RTTIObject entry = RTTIUtils.newClassBuilder(registry, "UnknownEntry<%8x>".formatted(id)) - .member("Data", "Array") - .build().instantiate(); + entry = null; + } + + if (entry == null) { + type = RTTIUtils.newClassBuilder(registry, "RTTIRefObject", "UnknownEntry<%8x>".formatted(id)).build(); + entry = type.read(registry, slice); + } - entry.set("Data", remaining); - entries.add(entry); + if (slice.remaining() > 0) { + final Byte[] remaining = IOUtils.box(IOUtils.getBytesExact(slice, slice.remaining())); + entry.define("$Remaining", registry.find("Array"), remaining); } + entries.add(entry); buffer.position(buffer.position() + size); } diff --git a/src/main/java/com/shade/decima/model/rtti/RTTIUtils.java b/src/main/java/com/shade/decima/model/rtti/RTTIUtils.java index 71d1034a3..997a4dd19 100644 --- a/src/main/java/com/shade/decima/model/rtti/RTTIUtils.java +++ b/src/main/java/com/shade/decima/model/rtti/RTTIUtils.java @@ -3,6 +3,7 @@ import com.shade.decima.model.rtti.registry.RTTITypeRegistry; import com.shade.decima.model.rtti.types.RTTITypeClass; import com.shade.util.NotNull; +import com.shade.util.Nullable; import java.lang.reflect.Array; import java.nio.ByteBuffer; @@ -19,6 +20,11 @@ public static ClassBuilder newClassBuilder(@NotNull RTTITypeRegistry registry, @ return new ClassBuilder(registry, name); } + @NotNull + public static ClassBuilder newClassBuilder(@NotNull RTTITypeRegistry registry, @NotNull String base, @NotNull String name) { + return new ClassBuilder(registry, (RTTITypeClass) registry.find(base), name); + } + @SuppressWarnings("unchecked") @NotNull public static T[] readCollection(@NotNull RTTITypeRegistry registry, @NotNull ByteBuffer buffer, @NotNull RTTIType type, int count) { @@ -32,14 +38,20 @@ public static T[] readCollection(@NotNull RTTITypeRegistry registry, @NotNul public static class ClassBuilder { private final RTTITypeRegistry registry; private final String name; + private final RTTITypeClass base; private final Map> members; - public ClassBuilder(@NotNull RTTITypeRegistry registry, @NotNull String name) { + public ClassBuilder(@NotNull RTTITypeRegistry registry, @Nullable RTTITypeClass base, @NotNull String name) { this.registry = registry; this.name = name; + this.base = base; this.members = new LinkedHashMap<>(); } + public ClassBuilder(@NotNull RTTITypeRegistry registry, @NotNull String name) { + this(registry, null, name); + } + @NotNull public ClassBuilder member(@NotNull String name, @NotNull String type) { return member(name, registry.find(type)); @@ -54,13 +66,17 @@ public ClassBuilder member(@NotNull String name, @NotNull RTTIType type) { @NotNull public RTTITypeClass build() { final RTTITypeClass clazz = new RTTITypeClass(name, - new RTTITypeClass.Base[0], + new RTTITypeClass.Base[base != null ? 1 : 0], new RTTITypeClass.Member[members.size()], Collections.emptyMap(), 0, 0 ); + if (base != null) { + clazz.getBases()[0] = new RTTITypeClass.Base(clazz, base, 0); + } + final RTTITypeClass.Member[] members = this.members.entrySet().stream() .map(info -> new RTTITypeClass.Member(clazz, info.getValue(), info.getKey(), "", 0, 0)) .toArray(RTTITypeClass.Member[]::new); diff --git a/src/main/java/com/shade/decima/ui/editor/core/CoreNodeEntry.java b/src/main/java/com/shade/decima/ui/editor/core/CoreNodeEntry.java index 608da8b23..fcf2e1084 100644 --- a/src/main/java/com/shade/decima/ui/editor/core/CoreNodeEntry.java +++ b/src/main/java/com/shade/decima/ui/editor/core/CoreNodeEntry.java @@ -6,16 +6,13 @@ import com.shade.util.NotNull; public class CoreNodeEntry extends CoreNodeObject { - private final RTTIObject objectUUID; - public CoreNodeEntry(@NotNull CoreNodeBinary parent, @NotNull RTTIObject object) { super(parent, object.getType(), object, RTTITypeRegistry.getFullTypeName(object.getType()), new PathElementUUID(object.get("ObjectUUID"))); - this.objectUUID = object.get("ObjectUUID"); } @NotNull public RTTIObject getObjectUUID() { - return objectUUID; + return getObject().get("ObjectUUID"); } @NotNull diff --git a/src/main/java/com/shade/decima/ui/editor/core/CoreNodeObject.java b/src/main/java/com/shade/decima/ui/editor/core/CoreNodeObject.java index c75893002..7afe787ed 100644 --- a/src/main/java/com/shade/decima/ui/editor/core/CoreNodeObject.java +++ b/src/main/java/com/shade/decima/ui/editor/core/CoreNodeObject.java @@ -20,7 +20,7 @@ public class CoreNodeObject extends TreeNodeLazy { private final PathElement element; private Object object; - public CoreNodeObject(@NotNull TreeNode parent, @NotNull RTTIType type, @NotNull Object object, @NotNull String name, PathElement element) { + public CoreNodeObject(@NotNull TreeNode parent, @NotNull RTTIType type, @NotNull Object object, @NotNull String name, @NotNull PathElement element) { super(parent); this.type = type; this.handler = ValueHandlerProvider.getValueHandler(type);