From c0ef8f1faeedc998e0a44370c438281fd01ebd80 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 27 Mar 2022 03:49:45 +0200 Subject: [PATCH] Fix support for accessing properties using reflection The test still crashes the game --- TechbloxModdingAPI/Blocks/BlockTests.cs | 2 +- .../Blocks/Engines/BlockEngine.cs | 18 ++++++++++-------- TechbloxModdingAPI/Utility/OptionalRef.cs | 9 +++++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/TechbloxModdingAPI/Blocks/BlockTests.cs b/TechbloxModdingAPI/Blocks/BlockTests.cs index 34903cb..d9ce279 100644 --- a/TechbloxModdingAPI/Blocks/BlockTests.cs +++ b/TechbloxModdingAPI/Blocks/BlockTests.cs @@ -82,7 +82,7 @@ namespace TechbloxModdingAPI.Blocks yield break; for (var index = 0; index < blocks.Length; index++) { - if (index % 50 == 0) yield return new WaitForSecondsEnumerator(0.2f).Continue(); //The material or flipped status can only be changed 130 times per submission + if (index % 50 == 0) yield return new WaitForSecondsEnumerator(1f).Continue(); //The material or flipped status can only be changed 130 times per submission var block = blocks[index]; if (!block.Exists) continue; foreach (var property in block.GetType().GetProperties()) diff --git a/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs b/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs index 0b63e2c..92e2236 100644 --- a/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs +++ b/TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs @@ -98,19 +98,21 @@ namespace TechbloxModdingAPI.Blocks.Engines internal object GetBlockInfo(Block block, Type type, string name) { - /*var opt = AccessTools.Method(typeof(BlockEngine), "GetBlockInfoOptional", generics: new[] { type }) - .Invoke(this, new object[] { block }); - TODO: Cannot call method with by-ref return value - var str = AccessTools.Method(opt.GetType(), "Get").Invoke(opt, Array.Empty()); - return AccessTools.Field(str.GetType(), name).GetValue(str);*/ - return AccessTools.Field(type, name).GetValue(Activator.CreateInstance(type)); + var opt = AccessTools.Method(typeof(NativeApiExtensions), "QueryEntityOptional", + new[] { typeof(EntitiesDB), typeof(EcsObjectBase), typeof(ExclusiveGroupStruct) }, new[] { type }) + .Invoke(null, new object[] { entitiesDB, block, null }); + var str = AccessTools.Property(opt.GetType(), "Value").GetValue(opt); + return AccessTools.Field(str.GetType(), name).GetValue(str); } internal void SetBlockInfo(Block block, Type type, string name, object value) { - /*var opt = AccessTools.Method(typeof(BlockEngine), "GetBlockInfoOptional", generics: new[] { type }) + var opt = AccessTools.Method(typeof(BlockEngine), "GetBlockInfoOptional", generics: new[] { type }) .Invoke(this, new object[] { block }); - var str = AccessTools.Method(opt.GetType(), "Get").Invoke(opt, Array.Empty()); - AccessTools.Field(str.GetType(), name).SetValue(str, value);*/ + var prop = AccessTools.Property(opt.GetType(), "Value"); + var str = prop.GetValue(opt); + AccessTools.Field(str.GetType(), name).SetValue(str, value); + prop.SetValue(opt, str); } public void UpdateDisplayedBlock(EGID id) diff --git a/TechbloxModdingAPI/Utility/OptionalRef.cs b/TechbloxModdingAPI/Utility/OptionalRef.cs index 9b3ec3d..a5e26b6 100644 --- a/TechbloxModdingAPI/Utility/OptionalRef.cs +++ b/TechbloxModdingAPI/Utility/OptionalRef.cs @@ -64,6 +64,15 @@ namespace TechbloxModdingAPI.Utility return ref managedArray[index]; } + /// + /// A non-by-ref view that allows getting and setting the value. + /// + public T Value + { + get => Get(); + set => Get() = value; + } + public bool Exists => state != State.Empty; public T? Nullable() => this ? Get() : default;