using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Text; using System.Text.Formatting; using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Players; using HarmonyLib; using RobocraftX.GUI.Debug; using Svelto.ECS; using Svelto.ECS.Experimental; using TechbloxModdingAPI.Engines; namespace TechbloxModdingAPI.Utility { public class DebugInterfaceEngine : IApiEngine { private static Dictionary> _extraInfo=new Dictionary>(); public void Ready() { } public EntitiesDB entitiesDB { get; set; } public void Dispose() { } public void SetInfo(string id, Func contentGetter) => _extraInfo[id] = contentGetter; public bool RemoveInfo(string id) => _extraInfo.Remove(id); public string Name => "TechbloxModdingAPIDebugInterfaceGameEngine"; public bool isRemovable => true; [HarmonyPatch] private class Patch { public static IEnumerable Transpiler(IEnumerable instructions) { var list = new List(instructions); try { //Before setting the text from the StringBuffer int index = list.FindLastIndex(inst => inst.opcode == OpCodes.Ldfld); var array = new CodeInstruction[] { new CodeInstruction(OpCodes.Ldloc_0), //StringBuffer new CodeInstruction(OpCodes.Call, ((Action)AddInfo).Method) }; list.InsertRange(index - 1, array); //-1: ldloc.1 ("local") before ldfld } catch (Exception e) { Logging.LogWarning("Failed to inject AddInfo method for the debug display!\n" + e); } return list; } public static void AddInfo(StringBuilder sb) { foreach (var info in _extraInfo) { try { string text = info.Value().Trim(); if (text.Length != 0) sb.Append(text + "\n"); } catch (Exception e) { Logging.LogWarning("Unable to get info for " + info.Key + "\n" + e); } } } public static MethodInfo TargetMethod() { return AccessTools.Method("RobocraftX.GUI.Debug.DebugDisplayEngine:UpdateDisplay"); } } } }