C
C#2mo ago
LudoCrypt

Can I add a field to compiled class?

I'm making a mod for a game and I need to give a class some extra information. I don't have access to how its constructed so I can't do type building. I can't replace dll's because this is a plugin. Is what I need to do possible with those restrictions?
19 Replies
Jimmacle
Jimmacle2mo ago
do you actually need to modify the class or do you just need to associate information with it?
LudoCrypt
LudoCrypt2mo ago
I need to give it a variable so i can use it inside the class. I have a thing for like hooking into a method to add code to it, and I need to do that, but I need to use a variable specific to the class
Jimmacle
Jimmacle2mo ago
ConditionalWeakTable Class (System.Runtime.CompilerServices)
Enables compilers to dynamically attach object fields to managed objects.
Jimmacle
Jimmacle2mo ago
it's like a dictionary that automatically cleans up entries when the key is GCed
LudoCrypt
LudoCrypt2mo ago
I KNEW TGHERE WAS A BETTER WAY TO DO THAT thank you
Jimmacle
Jimmacle2mo ago
so instead of modifying the class directly you can use one of these and for each class add an entry with the class as the key and your custom data as the value i'd personally write some extension methods to make it more convenient to use like int GetMyInt(this ClassICantModify obj)
LudoCrypt
LudoCrypt2mo ago
Where would I put that
Jimmacle
Jimmacle2mo ago
sec, i'll wite a more thorough example
public class MyExtraData
{
public string MyString { get; set; }
public int MyInt { get; set; }
}

public static class ClassExtendedData
{
private static readonly ConditionalWeakTable<object, MyExtraData> Table = new();

public static MyExtraData GetMyExtraData(this object obj)
{
if (Table.TryGetValue(obj, out var data))
return data;

data = new MyExtraData();
Table.Add(obj, data);
return data;
}
}
public class MyExtraData
{
public string MyString { get; set; }
public int MyInt { get; set; }
}

public static class ClassExtendedData
{
private static readonly ConditionalWeakTable<object, MyExtraData> Table = new();

public static MyExtraData GetMyExtraData(this object obj)
{
if (Table.TryGetValue(obj, out var data))
return data;

data = new MyExtraData();
Table.Add(obj, data);
return data;
}
}
then you'd use this inside the class you're patching like
var myExtraData = this.GetMyExtraData()
var myExtraData = this.GetMyExtraData()
LudoCrypt
LudoCrypt2mo ago
ohhh okay tysm
jcotton42
jcotton422mo ago
is CWT thread safe? ah yep
jcotton42
jcotton422mo ago
ConditionalWeakTable.GetOrCreateValue(TKey) Method (System.Runtime....
Atomically searches for a specified key in the table and returns the corresponding value. If the key does not exist in the table, the method invokes the parameterless constructor of the class that represents the table's value to create a value that is bound to the specified key.
jcotton42
jcotton422mo ago
rather than a separate check then add
Jimmacle
Jimmacle2mo ago
ah, yeah i just did it from limited memory of using it years ago
LudoCrypt
LudoCrypt2mo ago
ohh that might explain why the screen kept going black
Jimmacle
Jimmacle2mo ago
dunno about that, but it's more correct either way it only really affects the first time it's accessed
LudoCrypt
LudoCrypt2mo ago
well it only happens when i call the get data method so iunno
Jimmacle
Jimmacle2mo ago
there's probably another issue "screen goes black" isn't much info to go on
LudoCrypt
LudoCrypt2mo ago
yea which is why i didnt say anything
TilionDC
TilionDC2mo ago
if you are using Unity, chances are that you can use BepInEx lib