/// <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; Dispatcher.Invoke(DispatcherPriority.Input, new ThreadStart(() => { modCollection = ModsListBox.Items; })); 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]); } } string lolLocation = null; bool overwrite = true; Dispatcher.Invoke(DispatcherPriority.Input, new ThreadStart(() => { lolLocation = LocationTextbox.Text; })); if (IsGarena) { MessageBox.Show("Garena detected! Please note that you must uninstall LESs before patching your LoL with Garena." + Environment.NewLine + "Otherwise, your Garena LoL patcher will complain hard and we are not responsible for it ;)."); Uri lolRootLocation = new Uri(lolLocation); lolRootLocation = new Uri(lolRootLocation.LocalPath.Replace(lolRootLocation.Segments.Last(), String.Empty)); // Get LoL latest patched date String versionLocation = Path.Combine(lolRootLocation.LocalPath, "lol.version"); if (File.Exists(versionLocation)) { // Store the date in another file. It will be used in LESs removing. File.Copy(versionLocation, Path.Combine(lolRootLocation.LocalPath, "LESs_recent.version"), true); } if (Directory.Exists(Path.Combine(lolLocation, "LESsBackup"))) { MessageBoxResult diagRst = MessageBox.Show("We found that you already have backup files. Overwriting it may result in you losing your original files." + Environment.NewLine + "Would you like to overwrite your old files?", "You already have backup files", MessageBoxButton.YesNo); if (diagRst == MessageBoxResult.No) { overwrite = false; } } } Dictionary <string, SwfFile> swfs = new Dictionary <string, SwfFile>(); Stahpwatch = Stopwatch.StartNew(); foreach (var lessMod in modsToPatch) { Debug.Assert(lessMod.Patches.Length > 0); SetStatusLabelAsync("Patching mod: " + lessMod.Name); foreach (var patch in lessMod.Patches) { 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 (IsGarena) { if (!Directory.Exists(Path.Combine(lolLocation, "LESsBackup", CurrentLocation))) { Directory.CreateDirectory(Path.Combine(lolLocation, "LESsBackup", CurrentLocation)); } if (!File.Exists(Path.Combine(lolLocation, "LESsBackup", patch.Swf))) { if (overwrite) { File.Copy(Path.Combine(lolLocation, patch.Swf), Path.Combine(lolLocation, "LESsBackup", patch.Swf)); } } } else { if (!Directory.Exists(Path.Combine(lolLocation, "LESsBackup", INTENDED_VERSION, CurrentLocation))) { Directory.CreateDirectory(Path.Combine(lolLocation, "LESsBackup", INTENDED_VERSION, CurrentLocation)); } if (!File.Exists(Path.Combine(lolLocation, "LESsBackup", INTENDED_VERSION, patch.Swf))) { File.Copy(Path.Combine(lolLocation, patch.Swf), Path.Combine(lolLocation, "LESsBackup", INTENDED_VERSION, patch.Swf)); } } } swfs.Add(patch.Swf, SwfFile.ReadFile(fullPath)); } SwfFile swf = swfs[patch.Swf]; 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; switch (patch.Action) { case "replace_trait": //replace trait (method) 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)); } if (classTrait) { cls.Traits[traitIndex] = newTrait; } else { cls.Instance.Traits[traitIndex] = newTrait; } break; case "replace_cinit": //replace class constructor asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code))); cls.ClassInit = asm.Assemble() as MethodInfo; break; case "replace_iinit": //replace instance constructor 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) 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) 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(string.Format("Class {0} not found in file {1}", patch.Class, patch.Swf)); } } } //return; 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; } } } Stahpwatch.Stop(); }
/// <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; 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]); } } Dictionary <string, SwfFile> swfs = new Dictionary <string, SwfFile>(); timer = Stopwatch.StartNew(); foreach (var lessMod in modsToPatch) { Debug.Assert(lessMod.Patches.Length > 0); SetStatusLabelAsync("Patching mod: " + lessMod.Name); foreach (var patch in lessMod.Patches) { 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", INTENDED_VERSION, CurrentLocation))) { Directory.CreateDirectory(Path.Combine(lolLocation, "LESsBackup", INTENDED_VERSION, CurrentLocation)); } } if (!File.Exists(Path.Combine(lolLocation, "LESsBackup", INTENDED_VERSION, patch.Swf))) { File.Copy(Path.Combine(lolLocation, patch.Swf), Path.Combine(lolLocation, "LESsBackup", INTENDED_VERSION, patch.Swf)); } swfs.Add(patch.Swf, SwfFile.ReadFile(fullPath)); } SwfFile swf = swfs[patch.Swf]; 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; switch (patch.Action) { case "replace_trait": //replace trait (method) 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)); } if (classTrait) { cls.Traits[traitIndex] = newTrait; } else { cls.Instance.Traits[traitIndex] = newTrait; } break; case "replace_cinit": //replace class constructor asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code))); cls.ClassInit = asm.Assemble() as MethodInfo; break; case "replace_iinit": //replace instance constructor 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) 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) 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(string.Format("Class {0} not found in file {1}", patch.Class, patch.Swf)); } } } //return; 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(); }
/// <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]; if (patch.Action == "replace_swf_character")// replace an swf-character (buttons, sprites, fonts etc.) { ushort charId; if (ushort.TryParse(patch.Class, out charId) && swf.CharacterTags.ContainsKey(charId)) { swf.CharacterTags[charId].SetData(File.ReadAllBytes(Path.Combine(lessMod.Directory, patch.Code))); } else { _errorLevel = ErrorLevel.UnableToPatch; throw new TraitNotFoundException($"<{patch.Class}> is not a valid Character ID."); } } else { //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.FindClass(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.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name, Scope.Instance); bool classTrait = false; if (traitIndex < 0) { traitIndex = cls.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name, Scope.Class); 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.ClassTraits[traitIndex] = newTrait; } else { cls.InstanceTraits[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.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, Scope.Class); if (traitIndex < 0) { cls.ClassTraits.Add(newTrait); } else { cls.ClassTraits[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.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name, Scope.Instance); if (traitIndex < 0) { cls.InstanceTraits.Add(newTrait); } else { cls.InstanceTraits[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(); }