Last updated | a year ago |
Total downloads | 13168 |
Total rating | 1 |
Categories | Libraries |
Dependency string | GTFOModding-InjectLib-1.0.2 |
Dependants | 51 other packages depend on this package |
This mod requires the following mods to function
BepInEx-BepInExPack_GTFO
BepInEx pack for GTFO. Preconfigured and includes Unity Base DLLs.
Preferred version: 3.2.1README
Features
- Inject Custom Fields to Il2Cpp type
- Inject Custom Json fields to Il2Cpp type
Referencing to your plugin
[BepInDependency("GTFO.InjectLib", BepInDependency.DependencyFlags.HardDependency)]
<BIECacheFolder>$(GameFolder)\BepInEx\cache</BIECacheFolder>
<!--
This is "SAFE" il2cpp Newtonsoft.json.dll reference generated by patcher!
You should start game at least once to get it generated!
-->
<Reference Include="$(BIECacheFolder)\Il2CppJsonNet.dll" Private="false" />
Inject Fields
- Feature to extends il2cpp domain types and inject your own data to it!
//Defining Field is reqired in order to set/get data
FieldInjector<Il2CppType>.DefineValueField<UnmanagedType>(string fieldName);
FieldInjector<Il2CppType>.DefineManagedField<ManagedType>(string fieldName);
//Set data
bool FieldInjector<Il2CppType>.TrySetValueField<UnmanagedType>(Il2CppType obj, string fieldName, UnmanagedType value);
bool FieldInjector<Il2CppType>.TrySetManagedField<ManagedType>(Il2CppType obj, string fieldName, ManagedType value);
//Load Saved data
bool FieldInjector<Il2CppType>.TryGetValueField<UnmanagedType>(Il2CppType obj, string fieldName, out UnmanagedType value);
bool FieldInjector<Il2CppType>.TryGetManagedField<ManagedType>(Il2CppType obj, string fieldName, out ManagedType value);
Inject Custom Jsons to existing il2cpp type (base game json)
//SetConverter alter the whole json parse behaviour
//Useful if you want to fully alter the content of json
JsonInjector.SetConverter<Il2CppType>(Il2CppJsonReferenceTypeConverter<T> converter);
JsonInjector.SetConverter<UnmanagedIl2CppType>(Il2CppJsonUnmanagedTypeConverter<T> converter); //Type must be defined on il2cpp domain!!!
//AddHandler is similar to Harmony Postfix without out ref __result param
//You only can get JToken of parsed json and result object
//So you could inject your own field using FieldInjector
JsonInjector.AddHandler<Il2CppType>(Il2CppJsonReferenceTypeHandler<T> handler);
JsonInjector.AddHandler<UnmanagedIl2CppType>(Il2CppJsonUnmanagedTypeHandler<T> handler);
public abstract class Il2CppJsonReferenceTypeConverter<T> : INativeJsonConverter where T : Il2CppObjectBase
{
protected abstract T Read(JToken jToken, T existingValue, JsonSerializer serializer);
protected abstract void Write(JsonWriter writer, T value, JsonSerializer serializer);
}
public abstract class Il2CppJsonUnmanagedTypeConverter<T> : INativeJsonConverter where T : unmanaged
{
protected abstract T Read(JToken jToken, T existingValue, JsonSerializer serializer);
protected abstract void Write(JsonWriter writer, T value, JsonSerializer serializer);
protected abstract Il2CppSystem.Object ToIl2CppObject(T value);
}
public abstract class Il2CppJsonReferenceTypeHandler<T> : INativeJsonHandler where T : Il2CppObjectBase
{
public abstract void OnRead(in Il2CppSystem.Object result, in JToken jToken);
}
public abstract class Il2CppJsonUnmanagedTypeHandler<T> : INativeJsonHandler where T : unmanaged
{
public abstract void OnRead(in Il2CppSystem.Object result, in JToken jToken);
}
Bare example of Json Injection
JsonInjector.SetConverter(new EventTypeConverter());
JsonInjector.AddHandler(new EventDataHandler());
//This converter alter the behaviour of reading/writing eWardenObjectiveEventType enum
//So you could Parse extended enum types!
internal class EventTypeConverter : Il2CppJsonUnmanagedTypeConverter<eWardenObjectiveEventType>
{
protected override eWardenObjectiveEventType Read(JToken jToken, eWardenObjectiveEventType existingValue, JsonSerializer serializer)
{
int value = 0;
switch(jToken.Type)
{
case JTokenType.Integer:
value = (int)jToken;
break;
case JTokenType.String:
var str = (string)jToken;
if (Enum.TryParse<WEE_Type>(str, ignoreCase: true, out var weeResult))
{
value = (int)weeResult;
break;
}
else if (Enum.TryParse<eWardenObjectiveEventType>(str, ignoreCase: true, out var woResult))
{
value = (int)woResult;
break;
}
return eWardenObjectiveEventType.None;
default:
return eWardenObjectiveEventType.None;
}
return (eWardenObjectiveEventType)value;
}
protected override void Write(JsonWriter writer, eWardenObjectiveEventType value, JsonSerializer serializer)
{
writer.WriteValue((int)value);
}
protected override Il2CppSystem.Object ToIl2CppObject(eWardenObjectiveEventType value)
{
return new Il2CppSystem.Int32() { m_value = (int)value }.BoxIl2CppObject();
}
}
//This one reads Custom Fields from WardenObjectiveEventData type!
internal class EventDataHandler : Il2CppJsonReferenceTypeHandler<WardenObjectiveEventData>
{
private readonly static JsonSerializerOptions _JsonOption;
static EventDataHandler()
{
_JsonOption = new JsonSerializerOptions(JSON.DefaultSerializerSettings);
_JsonOption.Converters.Add(new LocalizedTextConverter());
}
public override void OnRead(in Il2CppSystem.Object result, in JToken jToken)
{
var data = result.Cast<WardenObjectiveEventData>();
if (Enum.IsDefined((WEE_Type)data.Type))
{
var extData = JSON.Deserialize<WEE_EventData>(jToken.ToString(), _JsonOption);
data.SetWEEData(extData);
}
}
}