static void Main(string[] args) { if (args.Length != 1) { Usage(); Environment.Exit(1); } if (!args[0].EndsWith(".asm")) { Usage(); Environment.Exit(1); } try { string inputFile = args[0]; string outputFile = System.IO.Path.ChangeExtension(inputFile, ".hack"); var inStream = new FileStream(inputFile, FileMode.Open); var outStream = new FileStream(outputFile, FileMode.Create); Assembler.Assemble(inStream, outStream); } catch (System.Exception ex) { Console.WriteLine(ex.Message); } }
private static void MethodResolver(MethodContext context) { if (context.Method.Name == "SimpleSum") { Assembler assembler = new Assembler(64); //Replace with fatorial number: //int sum = num1+num2; //int fatorial = 1; //for(int i = 2; i <= sum; i++){ // fatorial *= i; //} //return fatorial; assembler.add(edx, ecx); assembler.mov(eax, 1); assembler.mov(ecx, 2); assembler.cmp(edx, 0x02); assembler.jl(assembler.@F); assembler.AnonymousLabel(); assembler.imul(eax, ecx); assembler.inc(ecx); assembler.cmp(ecx, edx); assembler.jle(assembler.@B); assembler.AnonymousLabel(); assembler.ret(); using MemoryStream ms = new MemoryStream(); assembler.Assemble(new StreamCodeWriter(ms), 0); byte[] asm = ms.ToArray(); context.ResolveNative(asm); } }
void Test_zero_bytes() { var a = new Assembler(64); var lblf = a.CreateLabel(); var lbll = a.CreateLabel(); var lbl1 = a.CreateLabel(); var lbl2 = a.CreateLabel(); a.Label(ref lblf); a.zero_bytes(); a.je(lbl1); a.je(lbl2); a.Label(ref lbl1); a.zero_bytes(); a.Label(ref lbl2); a.nop(); [email protected]_bytes(); a.Label(ref lbll); a.zero_bytes(); var writer = new CodeWriterImpl(); a.Assemble(writer, 0); var bytes = writer.ToArray(); Assert.Equal(new byte[] { 0x74, 0x02, 0x74, 0x00, 0x90 }, bytes); }
private static int Main(string[] args) { try { if (args.Length != 1) throw new Ufer(AppDomain.CurrentDomain.FriendlyName + " <xxx.asm>"); var fpatIn = args[0]; if (!fpatIn.EndsWith(".asm", StringComparison.InvariantCultureIgnoreCase)) throw new Ufer("Not an asm file"); var src = File.ReadAllText(fpatIn); var fpatOut = fpatIn.Substring(0, fpatIn.Length - 4) + ".hack"; var assembler = new Assembler(); File.WriteAllLines(fpatOut, assembler.Assemble(src)); return 0; } catch (Exception er) { Console.WriteLine(er.UstMessage()); return 1; } }
static void Main(string[] args) { Console.Title = "Test"; Instruction[] Unused; byte[] ProgMem = Assembler.Assemble(File.ReadAllText("Test.e64"), out Unused); Dump(ProgMem); //Console.WriteLine("Unused:"); //Console.WriteLine(string.Join(", ", Unused)); CPU Elisa = new CPU(ProgMem); Elisa.Ports.Add(0, (Data, IsRead) => { Console.Write((char)Data); return(0); }); try { while (!Elisa.Halted) { Elisa.Step(); } } catch (Exception E) { Console.WriteLine(E.Message); throw; } Console.ReadLine(); }
protected override void InitList() { if (!Directory.Exists(ProgramDirectory.PATH)) { return; } // Assemble all program files string[] filePaths = Directory.GetFiles(ProgramDirectory.PATH, "*.txt"); foreach (string filePath in filePaths) { string programText = File.ReadAllText(filePath); Program program = Assembler.Assemble(Path.GetFileNameWithoutExtension(filePath), programText); if (program != null) { // Setup autosave program.OnChange += () => SaveProgram(program); items.Add(program); } else { Debug.LogWarning("Assembly of file " + filePath + " failed"); } } }
private void button1_Click(object sender, EventArgs e) { String text = richTextBox1.Text; var lexerOutput = Lexer.lex(text.Split('\n')); if (lexerOutput.Item2.Count > 0) { string errors = ""; foreach (var error in lexerOutput.Item2) { errors += error + '\n'; } MessageBox.Show(errors, "Error while lexing", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var assmblerOutput = Assembler.Assemble(lexerOutput.Item1); if (assmblerOutput.Item2.Count > 0) { string errors = ""; foreach (var error in assmblerOutput.Item2) { errors += error + '\n'; } MessageBox.Show(errors, "Error while assmbling", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Form2 emulatorView = new Form2(assmblerOutput.Item1); emulatorView.Show(); }
static void TestAssemble() { try { Assembler a = new Assembler(); String lmsFilename = Path.Combine(TEST_OUTPUT, Path.GetFileNameWithoutExtension(SOURCE_FILENAME)) + ".lms"; String rmfFilename = Path.Combine(TEST_OUTPUT, Path.GetFileNameWithoutExtension(SOURCE_FILENAME)) + ".rmf"; FileStream fs = new FileStream(lmsFilename, FileMode.Open, FileAccess.Read); FileStream ofs = new FileStream(rmfFilename, FileMode.Create, FileAccess.Write); List <String> errors = new List <String>(); a.Assemble(fs, ofs, errors); fs.Close(); ofs.Close(); if (errors.Count > 0) { foreach (String s in errors) { Console.WriteLine(s); } } } catch (Exception e) { Console.WriteLine("Assemble error: " + e.Message); Console.WriteLine(e.StackTrace); Console.ReadKey(); } }
public void Test_For_Set_Reg_Label() { Assembler testAssembler = new Assembler(); var code = new List <string> { "SET X,data", ":data", "DAT \"Hello, World!\",0" }; testAssembler.Assemble(code); List <ushort> dump = new List <ushort>() { 0x7c61, 0x0002, 0x0048, 0x0065, 0x006c, 0x006c, 0x006f, 0x002c, 0x0020, 0x0057, 0x006f, 0x0072, 0x006c, 0x0064, 0x0021, 0x0000 }; CollectionAssert.AreEqual(dump, testAssembler.Dump); }
private void PreformRoomAsmPatch() { var labels = new AddressLabels(); var Asm = EnhancerResources.RoomDataHack; var assembler = new Assembler("RoomDataHack", Asm, StandardFileSystem.FileSystem) { Labels = labels }; var bin = assembler.Assemble(); var errors = assembler.GetErrors(); if (errors.Count > 0) { throw new EnhancerException("Room data hack ASM patch failed to assemble with " + errors.Count.ToString() + " errors. First error: " + errors[0].Message + " on line " + errors[0].LineNumber.ToString()); } var patches = assembler.GetPatchSegments(); for (int i = 0; i < patches.Count; i++) { var patch = patches[i]; Array.Copy(bin, patch.Start, enhancedRomData, patch.PatchOffset, patch.Length); } }
public void ChangePersonalInfoData(IChangePersonalInfoData data) { ApplicationUser user = repository.UserManager.FindByEmail(data.Email); if (data.NewFirstName.IsChanged) { user.FirstName = data.NewFirstName.NewValue; } if (data.NewSurname.IsChanged) { user.Surname = data.NewSurname.NewValue; } if (data.NewCity.IsChanged) { user.City = data.NewCity.NewValue; } if (data.NewPostDepartment.IsChanged) { user.PostDepartment = data.NewPostDepartment.NewValue; } if (data.NewPhone.IsChanged) { user.PhoneNumber = data.NewPhone.NewValue; } if (data.NewLanguage.IsChanged) { user.Language = data.NewLanguage.NewValue == null ? default(DAL.Entities.LanguageType?) : Assembler.Assemble(data.NewLanguage.NewValue.Value); } repository.UserRepository.Update(user); repository.Save(); }
private InlineHook(QHackContext ctx, AssemblyCode code, HookParameters parameters) { Context = ctx; Code = code.Copy(); MemoryAllocation = new MemoryAllocation(ctx); Parameters = parameters; byte[] headInstBytes = GetHeadBytes(Context.DataAccess.ReadBytes(Parameters.TargetAddress, 32)); nuint allocAddr = MemoryAllocation.AllocationBase; nuint safeFreeFlagAddr = allocAddr + (uint)HookInfo.Offset_SafeFreeFlag; nuint onceFlagAddr = allocAddr + (uint)HookInfo.Offset_OnceFlag; nuint codeAddr = allocAddr + (uint)HookInfo.HeaderSize; nuint retAddr = Parameters.TargetAddress + (uint)headInstBytes.Length; HookInfo info = new(allocAddr, headInstBytes); Assembler assembler = new(); assembler.Emit(DataHelper.GetBytes(info)); //emit the header before runnable code assembler.Emit((Instruction)$"mov dword ptr [{safeFreeFlagAddr}],1"); assembler.Emit(Parameters.IsOnce ? GetOnceCheckedCode(Code, onceFlagAddr) : Code); //once or not if (Parameters.Original) { assembler.Emit(headInstBytes); //emit the raw code replaced by hook jmp } assembler.Emit((Instruction)$"mov dword ptr [{safeFreeFlagAddr}],0"); assembler.Emit((Instruction)$"jmp {retAddr}"); Context.DataAccess.WriteBytes(allocAddr, assembler.GetByteCode(allocAddr)); JmpHeadBytes = new byte[headInstBytes.Length]; Array.Fill <byte>(JmpHeadBytes, 0x90); Assembler.Assemble($"jmp {codeAddr}", Parameters.TargetAddress).CopyTo(JmpHeadBytes, 0); }
static void TestAssemble() { Assembler a = new Assembler(); String f = "C:/temp/compiledbasic.lms"; FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read); FileStream ofs = new FileStream("c:/temp/compiledbasic.rbf", FileMode.Create, FileAccess.Write); List <String> errors = new List <String>(); a.Assemble(fs, ofs, errors); fs.Close(); ofs.Close(); if (errors.Count > 0) { foreach (String s in errors) { Console.WriteLine(s); } Console.ReadKey(); } }
void Assemble_throws_if_error() { var c = new Assembler(64); c.aaa(); Assert.Throws <InvalidOperationException>(() => c.Assemble(new CodeWriterImpl(), 0)); }
private static int Main(string[] args) { try { if (args.Length != 1) { throw new Ufer(AppDomain.CurrentDomain.FriendlyName + " <xxx.asm>"); } var fpatIn = args[0]; if (!fpatIn.EndsWith(".asm", StringComparison.InvariantCultureIgnoreCase)) { throw new Ufer("Not an asm file"); } var src = File.ReadAllText(fpatIn); var fpatOut = fpatIn.Substring(0, fpatIn.Length - 4) + ".hack"; var assembler = new Assembler(); File.WriteAllLines(fpatOut, assembler.Assemble(src)); return(0); } catch (Exception er) { Console.WriteLine(er.UstMessage()); return(1); } }
void Awake() { // Assemble all program files string[] filePaths = Directory.GetFiles(ProgramDirectory.value, "*.txt"); foreach (string filePath in filePaths) { string programText = File.ReadAllText(filePath); Program program = Assembler.Assemble(programText); if (program != null) { program.name = Path.GetFileNameWithoutExtension(filePath); Debug.Log("Assembly of program " + program.name + " succeeded"); // Setup autosave program.OnChange += () => SaveProgram(program); programs.Add(program); } else { Debug.LogWarning("Assembly of file " + filePath + " failed"); } } // Populate list foreach (Program program in programs) { CreateListEntry(program); } }
private void DisassemblyEditor_LostFocus(object sender, RoutedEventArgs e) { UndertaleCode code = this.DataContext as UndertaleCode; if (code == null) { return; // Probably loaded another data.win or something. } UndertaleData data = (Application.Current.MainWindow as MainWindow).Data; try { var instructions = Assembler.Assemble(DisassemblyEditor.Text, data); code.Replace(instructions); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Assembler error", MessageBoxButton.OK, MessageBoxImage.Error); return; } CurrentDisassembled = null; CurrentDecompiled = null; CurrentGraphed = null; DisassembleCode(code); DisassemblyView.Visibility = Visibility.Visible; DisassemblyEditor.Visibility = Visibility.Collapsed; }
public void ScanningException_ThrowsException() { var source = "BORK"; Assert.That(() => Assembler.Assemble(source), Throws.InstanceOf <AssemblingException>() .With.Message.EqualTo("[1] Error at BORK: Expected LABEL or INSTRUCTION.")); }
public void CommentsInSourceCode() { string[] sourceCode = { "; program to swap two memory locations", "", "LDA $0380 ; load memory address 896 into A", "LDX $0381 ; load memory address 897 into X", "", "STA $0381 ; store A into 897", "STX $0380 ; store X into 896", "", "RTS ; return from subroutine" }; var(binary, _) = Assembler.Assemble(sourceCode, 0x033C); byte[] expectedBinary = { 0x3C, 0x03, // staring memory location (828) 0xAD, 0x80, 0x03, // LDA $0380 ; (896) 0xAE, 0x81, 0x03, // LDX $0381 ; (897) 0x8D, 0x81, 0x03, // STA $0381 0x8E, 0x80, 0x03, // STX $0380 0x60 // RTS }; Assert.AreEqual(expectedBinary, binary); }
public void AssembleTest() { Assembler target = new Assembler(); // TODO: Initialize to an appropriate value target.Assemble(); Assert.Inconclusive("A method that does not return a value cannot be verified."); }
public void AssembleException() { var asm = new Assembler(); string[] mnemonics = new[] { "use32", "jmp [0x123456]" // Missing operand size. }; try { asm.Assemble(mnemonics); } catch (FasmException ex) { // Confirm exception details. Assert.Equal(FasmResult.Error, ex.Result); Assert.Equal(mnemonics, ex.Mnemonics); Assert.Equal(2, ex.Line); Assert.Equal(FasmErrors.OperandSizeNotSpecified, ex.ErrorCode); } asm.Dispose(); }
public IPersonalInfo GetPersonalInfo(string email) { ApplicationUser user = repository.UserManager.FindByEmail(email); LanguageType? userLanguage = user.Language != null?Assembler.Assemble(user.Language.Value) : default(LanguageType?); return(new PersonalInfo(user.FirstName, user.Surname, user.City, user.PostDepartment, user.PhoneNumber, userLanguage)); }
/// <summary> /// Takes either an array or list of strings containing assembly instructions, a MachineType of I386 or x64, /// an instance of the ERC_Core object and returns the associated opcodes. /// </summary> /// <param name="instructions">The instructions to be assemble=d</param> /// <param name="machineType">a ERC.MachineType of either I386 or x64</param> /// <returns>Returns an ERC_Result byte array containing the assembled instructions</returns> public static ErcResult <byte[]> AssembleOpcodes(List <string> instructions, MachineType machineType) { ErcResult <byte[]> result = new ErcResult <byte[]>(new ErcCore()); List <string> mnemonics = new List <string>(); if (machineType == MachineType.I386) { mnemonics.Add("use32"); } else if (machineType == MachineType.x64) { mnemonics.Add("use64"); } for (int i = 0; i < instructions.Count; i++) { mnemonics.Add(instructions[i]); } var asm = new Assembler(); try { result.ReturnValue = asm.Assemble(mnemonics); asm.Dispose(); } catch (Exception e) { result.Error = e; result.LogEvent(); asm.Dispose(); return(result); } return(result); }
public void CompileInMemory() { Assembler assembler = new Assembler(); var savableDocument = this.DockPanel.ActiveDocument as SourceDocument; var contents = savableDocument.ContentEditor.Text; var output = assembler.Assemble(contents); ushort currentAddress = 0; List<ushort> data = new List<ushort>(); foreach (var entry in output) { loMapping.Add(new LineOffsetMapping { LineNumber = entry.LineNumber, Address = entry.Address }); if (mapping.ContainsKey(entry.Address)) { mapping.Remove(entry.Address); } mapping.Add(entry.Address, entry.LineNumber); if (entry.Output != null) { foreach (ushort value in entry.Output) { currentAddress++; data.Add(value); } } } var arr = data.ToArray(); }
public void CodeWithAddressLabels() { string[] sourceCode = { "; print 'Y' if memeory address content is non-zero, otherwise 'N'", " LDA $0380 ; load memory address into A", " BEQ *LABEL ; check if it was 0", " LDA #$59 ; load 'Y' into A", " JMP END ; got to end", "LABEL: LDA #$4E ; load 'N' into A", "END: JSR $FFD2 ; write the character to the screen", " RTS" }; var(binary, _) = Assembler.Assemble(sourceCode, 0x033C); byte[] expectedBinary = { 0x3C, 0x03, 0xAD, 0x80, 0x03, // 033C 0xF0, 0x05, // 033F 0xA9, 0x59, // 0341 0x4C, 0x48, 0x03, // 0343 0xA9, 0x4E, // 0346 (LABEL) 0x20, 0xD2, 0xFF, // 0348 (END) 0x60 // 034B }; Assert.AreEqual(expectedBinary, binary); }
public void SimpleTest() { string[] sourceCode = { "LDA $0380", "LDX $0381", "STA $0381", "STX $0380", "RTS" }; var(binary, _) = Assembler.Assemble(sourceCode, 0x033C); byte[] expectedBinary = { 0x3C, 0x03, // staring memory location (828) 0xAD, 0x80, 0x03, // LDA $0380 ; (896) 0xAE, 0x81, 0x03, // LDX $0381 ; (897) 0x8D, 0x81, 0x03, // STA $0381 0x8E, 0x80, 0x03, // STX $0380 0x60 // RTS }; Assert.AreEqual(expectedBinary, binary); }
void Assemble_throws_if_null_writer() { var c = new Assembler(Bitness); c.nop(); Assert.Throws <ArgumentNullException>(() => c.Assemble(null, 0)); }
public void ParsingException_ThrowsException() { var source = "INC BORK"; Assert.That(() => Assembler.Assemble(source), Throws.InstanceOf <AssemblingException>() .With.Message.EqualTo("[1] Error at BORK: Expected register.")); }
/// <summary> /// Your own user code starts here. /// If this is your first time, do consider reading the notice above. /// It contains some very useful information. /// </summary> public static void Init() { /* * Reloaded Mod Loader Sample: Reloaded-Assembler * Architectures supported: X86, X64 * * Demonstrates the simple usage of ReloadedAssembler, * a background service wrapped around FASM.NET. * * ReloadedAssembler provides you a means to effortlessly * generate and compile X86 and X64 assembly in a * real-time, just-in-time fashion. */ // Want to see this in with a debugger? Uncomment this line. // Debugger.Launch(); // Print demo details. Bindings.PrintInfo("Reloaded-Assembler Demo: 64bit Assembly"); Bindings.PrintText("X64 Test:"); // Sample assembler. string[] x64asm = new[] { "use64", // Specifies this is a X64 piece of ASM. "mov rbx, rax", "mov rax, 0x123456", "jmp qword [0x123456]" // This is FASM, YOU MUST SPECIFY OPERAND SIZE EXPLICITLY (`qword` in this case) }; Bindings.PrintInfo("Assembling\n" + ConvertStringArrayToString(x64asm)); // Assemble and print result. byte[] resultx64 = Assembler.Assemble(x64asm); Bindings.PrintInfo("Result:" + ByteArrayToString(resultx64)); // Sample assembler. Bindings.PrintText("X86 Test:"); string[] x86asm = new[] { "use32", // Specifies this is a X86 piece of ASM. "mov ebx, eax", "mov eax, 0x123456", "jmp dword [0x123456]" // This is FASM, YOU MUST SPECIFY OPERAND SIZE EXPLICITLY (`dword` in this case) }; Bindings.PrintInfo("Assembling\n" + ConvertStringArrayToString(x86asm)); // Assemble and print result. byte[] resultx86 = Assembler.Assemble(x86asm); Bindings.PrintInfo("Result:" + ByteArrayToString(resultx86)); // Credits Bindings.PrintText("Protip: When using Reloaded it is highly recommended to first test your assembler for compilation" + " with standalone FASM assembler."); /*"Credits to Zenlulz for FASM.NET, Tomasz Grysztar for FASM and FASMlib. * Networked background service version is an implementation of my own"*/ }
void Undeclared_forward_anon_label_throws() { var c = new Assembler(64); c.nop(); c.je(c.@F); Assert.Throws <InvalidOperationException>(() => c.Assemble(new CodeWriterImpl(), 0)); }
void Unused_anonymous_label_throws() { var c = new Assembler(64); c.nop(); c.AnonymousLabel(); Assert.Throws <InvalidOperationException>(() => c.Assemble(new CodeWriterImpl(), 0)); }
private static void RunProgram(string assemblyCode) { Assembler assembler = new Assembler(); Instruction[] instructions = assembler.Assemble(assemblyCode); Memory memory = new Memory(); memory.LoadInstructions(instructions); Registers registers = new Registers(); registers.ValueWrittenToOutputRegister += System.Console.Write; Machine machine = new Machine(memory, registers); machine.Run(25); System.Console.ReadLine(); }
/// <summary> /// Gets all the mods and patches them. /// </summary> private void worker_DoWork(object sender, DoWorkEventArgs e) { _errorLevel = ErrorLevel.NoError; //Gets the list of mods ItemCollection modCollection = null; string lolLocation = null; //Get the data from the UI thread Dispatcher.Invoke(DispatcherPriority.Input, new ThreadStart(() => { modCollection = ModsListBox.Items; lolLocation = LocationTextbox.Text; })); SetStatusLabelAsync("Gathering mods..."); //Gets the list of mods that have been checked. List<LessMod> modsToPatch = new List<LessMod>(); foreach (var x in modCollection) { CheckBox box = (CheckBox)x; bool isBoxChecked = false; Dispatcher.Invoke(DispatcherPriority.Input, new ThreadStart(() => { isBoxChecked = box.IsChecked ?? false; })); if (isBoxChecked) { modsToPatch.Add(_lessMods[box]); } } //Create a new dictionary to hold the SWF definitions in. This stops opening and closing the same SWF file if it's going to be modified more than once. Dictionary<string, SwfFile> swfs = new Dictionary<string, SwfFile>(); //Start the stopwatch to see how long it took to patch (aiming for ~5 sec or less on test machine) timer = Stopwatch.StartNew(); //Go through each modification foreach (var lessMod in modsToPatch) { SetStatusLabelAsync("Patching mod: " + lessMod.Name); //Go through each patch within the mod foreach (var patch in lessMod.Patches) { //If the swf hasn't been loaded, load it into the dictionary. if (!swfs.ContainsKey(patch.Swf)) { string fullPath = Path.Combine(lolLocation, patch.Swf); //Backup the SWF string CurrentLocation = ""; string[] FileLocation = patch.Swf.Split('/', '\\'); foreach (string s in FileLocation.Take(FileLocation.Length - 1)) { CurrentLocation = Path.Combine(CurrentLocation, s); if (!Directory.Exists(Path.Combine(lolLocation, "LESsBackup", BackupVersion, CurrentLocation))) { Directory.CreateDirectory(Path.Combine(lolLocation, "LESsBackup", BackupVersion, CurrentLocation)); } } if (!File.Exists(Path.Combine(lolLocation, "LESsBackup", BackupVersion, patch.Swf))) { File.Copy(Path.Combine(lolLocation, patch.Swf), Path.Combine(lolLocation, "LESsBackup", BackupVersion, patch.Swf)); } swfs.Add(patch.Swf, SwfFile.ReadFile(fullPath)); } //Get the SWF file that is being modified SwfFile swf = swfs[patch.Swf]; //Get the ABC tags (containing the code) from the swf file. List<DoAbcTag> tags = swf.GetDoAbcTags(); bool classFound = false; foreach (var tag in tags) { //check if this tag contains our script ScriptInfo si = tag.GetScriptByClassName(patch.Class); //check next tag if it doesn't if (si == null) continue; ClassInfo cls = si.GetClassByClassName(patch.Class); classFound = true; Assembler asm; //Perform the action based on what the patch defines switch (patch.Action) { case "replace_trait": //replace trait (method) //Load the code from the patch and assemble it to be inserted into the code asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code))); TraitInfo newTrait = asm.Assemble() as TraitInfo; int traitIndex = cls.Instance.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name); bool classTrait = false; if (traitIndex < 0) { traitIndex = cls.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name); classTrait = true; } if (traitIndex < 0) { throw new TraitNotFoundException(String.Format("Can't find trait \"{0}\" in class \"{1}\"", newTrait.Name.Name, patch.Class)); } //Modified the found trait if (classTrait) { cls.Traits[traitIndex] = newTrait; } else { cls.Instance.Traits[traitIndex] = newTrait; } break; case "replace_cinit"://replace class constructor //Load the code from the patch and assemble it to be inserted into the code asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code))); cls.ClassInit = asm.Assemble() as MethodInfo; break; case "replace_iinit"://replace instance constructor //Load the code from the patch and assemble it to be inserted into the code asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code))); cls.Instance.InstanceInit = asm.Assemble() as MethodInfo; break; case "add_class_trait": //add new class trait (method) //Load the code from the patch and assemble it to be inserted into the code asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code))); newTrait = asm.Assemble() as TraitInfo; traitIndex = cls.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name); if (traitIndex < 0) { cls.Traits.Add(newTrait); } else { cls.Traits[traitIndex] = newTrait; } break; case "add_instance_trait": //add new instance trait (method) //Load the code from the patch and assemble it to be inserted into the code asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code))); newTrait = asm.Assemble() as TraitInfo; traitIndex = cls.Instance.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name); if (traitIndex < 0) { cls.Instance.Traits.Add(newTrait); } else { cls.Instance.Traits[traitIndex] = newTrait; } break; case "remove_class_trait": throw new NotImplementedException(); case "remove_instance_trait": throw new NotImplementedException(); default: throw new NotSupportedException($"Unknown Action \"{patch.Action}\" in mod {lessMod.Name}"); } } if (!classFound) { _errorLevel = ErrorLevel.UnableToPatch; throw new ClassNotFoundException($"Class {patch.Class} not found in file {patch.Swf}"); } } } //Save the modified SWFS to their original location foreach (var patchedSwf in swfs) { try { SetStatusLabelAsync("Applying mods: " + patchedSwf.Key); string swfLoc = Path.Combine(lolLocation, patchedSwf.Key); SwfFile.WriteFile(patchedSwf.Value, swfLoc); } catch { _errorLevel = ErrorLevel.GoodJobYourInstallationIsProbablyCorruptedNow; if (Debugger.IsAttached) throw; } } timer.Stop(); }