variable sized strings
I have the follow structure I want to define as a node. int32 - defining the length of a string string - with the size of the previous int.
I've tried this in a plugin. But the MemorySize don't seem to update when it reads the first int and figures out how long the string is.
class MyString : BaseNode
{
private int length;
public override int MemorySize => sizeof(int) + Encoding.UTF8.GuessByteCountPerChar() * length;
// This does nothing?
public override void Update(HotSpot spot)
{
base.Update(spot);
if (spot.Id == 0)
{
length = spot.Memory.ReadInt32(Offset);
}
}
public override Size Draw(ViewInfo view, int x, int y)
{
...
length = view.Memory.ReadInt32(Offset);
var text = view.Memory.ReadString(Encoding.UTF8, Offset + sizeof(int), length);
...
}
}
Could you show the C++ source of the MyString class?
It's C#, but here's the whole thing. I just removed the stuff i figured was irrelevant
using ReClassNET.Extensions;
using ReClassNET.Memory;
using ReClassNET.Nodes;
using ReClassNET.UI;
using System.Drawing;
using System.Text;
namespace SamplePluginManaged.Nodes
{
class UpkString : BaseNode
{
private int length;
public override int MemorySize => sizeof(int) + Encoding.UTF8.GuessByteCountPerChar() * length;
public override void GetUserInterfaceInfo(out string name, out Image icon)
{
name = "UpkString";
icon = null;
}
public override void Update(HotSpot spot)
{
base.Update(spot);
if (spot.Id == 0)
{
length = spot.Memory.ReadInt32(Offset);
}
}
public override Size Draw(ViewInfo view, int x, int y)
{
if (IsHidden && !IsWrapped)
{
return DrawHidden(view, x, y);
}
length = view.Memory.ReadInt32(Offset);
var text = view.Memory.ReadString(Encoding.UTF8, Offset + sizeof(int), length);
var origX = x;
AddSelection(view, x, y, view.Font.Height);
x += TextPadding;
x = AddIcon(view, x, y, Icons.Text, HotSpot.NoneId, HotSpotType.None);
x = AddAddressOffset(view, x, y);
x = AddText(view, x, y, view.Settings.TypeColor, HotSpot.NoneId, "UpkString") + view.Font.Width;
x = AddText(view, x, y, view.Settings.NameColor, HotSpot.NameId, Name) + view.Font.Width;
x = AddText(view, x, y, view.Settings.TextColor, HotSpot.NoneId, "= '");
x = AddText(view, x, y, view.Settings.TextColor, HotSpot.NoneId, text);
x = AddText(view, x, y, view.Settings.TextColor, HotSpot.NoneId, "'") + view.Font.Width;
x = AddComment(view, x, y);
DrawInvalidMemoryIndicatorIcon(view, y);
AddContextDropDownIcon(view, y);
AddDeleteIcon(view, y);
return new Size(x - origX, view.Font.Height);
}
public override int CalculateDrawnHeight(ViewInfo view)
{
return IsHidden && !IsWrapped ? HiddenHeight : view.Font.Height;
}
}
}
You misunderstood me. I want to see the code of the class you try to display in ReClass. Looks like UpkString is a class of the Unreal Engine?
Well. It's mostly a datafile. So I'm using the binary file plugin. UPK is a file format from the udk engine.
There's a lot of instances where there's first a int that defines the length of what follows. So I need to know how to define that as nodes..
The picture above is trivial. Later on there are long tables of these types of strings. Where it would be unfeasible to manually define the string lengths.
I've attached an example of the datafile
I'm afraid that's not possible with ReClass because the node size can't change at runtime. This limitation isn't a problem for the normal functionality because a compiled class can't change at runtime. The binary file plugin was just a demonstration what could be done. You found a use case which could not be done. You should use a real binary editor like https://www.sweetscape.com/010editor/ whichs supports this.
Is this a fundamental limitation to ReClass. Or something that could be solved? If it would be possible to have a node constructor with access to the memory, we could read the size on creation. Is this within the realm of possibility?
untested
public override Size Draw(ViewInfo view, int x, int y)
{
//...
var length = view.Memory.ReadInt32(Offset);
if (this->length != length)
{
this->length = length;
GetParentContainer()?.ChildHasChanged(this);
}
var text = view.Memory.ReadString(Encoding.UTF8, Offset + sizeof(int), length);
//...
}
It's a workaround and I don't want to list all the bad consequences here. 😄