public static void CacheData(MemoryStream stream, string cachePath) { var clock3 = Stopwatch.StartNew(); File.WriteAllBytes(cachePath, stream.ToArray()); PrepatcherMod.Info($"Write to file took {clock3.ElapsedMilliseconds}"); }
static void AddField(ModuleDefinition module, NewFieldData newField) { var fieldType = GenTypes.GetTypeInAnyAssembly(newField.fieldType); var ceFieldType = module.ImportReference(fieldType); PrepatcherMod.Info($"Patching in a new field {newField.name} of type {ceFieldType.ToStringSafe()}/{newField.fieldType} in type {newField.targetType}"); var ceField = new FieldDefinition( newField.name, FieldAttributes.Public, ceFieldType ); if (newField.isStatic) { ceField.Attributes |= FieldAttributes.Static; } var targetType = module.GetType(newField.targetType); targetType.Fields.Add(ceField); if (newField.defaultValue != null) { WriteFieldInitializers(newField, ceField, fieldType); } }
public static void BakeAsm(byte[] sourceAsmBytes, List <NewFieldData> fieldsToAdd, MemoryStream writeTo) { var clock = Stopwatch.StartNew(); using ModuleDefinition module = ModuleDefinition.ReadModule(new MemoryStream(sourceAsmBytes)); PrepatcherMod.Info($"Reading took {clock.ElapsedMilliseconds}"); module.GetType("Verse.Game").Fields.Add(new FieldDefinition( PrepatcherMod.PrepatcherMarkerField, FieldAttributes.Static, module.TypeSystem.Int32 )); foreach (var newField in fieldsToAdd) { AddField(module, newField); } PrepatcherMod.Info("Added fields"); PrepatcherMod.ProcessModule(module); module.GetType("Verse.Root").Methods.First(m => m.name == "Update").Body.Instructions.Insert(0, Instruction.Create( OpCodes.Call, module.ImportReference(SymbolExtensions.GetMethodInfo(() => Allocs.Update())) )); var clock2 = Stopwatch.StartNew(); module.Write(writeTo); PrepatcherMod.Info($"Write to memory took {clock2.ElapsedMilliseconds}"); }