Skip to content

Instantly share code, notes, and snippets.

@zzzz465
Created January 2, 2020 05:02
Show Gist options
  • Select an option

  • Save zzzz465/778997b14c9cb3fadb035651fb4a97b5 to your computer and use it in GitHub Desktop.

Select an option

Save zzzz465/778997b14c9cb3fadb035651fb4a97b5 to your computer and use it in GitHub Desktop.
error log parsing code
//it was written by madeline#1941. Rimworld Error string stack trace parser.
//no parameter parsing though. #FIXME
private static IEnumerable<Layer> ParseErrorString(string raw)
{
List<Layer> layers = new List<Layer>();
using (StringReader reader = new StringReader(raw))
{
var line = string.Empty;
while((line = reader.ReadLine()) != null)
{
try
{
Log.Warning("raw : " + line);
MethodBase methodBase = null;
Type type = null;
StackFrame frame = null;
if(!line.StartsWith("at"))
continue;
//(?<= )[\w\./<>]*(?= )
//(?<=( ))([\\w]+\\.)+[\\w]+(..ctor)*
var match = Regex.Match(line, "(?<= )[\\w\\./<>]*(?= )");
if(!match.Success)
continue;
var MethodFullName = match.Value.Split('.').Where(str => string.IsNullOrEmpty(str) == false).ToList();
//test
foreach(var str in MethodFullName)
{
Log.Warning(str);
}
//
//filtering
Log.Warning("// filtered strings");
string[] copy = MethodFullName.ToArray();
for(int i = 0; i < copy.Length; i++)
{
var str = copy[i];
MethodFullName[i] = Regex.Match(str, "(?<=<)\\w+(?=>)|^\\w+")?.Value;
Log.Warning(MethodFullName[i]);
}
var typeWithNamespace = MethodFullName.Take(MethodFullName.Count() - 1);
var methodname = MethodFullName.Last();
//var parameters = splittedLine[1].Take(splittedLine[1].Length - 1).ToString().Split(',');
var completedTypeName = string.Join(".", typeWithNamespace.ToArray());
Log.Warning("type string : " + completedTypeName);
type = AccessTools.TypeByName(completedTypeName);
if(type != null)
{
Log.Warning("Found type : " + type.ToString());
}
else
Log.Error("Cannot find type : " + completedTypeName);
//List<Type> ParameterTypes = new List<Type>();
//foreach(var typestring in parameters)
//{
// Log.Warning("type : " + typestring);
// var parsedType = AccessTools.TypeByName(typestring);
//}
/*
if (ParameterTypes.Any(item => item == null))
{
StringBuilder strbuilder = new StringBuilder();
ParameterTypes.ForEach(str =>
{
strbuilder.Append(str);
strbuilder.AppendLine();
});
Log.Warning(string.Format("there's non-interpretable type string in parameters.\n{0}", strbuilder.ToString()));
ParameterTypes.Clear();
}
*/
if (string.Equals(methodname, "ctor"))
{
methodBase = AccessTools.Constructor(type); // ParameterTypes.Count > 0 ? ParameterTypes.ToArray() : null);
if(methodBase == null)
Log.Warning(string.Format("Cannot get ctor methodbase from type {0}", type));
}
else if (Regex.IsMatch(methodname, "(_Patch[\\d]+)"))
{
Match match2 = Regex.Match(methodname, ".+(?=(_Patch\\d))");
if (match2.Success)
{
methodname = match2.Value;
methodBase = AccessTools.Method(type, methodname);
}
else
Log.Warning(string.Format("method {0} seems to been patched but cannot get original method name", methodname));
}
else
methodBase = AccessTools.Method(type, methodname);
//check method name is patched
layers.Add(new Layer(methodBase, type, frame));
}
catch(Exception ex)
{
Log.Warning(ex.ToString());
}
}
}
return layers;
}
@zzzz465

zzzz465 commented Jan 2, 2020

Copy link
Copy Markdown
Author

also struct layer
public struct Layer
{
public StackFrame frame { get; private set; }

        public Type type { get; private set; }
        public MethodBase method { get; private set; }
        public Patches patches { get; private set; }

        public Layer(MethodBase method = null, Type type = null, StackFrame frame = null)
        {
            this.method = method;
            this.type = type;
            this.frame = frame;
            if(method != null)
                patches = ErrorAnalyzer.HMinstance.GetPatchInfo(method);
            else
                patches = null;
        }

        public override string ToString()
        {
            int prefixesCount = patches?.Prefixes != null ? patches.Prefixes.Count : 0;
            int postfixesCount = patches?.Postfixes != null ? patches.Postfixes.Count : 0;
            int transpilersCount = patches?.Transpilers != null ? patches.Transpilers.Count : 0;
            return string.Format("type {0} | method {1} | prefixes : {2} postfixes : {3} transpilers : {4}", type != null ? type.Name : "null",     // 0
                                                                                                             method != null ? method.Name : "null", // 1
                                                                                                             prefixesCount,                         // 2
                                                                                                             postfixesCount,                        // 3
                                                                                                             transpilersCount);                     // 4
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment