private void CopyToClient(WorstHack data)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                StatusLabel.Content = "Patched " + data.FileName + "!";
            }));

            File.Copy(Path.Combine("temp", data.FileLocation.Replace(".dat", ""), data.FileName), Path.Combine(data.LocationText, data.FileLocation), true);
        }
        private void CopyToClient(WorstHack data)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                StatusLabel.Content = "Patched " + data.FileName + "!";
            }));

            File.Copy(Path.Combine("temp", data.FileLocation.Replace(".dat", ""), data.FileName), Path.Combine(data.LocationText, data.FileLocation), true);
        }
        private void Repackage(WorstHack data)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                StatusLabel.Content = "Patching mods to client...";
            }));

            string AbcNumber = data.ReAssembleLocation.Substring(data.ReAssembleLocation.IndexOf('-')).Replace("-", "").Replace("\\", "");

            ProcessStartInfo ReAsm = new ProcessStartInfo();

            ReAsm.FileName = "rabcasm.exe";
            ReAsm.RedirectStandardError = true;
            ReAsm.UseShellExecute       = false;
            ReAsm.CreateNoWindow        = true;
            ReAsm.Arguments             = Path.Combine("temp", data.ReAssembleLocation + data.FileName.Replace(".dat", "") + "-" + AbcNumber + ".main.asasm");
            var ReAsmProc = Process.Start(ReAsm);

            while (ReAsmProc != null && !ReAsmProc.StandardError.EndOfStream)
            {
                string line = ReAsmProc.StandardError.ReadLine();
                File.AppendAllText("debug.log", line + Environment.NewLine);
            }
            if (ReAsmProc != null)
            {
                ReAsmProc.WaitForExit();
            }

            ProcessStartInfo DoPatch = new ProcessStartInfo();

            DoPatch.FileName = "abcreplace.exe";
            DoPatch.RedirectStandardError = true;
            DoPatch.UseShellExecute       = false;
            DoPatch.CreateNoWindow        = true;
            DoPatch.Arguments             = Path.Combine("temp", data.FileLocation.Replace(".dat", ""), data.FileName) + " " + AbcNumber + " " + Path.Combine("temp", data.ReAssembleLocation + data.FileName.Replace(".dat", "") + "-" + AbcNumber + ".main.abc");
            var FinalPatchProc = Process.Start(DoPatch);

            while (FinalPatchProc != null && !FinalPatchProc.StandardError.EndOfStream)
            {
                string line = FinalPatchProc.StandardError.ReadLine();
                File.AppendAllText("debug.log", line + Environment.NewLine);
            }
            if (FinalPatchProc != null)
            {
                FinalPatchProc.WaitForExit();
            }
        }
        private void Repackage(WorstHack data)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                StatusLabel.Content = "Patching mods to client...";
            }));

            string AbcNumber = data.ReAssembleLocation.Substring(data.ReAssembleLocation.IndexOf('-')).Replace("-", "").Replace("\\", "");

            ProcessStartInfo ReAsm = new ProcessStartInfo();
            ReAsm.FileName = "rabcasm.exe";
            ReAsm.RedirectStandardError = true;
            ReAsm.UseShellExecute = false;
            ReAsm.CreateNoWindow = true;
            ReAsm.Arguments = Path.Combine("temp", data.ReAssembleLocation + data.FileName.Replace(".dat", "") + "-" + AbcNumber + ".main.asasm");
            var ReAsmProc = Process.Start(ReAsm);
            while (ReAsmProc != null && !ReAsmProc.StandardError.EndOfStream)
            {
                string line = ReAsmProc.StandardError.ReadLine();
                File.AppendAllText("debug.log", line + Environment.NewLine);
            }
            if (ReAsmProc != null)
            {
                ReAsmProc.WaitForExit();
            }

            ProcessStartInfo DoPatch = new ProcessStartInfo();
            DoPatch.FileName = "abcreplace.exe";
            DoPatch.RedirectStandardError = true;
            DoPatch.UseShellExecute = false;
            DoPatch.CreateNoWindow = true;
            DoPatch.Arguments = Path.Combine("temp", data.FileLocation.Replace(".dat", ""), data.FileName) + " " + AbcNumber + " " + Path.Combine("temp", data.ReAssembleLocation + data.FileName.Replace(".dat", "") + "-" + AbcNumber + ".main.abc");
            var FinalPatchProc = Process.Start(DoPatch);
            while (FinalPatchProc != null && !FinalPatchProc.StandardError.EndOfStream)
            {
                string line = FinalPatchProc.StandardError.ReadLine();
                File.AppendAllText("debug.log", line + Environment.NewLine);
            }
            if (FinalPatchProc != null)
            {
                FinalPatchProc.WaitForExit();
            }
        }
        private void Patcher(string ModName, int AmountOfPatches)
        {
            string PatchNumber = "";
            if (AmountOfPatches >= 1)
                PatchNumber = AmountOfPatches.ToString();

            string[] ModDetails = File.ReadAllLines(Path.Combine("mods", ModName, "patch" + PatchNumber + ".txt"));
            string FileLocation = "null";
            string TryFindClass = "null";
            string TraitToModify = "null";
            bool IsNewTrait = false;
            foreach (string s in ModDetails)
            {
                if (s.StartsWith("#"))
                {
                    TryFindClass = s.Substring(1);
                }
                else if (s.StartsWith("@@@"))
                {
                    TraitToModify = s.Substring(3);
                }
                else if (s.StartsWith("@+@"))//Insert the new trait above this one
                {
                    TraitToModify = s.Substring(3);
                    IsNewTrait = true;
                }
                else if (s.StartsWith("~"))
                {
                    FileLocation = s.Substring(1);
                }
            }

            File.AppendAllText("debug.log", "Patching " + ModName + PatchNumber + Environment.NewLine);

            string[] FilePart = FileLocation.Split('/');
            string FileName = FilePart[FilePart.Length - 1];

            string LocationText = "";
            Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                LocationText = LocationTextbox.Text;
            }));

            //Wait for UI thread to respond...
            while (String.IsNullOrEmpty(LocationText))
                ;

            if (!Directory.Exists(Path.Combine("temp", FileLocation.Replace(".dat", ""))))
            {
                Directory.CreateDirectory(Path.Combine("temp", FileLocation.Replace(".dat", "")));

                string n = "";
                foreach (string s in FilePart.Take(FilePart.Length - 1))
                {
                    n = Path.Combine(n, s);
                    if (!Directory.Exists(Path.Combine(LocationText, "LESsBackup", IntendedVersion, n)))
                    {
                        Directory.CreateDirectory(Path.Combine(LocationText, "LESsBackup", IntendedVersion, n));
                    }
                }
                if (!File.Exists(Path.Combine(LocationText, "LESsBackup", IntendedVersion, FileLocation)))
                {
                    File.Copy(Path.Combine(LocationText, FileLocation), Path.Combine(LocationText, "LESsBackup", IntendedVersion, FileLocation));
                }

                File.Copy(Path.Combine(LocationText, FileLocation), Path.Combine("temp", FileLocation.Replace(".dat", ""), FileName));

                Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
                {
                    StatusLabel.Content = "Exporting patch " + ModName;
                }));

                File.AppendAllText("debug.log", "Running abcexport" + Environment.NewLine);

                ProcessStartInfo Export = new ProcessStartInfo();
                Export.FileName = "abcexport.exe";
                Export.CreateNoWindow = true;
                Export.UseShellExecute = false;
                Export.Arguments = Path.Combine("temp", FileLocation.Replace(".dat", ""), FileName);
                var ExportProc = Process.Start(Export);
                if (ExportProc != null)
                {
                    ExportProc.WaitForExit();
                }

                Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
                {
                    StatusLabel.Content = "Disassembling patch (" + ModName + ")";
                }));

                string[] ABCFiles = Directory.GetFiles(Path.Combine("temp", FileLocation.Replace(".dat", "")), "*.abc");

                File.AppendAllText("debug.log", "Got " + ABCFiles.Length + " files" + Environment.NewLine);

                foreach (string s in ABCFiles)
                {
                    ProcessStartInfo Disassemble = new ProcessStartInfo();
                    Disassemble.FileName = "rabcdasm.exe";
                    Disassemble.Arguments = s;
                    Disassemble.UseShellExecute = false;
                    Disassemble.CreateNoWindow = true;
                    var DisasmProc = Process.Start(Disassemble);
                    if (DisasmProc != null)
                    {
                        DisasmProc.WaitForExit();
                    }
                }
            }

            if (TryFindClass.IndexOf(':') == 0)
            {
                File.AppendAllText("debug.log", "INVALID MOD!!!" + Environment.NewLine);
                throw new Exception("Invalid mod " + ModName);
            }

            List<string> directories = Directory.GetDirectories(Path.Combine("temp", FileLocation.Replace(".dat", "")), "*", SearchOption.AllDirectories).ToList();

            //Get all directories that match the requested class to modify
            string SearchFor = TryFindClass.Substring(0, TryFindClass.IndexOf(':'));
            List<string> FoundDirectories = new List<string>();
            foreach (string s in directories)
            {
                if (!s.Contains("com"))
                    continue;

                string tempS = s;
                tempS = tempS.Substring(tempS.IndexOf("com"));
                tempS = tempS.Replace("\\", ".");
                if (tempS == SearchFor)
                {
                    FoundDirectories.Add(s);
                }
            }

            if (FoundDirectories.Count == 0)
            {
                File.AppendAllText("debug.log", "No class matching " + SearchFor + " for mod " + ModName + Environment.NewLine);
                throw new Exception("No class matching " + SearchFor + " for mod " + ModName);
            }

            string FinalDirectory = "";
            string Class = TryFindClass.Substring(TryFindClass.IndexOf(':')).Replace(":", "");
            //Find the directory that has the requested class
            foreach (string s in FoundDirectories)
            {
                string[] m = Directory.GetFiles(s);
                string x = Path.Combine(s, Class + ".class.asasm");
                if (m.Contains(x))
                {
                    FinalDirectory = s;
                }
            }

            string[] ClassModifier = File.ReadAllLines(Path.Combine(FinalDirectory, Class + ".class.asasm"));

            //return if the new trait already exists
            if (IsNewTrait)
            {
                foreach (string l in ClassModifier)
                {
                    if (l == ModDetails[3])
                        return;
                }
            }

            int TraitStartPosition = 0;
            int TraitEndLocation = 0;
            //Get location of trait
            for (int i = 0; i < ClassModifier.Length; i++)
            {
                if (ClassModifier[i] == TraitToModify)
                {
                    TraitStartPosition = i;
                    break;
                }
            }

            if (TraitStartPosition == 0)
            {
                File.AppendAllText("debug.log", "Trait start location was not found! Corrupt mod?");
                throw new Exception("Trait start location was not found! Corrupt mod?");
            }

            if (!IsNewTrait)
            {
                //Get end location of trait
                for (int i = TraitStartPosition; i < ClassModifier.Length; i++)
                {
                    if (ClassModifier[i].Trim() == "end ; method")
                    {
                        if (ClassModifier[i + 1].Trim() == "end ; trait")
                        {
                            TraitEndLocation = i + 2;
                        }
                        else
                        {
                            TraitEndLocation = i + 1;
                        }
                        break;
                    }
                }

                if (TraitEndLocation < TraitStartPosition)
                {
                    File.AppendAllText("debug.log", "Trait end location was smaller than trait start location! " + TraitEndLocation + ", " + TraitStartPosition);
                    throw new Exception("Trait end location was smaller than trait start location! " + TraitEndLocation + ", " + TraitStartPosition);
                }

                string[] StartTrait = new string[TraitStartPosition];
                Array.Copy(ClassModifier, StartTrait, TraitStartPosition);
                string[] AfterTrait = new string[ClassModifier.Length - TraitEndLocation];
                Array.Copy(ClassModifier, TraitEndLocation, AfterTrait, 0, ClassModifier.Length - TraitEndLocation);

                string[] FinalClass = new string[StartTrait.Length + (ModDetails.Length - 3) + AfterTrait.Length];
                Array.Copy(StartTrait, FinalClass, TraitStartPosition);
                Array.Copy(ModDetails, 3, FinalClass, TraitStartPosition, (ModDetails.Length - 3));
                Array.Copy(AfterTrait, 0, FinalClass, TraitStartPosition + (ModDetails.Length - 3), AfterTrait.Length);

                File.Delete(Path.Combine(FinalDirectory, Class + ".class.asasm"));
                File.WriteAllLines(Path.Combine(FinalDirectory, Class + ".class.asasm"), FinalClass);
            }
            else
            {
                string[] FinalClass = new string[ClassModifier.Length + (ModDetails.Length - 3)];
                Array.Copy(ClassModifier, 0, FinalClass, 0, TraitStartPosition);
                Array.Copy(ModDetails, 3, FinalClass, TraitStartPosition, ModDetails.Length - 3);
                Array.Copy(ClassModifier, TraitStartPosition, FinalClass, TraitStartPosition + ModDetails.Length - 3, ClassModifier.Length - TraitStartPosition);

                File.Delete(Path.Combine(FinalDirectory, Class + ".class.asasm"));
                File.WriteAllLines(Path.Combine(FinalDirectory, Class + ".class.asasm"), FinalClass);
            }

            WorstHack h = new WorstHack();
            h.FileName = FileName;
            h.LocationText = LocationText;
            h.ReAssembleLocation = FinalDirectory.Substring(0, FinalDirectory.IndexOf("com")).Replace("temp\\", "");
            h.FileLocation = FileLocation;

            if (!ReassembleLocations.Contains(h))
                ReassembleLocations.Add(h);
        }
        private void Patcher(string ModName, int AmountOfPatches)
        {
            string PatchNumber = "";

            if (AmountOfPatches >= 1)
            {
                PatchNumber = AmountOfPatches.ToString();
            }

            string[] ModDetails    = File.ReadAllLines(Path.Combine("mods", ModName, "patch" + PatchNumber + ".txt"));
            string   FileLocation  = "null";
            string   TryFindClass  = "null";
            string   TraitToModify = "null";
            bool     IsNewTrait    = false;

            foreach (string s in ModDetails)
            {
                if (s.StartsWith("#"))
                {
                    TryFindClass = s.Substring(1);
                }
                else if (s.StartsWith("@@@"))
                {
                    TraitToModify = s.Substring(3);
                }
                else if (s.StartsWith("@+@"))//Insert the new trait above this one
                {
                    TraitToModify = s.Substring(3);
                    IsNewTrait    = true;
                }
                else if (s.StartsWith("~"))
                {
                    FileLocation = s.Substring(1);
                }
            }

            File.AppendAllText("debug.log", "Patching " + ModName + PatchNumber + Environment.NewLine);

            string[] FilePart = FileLocation.Split('/');
            string   FileName = FilePart[FilePart.Length - 1];

            string LocationText = "";

            Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                LocationText = LocationTextbox.Text;
            }));

            //Wait for UI thread to respond...
            while (String.IsNullOrEmpty(LocationText))
            {
                ;
            }

            if (!Directory.Exists(Path.Combine("temp", FileLocation.Replace(".dat", ""))))
            {
                Directory.CreateDirectory(Path.Combine("temp", FileLocation.Replace(".dat", "")));

                string n = "";
                foreach (string s in FilePart.Take(FilePart.Length - 1))
                {
                    n = Path.Combine(n, s);
                    if (!Directory.Exists(Path.Combine(LocationText, "LESsBackup", IntendedVersion, n)))
                    {
                        Directory.CreateDirectory(Path.Combine(LocationText, "LESsBackup", IntendedVersion, n));
                    }
                }
                if (!File.Exists(Path.Combine(LocationText, "LESsBackup", IntendedVersion, FileLocation)))
                {
                    File.Copy(Path.Combine(LocationText, FileLocation), Path.Combine(LocationText, "LESsBackup", IntendedVersion, FileLocation));
                }

                File.Copy(Path.Combine(LocationText, FileLocation), Path.Combine("temp", FileLocation.Replace(".dat", ""), FileName));

                Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
                {
                    StatusLabel.Content = "Exporting patch " + ModName;
                }));

                File.AppendAllText("debug.log", "Running abcexport" + Environment.NewLine);

                ProcessStartInfo Export = new ProcessStartInfo();
                Export.FileName        = "abcexport.exe";
                Export.CreateNoWindow  = true;
                Export.UseShellExecute = false;
                Export.Arguments       = Path.Combine("temp", FileLocation.Replace(".dat", ""), FileName);
                var ExportProc = Process.Start(Export);
                if (ExportProc != null)
                {
                    ExportProc.WaitForExit();
                }

                Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
                {
                    StatusLabel.Content = "Disassembling patch (" + ModName + ")";
                }));

                string[] ABCFiles = Directory.GetFiles(Path.Combine("temp", FileLocation.Replace(".dat", "")), "*.abc");

                File.AppendAllText("debug.log", "Got " + ABCFiles.Length + " files" + Environment.NewLine);

                foreach (string s in ABCFiles)
                {
                    ProcessStartInfo Disassemble = new ProcessStartInfo();
                    Disassemble.FileName        = "rabcdasm.exe";
                    Disassemble.Arguments       = s;
                    Disassemble.UseShellExecute = false;
                    Disassemble.CreateNoWindow  = true;
                    var DisasmProc = Process.Start(Disassemble);
                    if (DisasmProc != null)
                    {
                        DisasmProc.WaitForExit();
                    }
                }
            }

            if (TryFindClass.IndexOf(':') == 0)
            {
                File.AppendAllText("debug.log", "INVALID MOD!!!" + Environment.NewLine);
                throw new Exception("Invalid mod " + ModName);
            }

            List <string> directories = Directory.GetDirectories(Path.Combine("temp", FileLocation.Replace(".dat", "")), "*", SearchOption.AllDirectories).ToList();

            //Get all directories that match the requested class to modify
            string        SearchFor        = TryFindClass.Substring(0, TryFindClass.IndexOf(':'));
            List <string> FoundDirectories = new List <string>();

            foreach (string s in directories)
            {
                if (!s.Contains("com"))
                {
                    continue;
                }

                string tempS = s;
                tempS = tempS.Substring(tempS.IndexOf("com"));
                tempS = tempS.Replace("\\", ".");
                if (tempS == SearchFor)
                {
                    FoundDirectories.Add(s);
                }
            }

            if (FoundDirectories.Count == 0)
            {
                File.AppendAllText("debug.log", "No class matching " + SearchFor + " for mod " + ModName + Environment.NewLine);
                throw new Exception("No class matching " + SearchFor + " for mod " + ModName);
            }

            string FinalDirectory = "";
            string Class          = TryFindClass.Substring(TryFindClass.IndexOf(':')).Replace(":", "");

            //Find the directory that has the requested class
            foreach (string s in FoundDirectories)
            {
                string[] m = Directory.GetFiles(s);
                string   x = Path.Combine(s, Class + ".class.asasm");
                if (m.Contains(x))
                {
                    FinalDirectory = s;
                }
            }

            string[] ClassModifier = File.ReadAllLines(Path.Combine(FinalDirectory, Class + ".class.asasm"));

            //return if the new trait already exists
            if (IsNewTrait)
            {
                foreach (string l in ClassModifier)
                {
                    if (l == ModDetails[3])
                    {
                        return;
                    }
                }
            }

            int TraitStartPosition = 0;
            int TraitEndLocation   = 0;

            //Get location of trait
            for (int i = 0; i < ClassModifier.Length; i++)
            {
                if (ClassModifier[i] == TraitToModify)
                {
                    TraitStartPosition = i;
                    break;
                }
            }

            if (TraitStartPosition == 0)
            {
                File.AppendAllText("debug.log", "Trait start location was not found! Corrupt mod?");
                throw new Exception("Trait start location was not found! Corrupt mod?");
            }

            if (!IsNewTrait)
            {
                //Get end location of trait
                for (int i = TraitStartPosition; i < ClassModifier.Length; i++)
                {
                    if (ClassModifier[i].Trim() == "end ; method")
                    {
                        if (ClassModifier[i + 1].Trim() == "end ; trait")
                        {
                            TraitEndLocation = i + 2;
                        }
                        else
                        {
                            TraitEndLocation = i + 1;
                        }
                        break;
                    }
                }

                if (TraitEndLocation < TraitStartPosition)
                {
                    File.AppendAllText("debug.log", "Trait end location was smaller than trait start location! " + TraitEndLocation + ", " + TraitStartPosition);
                    throw new Exception("Trait end location was smaller than trait start location! " + TraitEndLocation + ", " + TraitStartPosition);
                }

                string[] StartTrait = new string[TraitStartPosition];
                Array.Copy(ClassModifier, StartTrait, TraitStartPosition);
                string[] AfterTrait = new string[ClassModifier.Length - TraitEndLocation];
                Array.Copy(ClassModifier, TraitEndLocation, AfterTrait, 0, ClassModifier.Length - TraitEndLocation);

                string[] FinalClass = new string[StartTrait.Length + (ModDetails.Length - 3) + AfterTrait.Length];
                Array.Copy(StartTrait, FinalClass, TraitStartPosition);
                Array.Copy(ModDetails, 3, FinalClass, TraitStartPosition, (ModDetails.Length - 3));
                Array.Copy(AfterTrait, 0, FinalClass, TraitStartPosition + (ModDetails.Length - 3), AfterTrait.Length);

                File.Delete(Path.Combine(FinalDirectory, Class + ".class.asasm"));
                File.WriteAllLines(Path.Combine(FinalDirectory, Class + ".class.asasm"), FinalClass);
            }
            else
            {
                string[] FinalClass = new string[ClassModifier.Length + (ModDetails.Length - 3)];
                Array.Copy(ClassModifier, 0, FinalClass, 0, TraitStartPosition);
                Array.Copy(ModDetails, 3, FinalClass, TraitStartPosition, ModDetails.Length - 3);
                Array.Copy(ClassModifier, TraitStartPosition, FinalClass, TraitStartPosition + ModDetails.Length - 3, ClassModifier.Length - TraitStartPosition);

                File.Delete(Path.Combine(FinalDirectory, Class + ".class.asasm"));
                File.WriteAllLines(Path.Combine(FinalDirectory, Class + ".class.asasm"), FinalClass);
            }

            WorstHack h = new WorstHack();

            h.FileName           = FileName;
            h.LocationText       = LocationText;
            h.ReAssembleLocation = FinalDirectory.Substring(0, FinalDirectory.IndexOf("com")).Replace("temp\\", "");
            h.FileLocation       = FileLocation;

            if (!ReassembleLocations.Contains(h))
            {
                ReassembleLocations.Add(h);
            }
        }