MyLog logs to the Torch logging system
Fixed issue with labels not being transferred correctly when transpiling.
This commit is contained in:
@@ -6,10 +6,12 @@
|
|||||||
<target xsi:type="File" name="main" layout="${time} [${level:uppercase=true}] ${logger}: ${message}" fileName="Logs\Torch-${shortdate}.log" />
|
<target xsi:type="File" name="main" layout="${time} [${level:uppercase=true}] ${logger}: ${message}" fileName="Logs\Torch-${shortdate}.log" />
|
||||||
<target xsi:type="File" name="chat" layout="${longdate} ${message}" fileName="Logs\Chat.log" />
|
<target xsi:type="File" name="chat" layout="${longdate} ${message}" fileName="Logs\Chat.log" />
|
||||||
<target xsi:type="ColoredConsole" name="console" layout="${time} [${level:uppercase=true}] ${logger}: ${message}" />
|
<target xsi:type="ColoredConsole" name="console" layout="${time} [${level:uppercase=true}] ${logger}: ${message}" />
|
||||||
|
<target xsi:type="File" name="patch" layout="${message}" fileName="Logs\patch.log"/>
|
||||||
</targets>
|
</targets>
|
||||||
|
|
||||||
<rules>
|
<rules>
|
||||||
<logger name="*" minlevel="Info" writeTo="main, console" />
|
<logger name="*" minlevel="Info" writeTo="main, console" />
|
||||||
<logger name="Chat" minlevel="Info" writeTo="chat" />
|
<logger name="Chat" minlevel="Info" writeTo="chat" />
|
||||||
|
<!--<logger name="Torch.Managers.PatchManager.*" minlevel="Trace" writeTo="patch"/>-->
|
||||||
</rules>
|
</rules>
|
||||||
</nlog>
|
</nlog>
|
157
Torch/Managers/KeenLogManager.cs
Normal file
157
Torch/Managers/KeenLogManager.cs
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
using Torch.API;
|
||||||
|
using Torch.Managers.PatchManager;
|
||||||
|
using Torch.Utils;
|
||||||
|
using VRage.Utils;
|
||||||
|
|
||||||
|
namespace Torch.Managers
|
||||||
|
{
|
||||||
|
public class KeenLogManager : Manager
|
||||||
|
{
|
||||||
|
private static readonly Logger _log = LogManager.GetLogger("Keen");
|
||||||
|
|
||||||
|
#pragma warning disable 649
|
||||||
|
[Dependency]
|
||||||
|
private PatchManager.PatchManager _patchManager;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.Log), Parameters = new[] { typeof(MyLogSeverity), typeof(StringBuilder) })]
|
||||||
|
private static MethodInfo _logStringBuilder;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.Log), Parameters = new[] { typeof(MyLogSeverity), typeof(string), typeof(object[]) })]
|
||||||
|
private static MethodInfo _logFormatted;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.WriteLine), Parameters = new[] { typeof(string) })]
|
||||||
|
private static MethodInfo _logWriteLine;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.AppendToClosedLog), Parameters = new[] { typeof(string) })]
|
||||||
|
private static MethodInfo _logAppendToClosedLog;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.WriteLine), Parameters = new[] { typeof(string), typeof(LoggingOptions) })]
|
||||||
|
private static MethodInfo _logWriteLineOptions;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.WriteLine), Parameters = new[] { typeof(Exception) })]
|
||||||
|
private static MethodInfo _logWriteLineException;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.AppendToClosedLog), Parameters = new[] { typeof(Exception) })]
|
||||||
|
private static MethodInfo _logAppendToClosedLogException;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.WriteLineAndConsole), Parameters = new[] { typeof(string) })]
|
||||||
|
private static MethodInfo _logWriteLineAndConsole;
|
||||||
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
private PatchContext _context;
|
||||||
|
|
||||||
|
public KeenLogManager(ITorchBase torchInstance) : base(torchInstance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Attach()
|
||||||
|
{
|
||||||
|
_context = _patchManager.AcquireContext();
|
||||||
|
|
||||||
|
_context.GetPattern(_logStringBuilder).Prefixes.Add(Method(nameof(PrefixLogStringBuilder)));
|
||||||
|
_context.GetPattern(_logFormatted).Prefixes.Add(Method(nameof(PrefixLogFormatted)));
|
||||||
|
|
||||||
|
_context.GetPattern(_logWriteLine).Prefixes.Add(Method(nameof(PrefixWriteLine)));
|
||||||
|
_context.GetPattern(_logAppendToClosedLog).Prefixes.Add(Method(nameof(PrefixAppendToClosedLog)));
|
||||||
|
_context.GetPattern(_logWriteLineAndConsole).Prefixes.Add(Method(nameof(PrefixWriteLine)));
|
||||||
|
|
||||||
|
_context.GetPattern(_logWriteLineException).Prefixes.Add(Method(nameof(PrefixWriteLineException)));
|
||||||
|
_context.GetPattern(_logAppendToClosedLogException).Prefixes.Add(Method(nameof(PrefixAppendToClosedLogException)));
|
||||||
|
|
||||||
|
_context.GetPattern(_logWriteLineOptions).Prefixes.Add(Method(nameof(PrefixWriteLineOptions)));
|
||||||
|
|
||||||
|
_patchManager.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Detach()
|
||||||
|
{
|
||||||
|
_patchManager.FreeContext(_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MethodInfo Method(string name)
|
||||||
|
{
|
||||||
|
return typeof(KeenLogManager).GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ReflectedMethod(Name = "GetThreadId")]
|
||||||
|
private static Func<MyLog, int> _getThreadId;
|
||||||
|
|
||||||
|
[ReflectedMethod(Name = "GetIdentByThread")]
|
||||||
|
private static Func<MyLog, int, int> _getIndentByThread;
|
||||||
|
|
||||||
|
private static readonly ThreadLocal<StringBuilder> _tmpStringBuilder = new ThreadLocal<StringBuilder>(() => new StringBuilder(32));
|
||||||
|
|
||||||
|
private static StringBuilder PrepareLog(MyLog log)
|
||||||
|
{
|
||||||
|
return _tmpStringBuilder.Value.Clear().Append(' ', _getIndentByThread(log, _getThreadId(log)) * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool PrefixWriteLine(MyLog __instance, string msg)
|
||||||
|
{
|
||||||
|
_log.Info(PrepareLog(__instance).Append(msg));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private static bool PrefixAppendToClosedLog(MyLog __instance, string text)
|
||||||
|
{
|
||||||
|
_log.Info(PrepareLog(__instance).Append(text));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private static bool PrefixWriteLineOptions(MyLog __instance, string message, LoggingOptions option)
|
||||||
|
{
|
||||||
|
if (__instance.LogFlag(option))
|
||||||
|
_log.Info(PrepareLog(__instance).Append(message));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool PrefixAppendToClosedLogException(Exception e)
|
||||||
|
{
|
||||||
|
_log.Info(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool PrefixWriteLineException(Exception ex)
|
||||||
|
{
|
||||||
|
_log.Info(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool PrefixLogFormatted(MyLog __instance, MyLogSeverity severity, string format, object[] args)
|
||||||
|
{
|
||||||
|
_log.Log(LogLevelFor(severity), PrepareLog(__instance).AppendFormat(format, args));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool PrefixLogStringBuilder(MyLog __instance, MyLogSeverity severity, StringBuilder builder)
|
||||||
|
{
|
||||||
|
_log.Log(LogLevelFor(severity), PrepareLog(__instance).Append(builder));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LogLevel LogLevelFor(MyLogSeverity severity)
|
||||||
|
{
|
||||||
|
switch (severity)
|
||||||
|
{
|
||||||
|
case MyLogSeverity.Debug:
|
||||||
|
return LogLevel.Debug;
|
||||||
|
case MyLogSeverity.Info:
|
||||||
|
return LogLevel.Info;
|
||||||
|
case MyLogSeverity.Warning:
|
||||||
|
return LogLevel.Warn;
|
||||||
|
case MyLogSeverity.Error:
|
||||||
|
return LogLevel.Error;
|
||||||
|
case MyLogSeverity.Critical:
|
||||||
|
return LogLevel.Fatal;
|
||||||
|
default:
|
||||||
|
return LogLevel.Info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -34,18 +34,21 @@ namespace Torch.Managers.PatchManager
|
|||||||
|
|
||||||
if (Prefixes.Count == 0 && Suffixes.Count == 0 && Transpilers.Count == 0)
|
if (Prefixes.Count == 0 && Suffixes.Count == 0 && Transpilers.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
_log.Debug($"Begin patching {_method.DeclaringType?.FullName}#{_method.Name}({string.Join(", ", _method.GetParameters().Select(x => x.ParameterType.Name))})");
|
||||||
var patch = ComposePatchedMethod();
|
var patch = ComposePatchedMethod();
|
||||||
|
|
||||||
_revertAddress = AssemblyMemory.GetMethodBodyStart(_method);
|
_revertAddress = AssemblyMemory.GetMethodBodyStart(_method);
|
||||||
var newAddress = AssemblyMemory.GetMethodBodyStart(patch);
|
var newAddress = AssemblyMemory.GetMethodBodyStart(patch);
|
||||||
_revertData = AssemblyMemory.WriteJump(_revertAddress, newAddress);
|
_revertData = AssemblyMemory.WriteJump(_revertAddress, newAddress);
|
||||||
_pinnedPatch = GCHandle.Alloc(patch);
|
_pinnedPatch = GCHandle.Alloc(patch);
|
||||||
|
_log.Debug($"Done patching {_method.DeclaringType?.FullName}#{_method.Name}({string.Join(", ", _method.GetParameters().Select(x => x.ParameterType.Name))})");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Revert()
|
internal void Revert()
|
||||||
{
|
{
|
||||||
if (_pinnedPatch.HasValue)
|
if (_pinnedPatch.HasValue)
|
||||||
{
|
{
|
||||||
|
_log.Debug($"Revert {_method.DeclaringType?.FullName}#{_method.Name}({string.Join(", ", _method.GetParameters().Select(x => x.ParameterType.Name))})");
|
||||||
AssemblyMemory.WriteMemory(_revertAddress, _revertData);
|
AssemblyMemory.WriteMemory(_revertAddress, _revertData);
|
||||||
_revertData = null;
|
_revertData = null;
|
||||||
_pinnedPatch.Value.Free();
|
_pinnedPatch.Value.Free();
|
||||||
@@ -113,29 +116,30 @@ namespace Torch.Managers.PatchManager
|
|||||||
|
|
||||||
var specialVariables = new Dictionary<string, LocalBuilder>();
|
var specialVariables = new Dictionary<string, LocalBuilder>();
|
||||||
|
|
||||||
Label? labelAfterOriginalContent = Suffixes.Count > 0 ? target.DefineLabel() : (Label?)null;
|
Label labelAfterOriginalContent = target.DefineLabel();
|
||||||
Label? labelAfterOriginalReturn = Prefixes.Any(x => x.ReturnType == typeof(bool)) ? target.DefineLabel() : (Label?)null;
|
Label labelAfterOriginalReturn = target.DefineLabel();
|
||||||
|
|
||||||
|
|
||||||
var returnType = _method is MethodInfo meth ? meth.ReturnType : typeof(void);
|
Type returnType = _method is MethodInfo meth ? meth.ReturnType : typeof(void);
|
||||||
var resultVariable = returnType != typeof(void) && (labelAfterOriginalReturn.HasValue || // If we jump past main content we need local to store return val
|
LocalBuilder resultVariable = null;
|
||||||
Prefixes.Concat(Suffixes).SelectMany(x => x.GetParameters()).Any(x => x.Name == RESULT_PARAMETER))
|
if (returnType != typeof(void))
|
||||||
? target.DeclareLocal(returnType)
|
{
|
||||||
: null;
|
if (Prefixes.Concat(Suffixes).SelectMany(x => x.GetParameters()).Any(x => x.Name == RESULT_PARAMETER))
|
||||||
|
resultVariable = target.DeclareLocal(returnType);
|
||||||
|
else if (Prefixes.Any(x => x.ReturnType == typeof(bool)))
|
||||||
|
resultVariable = target.DeclareLocal(returnType);
|
||||||
|
}
|
||||||
resultVariable?.SetToDefault(target);
|
resultVariable?.SetToDefault(target);
|
||||||
|
|
||||||
if (resultVariable != null)
|
if (resultVariable != null)
|
||||||
specialVariables.Add(RESULT_PARAMETER, resultVariable);
|
specialVariables.Add(RESULT_PARAMETER, resultVariable);
|
||||||
|
|
||||||
target.EmitComment("Prefixes Begin");
|
target.EmitComment("Prefixes Begin");
|
||||||
foreach (var prefix in Prefixes)
|
foreach (MethodInfo prefix in Prefixes)
|
||||||
{
|
{
|
||||||
EmitMonkeyCall(target, prefix, specialVariables);
|
EmitMonkeyCall(target, prefix, specialVariables);
|
||||||
if (prefix.ReturnType == typeof(bool))
|
if (prefix.ReturnType == typeof(bool))
|
||||||
{
|
target.Emit(OpCodes.Brfalse, labelAfterOriginalReturn);
|
||||||
Debug.Assert(labelAfterOriginalReturn.HasValue);
|
|
||||||
target.Emit(OpCodes.Brfalse, labelAfterOriginalReturn.Value);
|
|
||||||
}
|
|
||||||
else if (prefix.ReturnType != typeof(void))
|
else if (prefix.ReturnType != typeof(void))
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
$"Prefixes must return void or bool. {prefix.DeclaringType?.FullName}.{prefix.Name} returns {prefix.ReturnType}");
|
$"Prefixes must return void or bool. {prefix.DeclaringType?.FullName}.{prefix.Name} returns {prefix.ReturnType}");
|
||||||
@@ -145,31 +149,24 @@ namespace Torch.Managers.PatchManager
|
|||||||
target.EmitComment("Original Begin");
|
target.EmitComment("Original Begin");
|
||||||
MethodTranspiler.Transpile(_method, Transpilers, target, labelAfterOriginalContent);
|
MethodTranspiler.Transpile(_method, Transpilers, target, labelAfterOriginalContent);
|
||||||
target.EmitComment("Original End");
|
target.EmitComment("Original End");
|
||||||
if (labelAfterOriginalContent.HasValue)
|
|
||||||
{
|
target.MarkLabel(labelAfterOriginalContent);
|
||||||
target.MarkLabel(labelAfterOriginalContent.Value);
|
|
||||||
if (resultVariable != null)
|
if (resultVariable != null)
|
||||||
target.Emit(OpCodes.Stloc, resultVariable);
|
target.Emit(OpCodes.Stloc, resultVariable);
|
||||||
}
|
target.MarkLabel(labelAfterOriginalReturn);
|
||||||
if (labelAfterOriginalReturn.HasValue)
|
|
||||||
target.MarkLabel(labelAfterOriginalReturn.Value);
|
|
||||||
|
|
||||||
target.EmitComment("Suffixes Begin");
|
target.EmitComment("Suffixes Begin");
|
||||||
foreach (var suffix in Suffixes)
|
foreach (MethodInfo suffix in Suffixes)
|
||||||
{
|
{
|
||||||
EmitMonkeyCall(target, suffix, specialVariables);
|
EmitMonkeyCall(target, suffix, specialVariables);
|
||||||
if (suffix.ReturnType != typeof(void))
|
if (suffix.ReturnType != typeof(void))
|
||||||
throw new Exception($"Suffixes must return void. {suffix.DeclaringType?.FullName}.{suffix.Name} returns {suffix.ReturnType}");
|
throw new Exception($"Suffixes must return void. {suffix.DeclaringType?.FullName}.{suffix.Name} returns {suffix.ReturnType}");
|
||||||
}
|
}
|
||||||
target.EmitComment("Suffixes End");
|
target.EmitComment("Suffixes End");
|
||||||
|
|
||||||
if (labelAfterOriginalContent.HasValue || labelAfterOriginalReturn.HasValue)
|
|
||||||
{
|
|
||||||
if (resultVariable != null)
|
if (resultVariable != null)
|
||||||
target.Emit(OpCodes.Ldloc, resultVariable);
|
target.Emit(OpCodes.Ldloc, resultVariable);
|
||||||
target.Emit(OpCodes.Ret);
|
target.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void EmitMonkeyCall(LoggingIlGenerator target, MethodInfo patch,
|
private void EmitMonkeyCall(LoggingIlGenerator target, MethodInfo patch,
|
||||||
IReadOnlyDictionary<string, LocalBuilder> specialVariables)
|
IReadOnlyDictionary<string, LocalBuilder> specialVariables)
|
||||||
|
@@ -4,6 +4,7 @@ using System.Reflection;
|
|||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Torch.Managers.PatchManager.Transpile;
|
using Torch.Managers.PatchManager.Transpile;
|
||||||
|
using Label = System.Windows.Controls.Label;
|
||||||
|
|
||||||
namespace Torch.Managers.PatchManager.MSIL
|
namespace Torch.Managers.PatchManager.MSIL
|
||||||
{
|
{
|
||||||
@@ -69,7 +70,7 @@ namespace Torch.Managers.PatchManager.MSIL
|
|||||||
break;
|
break;
|
||||||
case OperandType.ShortInlineI:
|
case OperandType.ShortInlineI:
|
||||||
Operand = OpCode == OpCodes.Ldc_I4_S
|
Operand = OpCode == OpCodes.Ldc_I4_S
|
||||||
? (MsilOperand) new MsilOperandInline.MsilOperandInt8(this)
|
? (MsilOperand)new MsilOperandInline.MsilOperandInt8(this)
|
||||||
: new MsilOperandInline.MsilOperandUInt8(this);
|
: new MsilOperandInline.MsilOperandUInt8(this);
|
||||||
break;
|
break;
|
||||||
case OperandType.ShortInlineR:
|
case OperandType.ShortInlineR:
|
||||||
@@ -120,10 +121,23 @@ namespace Torch.Managers.PatchManager.MSIL
|
|||||||
/// <returns>This instruction</returns>
|
/// <returns>This instruction</returns>
|
||||||
public MsilInstruction InlineValue<T>(T o)
|
public MsilInstruction InlineValue<T>(T o)
|
||||||
{
|
{
|
||||||
((MsilOperandInline<T>) Operand).Value = o;
|
((MsilOperandInline<T>)Operand).Value = o;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes a copy of the instruction with a new opcode.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="code">The new opcode</param>
|
||||||
|
/// <returns>The copy</returns>
|
||||||
|
public MsilInstruction CopyWith(OpCode code)
|
||||||
|
{
|
||||||
|
var result = new MsilInstruction(code) { Operand = this.Operand };
|
||||||
|
foreach (MsilLabel x in Labels)
|
||||||
|
result.Labels.Add(x);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the inline branch target for this instruction.
|
/// Sets the inline branch target for this instruction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -131,7 +145,7 @@ namespace Torch.Managers.PatchManager.MSIL
|
|||||||
/// <returns>This instruction</returns>
|
/// <returns>This instruction</returns>
|
||||||
public MsilInstruction InlineTarget(MsilLabel label)
|
public MsilInstruction InlineTarget(MsilLabel label)
|
||||||
{
|
{
|
||||||
((MsilOperandBrTarget) Operand).Target = label;
|
((MsilOperandBrTarget)Operand).Target = label;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,7 +56,7 @@ namespace Torch.Managers.PatchManager.Transpile
|
|||||||
var instructionValue = (short)memory.ReadByte();
|
var instructionValue = (short)memory.ReadByte();
|
||||||
if (Prefixes.Contains(instructionValue))
|
if (Prefixes.Contains(instructionValue))
|
||||||
{
|
{
|
||||||
instructionValue = (short) ((instructionValue << 8) | memory.ReadByte());
|
instructionValue = (short)((instructionValue << 8) | memory.ReadByte());
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (!OpCodeLookup.TryGetValue(instructionValue, out OpCode opcode))
|
if (!OpCodeLookup.TryGetValue(instructionValue, out OpCode opcode))
|
||||||
@@ -65,7 +65,7 @@ namespace Torch.Managers.PatchManager.Transpile
|
|||||||
throw new Exception($"Opcode said it was {opcode.Size} but we read {count}");
|
throw new Exception($"Opcode said it was {opcode.Size} but we read {count}");
|
||||||
var instruction = new MsilInstruction(opcode)
|
var instruction = new MsilInstruction(opcode)
|
||||||
{
|
{
|
||||||
Offset = (int) memory.Position
|
Offset = (int)memory.Position
|
||||||
};
|
};
|
||||||
_instructions.Add(instruction);
|
_instructions.Add(instruction);
|
||||||
instruction.Operand?.Read(this, reader);
|
instruction.Operand?.Read(this, reader);
|
||||||
@@ -106,9 +106,9 @@ namespace Torch.Managers.PatchManager.Transpile
|
|||||||
var opcode = (OpCode)field.GetValue(null);
|
var opcode = (OpCode)field.GetValue(null);
|
||||||
if (opcode.OpCodeType != OpCodeType.Nternal)
|
if (opcode.OpCodeType != OpCodeType.Nternal)
|
||||||
OpCodeLookup.Add(opcode.Value, opcode);
|
OpCodeLookup.Add(opcode.Value, opcode);
|
||||||
if ((ushort) opcode.Value > 0xFF)
|
if ((ushort)opcode.Value > 0xFF)
|
||||||
{
|
{
|
||||||
Prefixes.Add((short) ((ushort) opcode.Value >> 8));
|
Prefixes.Add((short)((ushort)opcode.Value >> 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,18 +28,19 @@ namespace Torch.Managers.PatchManager.Transpile
|
|||||||
|
|
||||||
private static IEnumerable<MsilInstruction> FixBranchAndReturn(IEnumerable<MsilInstruction> insn, Label? retTarget)
|
private static IEnumerable<MsilInstruction> FixBranchAndReturn(IEnumerable<MsilInstruction> insn, Label? retTarget)
|
||||||
{
|
{
|
||||||
foreach (var i in insn)
|
foreach (MsilInstruction i in insn)
|
||||||
{
|
{
|
||||||
if (retTarget.HasValue && i.OpCode == OpCodes.Ret)
|
if (retTarget.HasValue && i.OpCode == OpCodes.Ret)
|
||||||
{
|
{
|
||||||
var j = new MsilInstruction(OpCodes.Br);
|
MsilInstruction j = new MsilInstruction(OpCodes.Br).InlineTarget(new MsilLabel(retTarget.Value));
|
||||||
((MsilOperandBrTarget)j.Operand).Target = new MsilLabel(retTarget.Value);
|
foreach (MsilLabel l in i.Labels)
|
||||||
|
j.Labels.Add(l);
|
||||||
yield return j;
|
yield return j;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_opcodeReplaceRule.TryGetValue(i.OpCode, out OpCode replaceOpcode))
|
if (_opcodeReplaceRule.TryGetValue(i.OpCode, out OpCode replaceOpcode))
|
||||||
{
|
{
|
||||||
yield return new MsilInstruction(replaceOpcode) { Operand = i.Operand };
|
yield return i.CopyWith(replaceOpcode);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
yield return i;
|
yield return i;
|
||||||
@@ -62,6 +63,7 @@ namespace Torch.Managers.PatchManager.Transpile
|
|||||||
_opcodeReplaceRule.Add(opcode, other.Value);
|
_opcodeReplaceRule.Add(opcode, other.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_opcodeReplaceRule[OpCodes.Leave_S] = OpCodes.Leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -159,6 +159,7 @@
|
|||||||
<Compile Include="Managers\ChatManager\ChatManagerClient.cs" />
|
<Compile Include="Managers\ChatManager\ChatManagerClient.cs" />
|
||||||
<Compile Include="Managers\ChatManager\ChatManagerServer.cs" />
|
<Compile Include="Managers\ChatManager\ChatManagerServer.cs" />
|
||||||
<Compile Include="Managers\DependencyManager.cs" />
|
<Compile Include="Managers\DependencyManager.cs" />
|
||||||
|
<Compile Include="Managers\KeenLogManager.cs" />
|
||||||
<Compile Include="Managers\PatchManager\AssemblyMemory.cs" />
|
<Compile Include="Managers\PatchManager\AssemblyMemory.cs" />
|
||||||
<Compile Include="Managers\PatchManager\DecoratedMethod.cs" />
|
<Compile Include="Managers\PatchManager\DecoratedMethod.cs" />
|
||||||
<Compile Include="Managers\PatchManager\EmitExtensions.cs" />
|
<Compile Include="Managers\PatchManager\EmitExtensions.cs" />
|
||||||
|
@@ -24,6 +24,7 @@ using Torch.API.Session;
|
|||||||
using Torch.Commands;
|
using Torch.Commands;
|
||||||
using Torch.Managers;
|
using Torch.Managers;
|
||||||
using Torch.Managers.ChatManager;
|
using Torch.Managers.ChatManager;
|
||||||
|
using Torch.Managers.PatchManager;
|
||||||
using Torch.Utils;
|
using Torch.Utils;
|
||||||
using Torch.Session;
|
using Torch.Session;
|
||||||
using VRage.Collections;
|
using VRage.Collections;
|
||||||
@@ -119,6 +120,8 @@ namespace Torch
|
|||||||
sessionManager.AddFactory((x) => new EntityManager(this));
|
sessionManager.AddFactory((x) => new EntityManager(this));
|
||||||
|
|
||||||
Managers.AddManager(sessionManager);
|
Managers.AddManager(sessionManager);
|
||||||
|
Managers.AddManager(new PatchManager(this));
|
||||||
|
Managers.AddManager(new KeenLogManager(this));
|
||||||
Managers.AddManager(new FilesystemManager(this));
|
Managers.AddManager(new FilesystemManager(this));
|
||||||
Managers.AddManager(new UpdateManager(this));
|
Managers.AddManager(new UpdateManager(this));
|
||||||
Managers.AddManager(Plugins);
|
Managers.AddManager(Plugins);
|
||||||
|
Reference in New Issue
Block a user