Results 1 to 3 of 3
  1. #1
    twas brillig's Avatar
    Join Date
    Jan 2014
    Gender
    male
    Location
    Southeastern USA
    Posts
    54
    Reputation
    10
    Thanks
    77
    My Mood
    Amused

    Modpack Installer - Need critique and improvements

    Hey guys, I'm new to C# and wanted to post my project and hopefully get some critique and possibly some improvements. It's a program that basically copies certain folders to the game's directory depending on which mods the user selects in the GUI. I made this because most of the users over at the World Of Tanks sub-forum seem to have a hard time installing the mods correctly. I will admit that as a WoT gamer myself, it is definitely much more convenient to use this program.

    [IMG]https://camo.******userconten*****m/2e00d1b2abd08c684228db4ef821605383286a89/687474703a2f2f6a6d656d6d6f6e732e783130686f73742e63 6f6d2f73637265656e5f73686f742e504e47[/IMG]

    View Entire Project


    The entire project is made up of two sections which consist of 5 files. I'm only interested in critique on the Logic side.
    • Logic:
      ├── Modpack_InstallerUI.cs
      ├── Install.cs
    • Information
      ├── About.cs
      ├── BusyWindow.cs
      ├── InstallProgress.cs


    Currently the installer works by having the executable in the same folder as the mods (screenshot below). The installer loops through the users selections and copies the selected folders where they belong. What I would like is to have all the mods in a Zip file and have the program unzip and copy the necessary folders. This is to prevent the user from tampering with the files and possibly breaking the Installer.
    [IMG]https://jmemmons.x10hos*****m/folder_screenshot.PNG[/IMG]

     
    Code:
    using System;
    using System.Collections.Generic;
    using System****;
    
    namespace Mod_Pack_Customizr
    {
        public class Install
        {
            private static string gamePath = "";
            private static List<string> modsList = new List<string>();
    
            // Initiates the copy process.
            public void startInstall(List<string> pathToMods, string pathToInstall)
            {
                modsList = pathToMods;
                gamePath = pathToInstall;
    
                //Copies all the directories and subdirectories under each path in modList.
                foreach (var path in modsList)
                {
                    DirectoryInfo source = new DirectoryInfo(path);
                    DirectoryInfo target = new DirectoryInfo(gamePath);
                    CopyAllDirectories(source, target);
                }
            }
    
            // This method performs the actual installation of the mods to the target directory. It is essentially just copying the mods the user selects 
            // to the target directory.
            private static void CopyAllDirectories(DirectoryInfo source, DirectoryInfo target)
            {
                // Checks if directory exists.
                Directory.CreateDirectory(target.FullName);
    
                // Copy each file into the new directory.
                foreach (FileInfo file in source.GetFiles())
                {
                    file.CopyTo(Path.Combine(target.FullName, file.Name), true);
                    Console.WriteLine(@"Copying {0}\{1}", target.FullName, file.Name);    // For debugging purposes.
                }
    
                // Copy each subdirectory using recursion.
                foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
                {
                    DirectoryInfo nextTargetSubDir =
                        target.CreateSubdirectory(diSourceSubDir.Name);
                    CopyAllDirectories(diSourceSubDir, nextTargetSubDir);
                }
            }
        }
    }



     
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Forms;
    using System****;
    
    namespace Mod_Pack_Customizr
    {
        public partial class Modpack_InstallerUI : Form
        {
            // Global Variables used throughout program.
            public string selectedPath = "";
            private About aboutForm;
            private BusyWindow busyWindow;
    
            public Modpack_InstallerUI()
            {
                InitializeComponent();
            }
    
    
            // This method is the event handler for when the Browse button is clicked. It's main purpose is to allow the user to select the directory they want the mods installed to.
            private void browseButton_Click(object sender, EventArgs e)
            {
                FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
                folderBrowser.Description = "Select the game directory where World of Tanks is located. \n i.e. C:\\Games\\World of Tanks";
                if ((folderBrowser.ShowDialog() == DialogResult.OK) && ContainsResModsFolder(folderBrowser.SelectedPath))
                {
                    selectedPath = folderBrowser.SelectedPath;
                    fileTextBox.AppendText(selectedPath);
                    enableAllCheckboxes();
                } else
                {
                    MessageBox.Show("This is not the correct game directory!");
                }
                
            }
    
    
            // This method enables the install button if one or more mods are selected. All checkboxes use this event handler with the exception of the All in One packs.
            private void handleChecked(object sender, EventArgs e)
            {
                // At least one checkbox is checked.
                if (modGroupBo*****ntrols.OfType<CheckBox>().Any(x => x.Checked))
                {
                    installButton.Enabled = true;
                }
                else
                {
                    installButton.Enabled = false;
                }
            }
    
    
            // This method loops through all the checkboxes and enables them based on some criteria. If a user selects the All in One mod, it's important
            // that we disable all of the other choices to keep from possible crashes. All checkboxes are disabled by default at program runtime so they need
            // to be enabled.
            private void enableAllCheckboxes()
            {
                foreach (var x in modGroupBo*****ntrols)
                {
                    var checkbox = x as CheckBox;
    
                    if ((checkbox.Checked == true) && (checkbox.TabIndex == 0))
                        continue;
    
                    if ((checkbox.Checked == true) && (checkbox.TabIndex == 1))
                    {
                        allInOneCheckbox.Enabled = true;
                        continue;
                    }
    
                    checkbox.Enabled = true;
                }
            }
    
    
            // This method loops through all the checkboxes and disables them based on some criteria. If a user selects the All in One mod, it's important
            // that we disable all of the other choices to keep from possible crashes. All checkboxes are already disabled at program runtime.
            private void disableAllCheckboxes()
            {
                foreach (var x in modGroupBo*****ntrols)
                {
                    var checkbox = x as CheckBox;
    
                    // If "All in One - with XVM" is checked, skip this iteration.
                    if ((checkbox.Checked == true) && (checkbox.TabIndex == 0))
                        continue;
    
                    // If "All in One - without XVM" is checked, disable other All in One mod and continue to the next checkbox.
                    if ((checkbox.Checked == true) && (checkbox.TabIndex == 1))
                    {
                        allInOneCheckbox.Enabled = false;
                        continue;
                    }
    
                    checkbox.Enabled = false;
                }
            }
    
    
            // This method loops through all the checkboxes and unchecks all of them. This operation is run after the installation is finished.
            private void uncheckAllBoxes()
            {
                foreach (var x in modGroupBo*****ntrols)
                {
                    var checkbox = x as CheckBox;
                    if (checkbox.Checked)
                        checkbox.Checked = false;
                }
            }
    
    
            // This method disables all other mods from being selected since the All In One essentially contains all of the other mods.
            private void allInOneCheckbox_CheckedChanged(object sender, EventArgs e)
            {
                if (allInOneCheckbox.Checked)
                {
                    disableAllCheckboxes();
                    // Uncheck all other boxes.
                    foreach (var x in modGroupBo*****ntrols)
                    {
                        var checkbox = x as CheckBox;
                        if (checkbox.Checked && checkbox.TabIndex == 0)
                            continue;
                        else
                            checkbox.Checked = false;
                    }
                    installButton.Enabled = true;
                }
                else
                {
                    enableAllCheckboxes();
                    installButton.Enabled = false;
                }
            }
    
    
            // This method disables the ability to check other boxes when this item is selected.
            private void allInOneWithoutXVMCheckbox_CheckedChanged(object sender, EventArgs e)
            {
                if (allInOneWithoutXVMCheckbox.Checked)
                {
                    disableAllCheckboxes();
    
                    // Uncheck all other boxes.
                    foreach (var x in modGroupBo*****ntrols)
                    {
                        var checkbox = x as CheckBox;
                        if (checkbox.Checked && checkbox.TabIndex == 1)
                            continue;
                        else
                            checkbox.Checked = false;
                    }
                    installButton.Enabled = true;
                }
                else
                {
                    enableAllCheckboxes();
                    installButton.Enabled = false;
                }
            }
    
    
            // Loops through all the checkboxes in modGroupBox and returns a string for each result that is checked. This is used in the DialogBox when the user clicks Install.
            private string selectedModStrings()
            {
                string str = "";
                foreach (Control c in modGroupBo*****ntrols)
                {
                    if ((c is CheckBox) && ((CheckBox)c).Checked)
                        str += c.Text + "\n";
                }
                return str + "\n";
            }
    
    
            // This method gets all the selected mods and creates a path for each one so that it can later be used to copy folders and subdirectories.
            public List<string> getSelectedMods()
            {
                List<string> modList = new List<string>();
                foreach (Control c in modGroupBo*****ntrols)
                {
                    // Creates path names based on selected mods and adds it to the list.
                    if ((c is CheckBox) && ((CheckBox)c).Checked)
                        modList.Add(Application.StartupPath + "\\" + c.Text);
                }
                return modList;
            }
    
    
            // This method is called when installing and uninstalling mods. It deletes all data in the res_mods folder to ensure that it won't have peices left over from a previous mod install.
            private void deleteAllFiles(string pathToDelete)
            {
                System****.DirectoryInfo directoryInfo = new DirectoryInfo(pathToDelete);
                
                foreach (FileInfo file in directoryInfo.GetFiles())
                    file.Delete();
    
                foreach (DirectoryInfo dir in directoryInfo.GetDirectories())
                    dir.Delete(true);
            }
    
    
            // Once the background worker is finished, this method is called.
            private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else
                {
                    MessageBox.Show("Install Completed!");
                    busyWindow.Dispose();
                    uncheckAllBoxes();
                }
            }
    
    
            // This is the method that is where the installation is triggered. It creates a constructor the Install and sends it the necessary parameters to begin the installation.
            private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                // Constructor for the Install object which performs the installation.
                Install installMod = new Install();
    
                // Install class requires two parameters to install mod. Argument 1 = path of selected mods. Argument 2 = path of game directory.
                List<object> argumentList = e.Argument as List<object>;
                List<string> argument1 = (List<string>)argumentList[0];
                string argument2 = (string)argumentList[1];
    
                // Starts the installation process.
                installMod.startInstall(argument1, argument2);
            }
    
    
            // This is the event handler for when the user chooses to install the mods.
            private void installButton_Click(object sender, EventArgs e)
            {
                // Show the user which mods they selected and where it will be installed so they can decide if they want to continue.
                string messageBoxText = "The Mods you have selected:\n\n" + selectedModStrings() +
                    "Now going to install the mods in the \"" + selectedPath + "\" directory. Do you want to continue?";
                DialogResult result = MessageBox.Show(messageBoxText, "Mod Installation", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == DialogResult.Yes)
                {
                    // Set up background worker object and connect handlers.
                    BackgroundWorker bgWorker = new BackgroundWorker();
                    bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
    
                    // Since a BackgroundWorker only takes 1 parameter and our Install function requires 2, I have placed both parameters into a List object.
                    // The DoWork method will extract the two arguments when RunWorkerAsync is called.
                    List<object> arguments = new List<object>();
                    arguments.Add(getSelectedMods());
                    arguments.Add(selectedPath);
    
                    // Launch background thread.
                    bgWorker.RunWorkerAsync(arguments);
    
                    // Show the user that something is happening. The RunWorkerCompleted method will dispose this window when the installation is complete.
                    busyWindow = new BusyWindow();
                    busyWindow.ShowDialog();
                }
                else
                {
                    uncheckAllBoxes();
                }
            }
    
    
            // This method uninstalls all previous mods in the res_mods folder.
            private void uninstallAllModsToolStripMenuItem_Click(object sender, EventArgs e)
            {
                // Must have a game path selected.
                if (selectedPath == null)
                {
                    string message = "Please select your World Of Tanks game directory.";
                    DialogResult uninstallDialog = MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
    
                // Start the uninstall of mods.
                else
                {
                    // Make sure this really is the correct folder.
                    if (ContainsResModsFolder(selectedPath))
                    {
                        string resModsPath= selectedPath + "\\res_mods";
                        string resAudioPath = selectedPath + "\\res\\audio";
                        deleteAllFiles(resModsPath);
                        deleteAllFiles(resAudioPath);
    
                        // TODO: Let the user know something actually happened.
                        //busyWindow = new BusyWindow();
                        //busyWindow.ShowDialog();
                    }
                    else
                    {
                        string errorMessage = "This doesn't appear to be the correct World Of Games directory.";
                        DialogResult errorDialog = MessageBox.Show(errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    }
                }
            }
    
    
            // Returns true if the selected directory is the actual World Of Tanks directory.
            private bool ContainsResModsFolder(string path)
            {
                DirectoryInfo gamePath = new DirectoryInfo(path);
                DirectoryInfo[] test = gamePath.GetDirectories();
                if (test.Any(r => r.FullName.Equals(Path.Combine(gamePath.FullName, "res_mods"))))
                {
                    return true;
                }
                return false;
            }
    
    
            // Exits the application when clicked.
            private void exitToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
    
    
            // Opens the About form which contains basic information about the program.
            private void aboutToolstripMenuItem_Click(object sender, EventArgs e)
            {
                aboutForm = new About();
                aboutForm.Show();
            }
        }
    }


    If you do make some improvements to the code, be sure to add your name under the Contributors section in the README on ****** so you can get proper credit.
    Software Developer, Educator, and Gamer.

  2. The Following User Says Thank You to twas brillig For This Useful Post:

    tiger snacks (06-13-2016)

  3. #2
    Sammy's Avatar
    Join Date
    Mar 2016
    Gender
    male
    Location
    Vaero
    Posts
    1,098
    Reputation
    224
    Thanks
    228
    Great to see you are going open source, so others can learn too. Unfortunately nobody is moderating it so there is no point in releasing the program.
    @twas brillig

  4. The Following User Says Thank You to Sammy For This Useful Post:

    twas brillig (06-15-2016)

  5. #3
    twas brillig's Avatar
    Join Date
    Jan 2014
    Gender
    male
    Location
    Southeastern USA
    Posts
    54
    Reputation
    10
    Thanks
    77
    My Mood
    Amused
    Quote Originally Posted by Sir Sam View Post
    Great to see you are going open source, so others can learn too. Unfortunately nobody is moderating it so there is no point in releasing the program.
    @twas brillig
    I appreciate the response. My program is included in all the mod packs so if any of the gamers want to contribute they know where to go.
    Software Developer, Educator, and Gamer.

Similar Threads

  1. Replies: 0
    Last Post: 01-19-2013, 10:14 AM
  2. Hopefully hard to detect hacks - need volunteers and testers
    By bagpiperdude90 in forum WarRock - International Hacks
    Replies: 8
    Last Post: 08-25-2007, 03:51 PM
  3. For all who need helps and n00bs that want start to create hack easily
    By idiot123 in forum WarRock - International Hacks
    Replies: 1
    Last Post: 08-20-2007, 11:05 AM
  4. Need Values And Tips For Making Trainer
    By jokuvaan11 in forum WarRock - International Hacks
    Replies: 6
    Last Post: 06-06-2007, 11:37 AM
  5. Need hacks and Bypass
    By Alexej1133 in forum WarRock - International Hacks
    Replies: 11
    Last Post: 06-03-2007, 05:47 PM