private void btnPatchBattlePack_Click(object sender, EventArgs e)
        {
            if (!TEMP_SETTINGS.CanPatchPacks)
            {
                LogOut("Error: Can not pack packs folder - unpack packs.zib again!");
                return;
            }

            //Read the 5 .ydk decks, patch the file, pack packs.zib again, copy it to working directory
            LogOut("Reading .json/.ydk files, please be patient...", Color.Blue);
            string[] files = Directory.GetFiles(CONSTANTS.ADD_PACKS_FOLDER);
            List <List <YGOPROCard> > list_of_card_lists = new List <List <YGOPROCard> >();

            foreach (string filename in files)
            {
                if (ChosenPacks[filename.Split('\\')[1]] == false)
                {
                    continue;
                }

                List <YGOPROCard> cards = new List <YGOPROCard>();
                if (filename.Contains(CONSTANTS.YDK_EXTENSION))
                {
                    cards = FileUtilities.parseCardListFromYDKFile(filename, CONSTANTS.CARD_DB_FILENAME, CONSTANTS.CARDS_NOT_AVAILABLE);
                }
                else if (filename.Contains(CONSTANTS.JSON_EXTENSION))
                {
                    cards = FileUtilities.cardsFromJSON(filename, CONSTANTS.CARD_DB_FILENAME, chkJSONRarity.Checked);
                }
                else if (filename.Contains(CONSTANTS.YDC_EXTENSION))
                {
                    try
                    {
                        byte[] ydc_binary = FileUtilities.parseCardListMainExtraSideFromYDCFile(filename);
                        var    list_of_main_extra_side = FileUtilities.YDCToYGOPRODeck(ydc_binary,
                                                                                       FileUtilities.ReverseDict(FileUtilities.GetCardIDToLOTDMapFromCSV(CONSTANTS.CSV_MAP_FILENAME)),
                                                                                       CONSTANTS.CARD_DB_FILENAME);
                        foreach (var deck in list_of_main_extra_side)
                        {
                            cards.AddRange(deck);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogOut("Error: couldn't read " + filename + " for pack data!");
                        continue;
                    }
                }
                else
                {
                    LogOut("Error: didn't recognize extension of " + filename + " as a valid draft pack file!");
                    continue;
                }

                list_of_card_lists.Add(cards);
            }

            if (list_of_card_lists.Count == 0)
            {
                LogOut("Error: no packs selected - please select at least 1!");
                return;
            }

            var card_name_to_LOTD_ID = FileUtilities.GetCardIDToLOTDMapFromCSV(CONSTANTS.CSV_MAP_FILENAME);

            LogOut(FileUtilities.WriteBattlePackBinFile(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, CONSTANTS.BATTLEPACK_1_FILENAME),
                                                        CONSTANTS.BATTLEPACK_NUM_CATEGORIES, list_of_card_lists, card_name_to_LOTD_ID));

            LogOut("Created " + Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, CONSTANTS.BATTLEPACK_1_FILENAME) + " successfully!");
            //Copy it to the working folder
            File.Copy(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, CONSTANTS.BATTLEPACK_1_FILENAME),
                      Path.Combine(CONSTANTS.YGODATA_PACKS + CONSTANTS.UNPACKED_SUFFIX, CONSTANTS.BATTLEPACK_1_FILENAME), true);

            LogOut("Copied the battlepack to the unpacked folder.", Color.Blue);

            LogOut(Cyclone.PackZibFile(CONSTANTS.YGODATA_PACKS + CONSTANTS.UNPACKED_SUFFIX,
                                       Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, CONSTANTS.YGODATA_PACKS)));

            //Copy it to the YGODATA folder
            File.Copy(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, CONSTANTS.YGODATA_PACKS),
                      Path.Combine(CONSTANTS.YGO_DATA_WORKING_FOLDER, CONSTANTS.YGODATA_PACKS), true);

            LogOut("Copied " + CONSTANTS.YGODATA_PACKS + " to " + CONSTANTS.YGO_DATA_WORKING_FOLDER + ".", Color.Blue);
        }
        private void btnPatchAIDraftDecks_Click(object sender, EventArgs e)
        {
            if (!TEMP_SETTINGS.CanPatchDecks)
            {
                LogOut("Error: Can not pack decks folder - unpack decks.zib again!");
                return;
            }

            Random rng = new Random();
            //Load all decks in DECK_DATABASE
            List <List <List <YGOPROCard> > > list_of_all_decks_ydk;
            List <byte[]> list_of_ydc_decks;

            //Get lists of random decks
            FileUtilities.GetRandomDecksFromFolder(CONSTANTS.DECK_DATABASE, CONSTANTS.CARD_DB_FILENAME, CONSTANTS.CARDS_NOT_AVAILABLE,
                                                   CONSTANTS.MAX_AI_DRAFT_INDEX * 2, CONSTANTS.YDK_EXTENSION,
                                                   CONSTANTS.YDC_EXTENSION, ChosenDecks, out list_of_all_decks_ydk, out list_of_ydc_decks);

            int max_num_decks = CONSTANTS.MAX_AI_DRAFT_INDEX * 2;
            //We now have all the decks. Now patch 20 decks.
            int number_of_decks = (list_of_all_decks_ydk.Count + list_of_ydc_decks.Count);

            if (number_of_decks == 0)
            {
                LogOut("Error: No decks found! Please add some decks to patch AI Draft decks!");
                return;
            }

            if (number_of_decks < CONSTANTS.MAX_AI_DRAFT_INDEX * 2)
            {
                LogOut("Note: Less than 20 decks detected, will repeat some!", Color.Magenta);
                int diff = CONSTANTS.MAX_AI_DRAFT_INDEX * 2 - number_of_decks;
                if (list_of_all_decks_ydk.Count != 0)
                {
                    for (int i = 0; i < diff; i++)
                    {
                        list_of_all_decks_ydk.Add(list_of_all_decks_ydk[rng.Next(list_of_all_decks_ydk.Count)]);
                    }
                }
                if (list_of_ydc_decks.Count != 0)
                {
                    for (int i = 0; i < diff; i++)
                    {
                        list_of_ydc_decks.Add(list_of_ydc_decks[rng.Next(list_of_ydc_decks.Count)]);
                    }
                }
            }

            var card_name_to_LOTD_ID = FileUtilities.GetCardIDToLOTDMapFromCSV(CONSTANTS.CSV_MAP_FILENAME);

            for (int deck_idx = CONSTANTS.MIN_AI_DRAFT_INDEX - 1; deck_idx < CONSTANTS.MAX_AI_DRAFT_INDEX; deck_idx++)
            {
                int    random_index    = 2 * deck_idx;
                string bpack_deck_name = CONSTANTS.AI_DECK_DRAFT_FILE_EU + (deck_idx + 1).ToString("D3") + CONSTANTS.YDC_EXTENSION;

                if (random_index < list_of_all_decks_ydk.Count)
                {
                    //Take YDK Deck
                    int list_idx = random_index;

                    LogOut(FileUtilities.WriteYDCDeckFile(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, bpack_deck_name),
                                                          list_of_all_decks_ydk[list_idx], card_name_to_LOTD_ID));
                }
                else
                {
                    //Take YDC Deck
                    int list_idx = random_index - list_of_all_decks_ydk.Count;

                    //Write raw binary
                    File.WriteAllBytes(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, bpack_deck_name), list_of_ydc_decks[list_idx]);
                }

                random_index    = 2 * deck_idx + 1;
                bpack_deck_name = CONSTANTS.AI_DECK_DRAFT_FILE_US + (deck_idx + 1).ToString("D3") + CONSTANTS.YDC_EXTENSION;
                string sealed_deck_name = CONSTANTS.AI_SEALED_DECK_FILE + (deck_idx + 1).ToString("D3") + CONSTANTS.YDC_EXTENSION;

                if (random_index < list_of_all_decks_ydk.Count)
                {
                    //Take YDK Deck
                    int list_idx = random_index;

                    LogOut(FileUtilities.WriteYDCDeckFile(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, bpack_deck_name),
                                                          list_of_all_decks_ydk[list_idx], card_name_to_LOTD_ID));

                    LogOut(FileUtilities.WriteYDCDeckFile(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, sealed_deck_name),
                                                          list_of_all_decks_ydk[list_idx], card_name_to_LOTD_ID));
                }
                else
                {
                    //Take YDC Deck
                    int list_idx = random_index - list_of_all_decks_ydk.Count;

                    File.WriteAllBytes(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, bpack_deck_name), list_of_ydc_decks[list_idx]);

                    File.WriteAllBytes(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, sealed_deck_name), list_of_ydc_decks[list_idx]);
                }
            }

            //At this point, we should have all decks in our working folder.

            //Now we copy them to the unpacked folder.
            for (int deck_idx = CONSTANTS.MIN_AI_DRAFT_INDEX - 1; deck_idx < CONSTANTS.MAX_AI_DRAFT_INDEX; deck_idx++)
            {
                string bpack_deck_name = CONSTANTS.AI_DECK_DRAFT_FILE_EU + (deck_idx + 1).ToString("D3") + CONSTANTS.YDC_EXTENSION;
                File.Copy(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, bpack_deck_name),
                          Path.Combine(CONSTANTS.YGODATA_DECKS + CONSTANTS.UNPACKED_SUFFIX, bpack_deck_name), true);

                bpack_deck_name = CONSTANTS.AI_DECK_DRAFT_FILE_US + (deck_idx + 1).ToString("D3") + CONSTANTS.YDC_EXTENSION;
                File.Copy(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, bpack_deck_name),
                          Path.Combine(CONSTANTS.YGODATA_DECKS + CONSTANTS.UNPACKED_SUFFIX, bpack_deck_name), true);

                string sealed_deck_name = CONSTANTS.AI_SEALED_DECK_FILE + (deck_idx + 1).ToString("D3") + CONSTANTS.YDC_EXTENSION;
                File.Copy(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, sealed_deck_name),
                          Path.Combine(CONSTANTS.YGODATA_DECKS + CONSTANTS.UNPACKED_SUFFIX, sealed_deck_name), true);
            }

            LogOut("Copied shuffled draft/sealed decks to working folder!", Color.Blue);

            //Pack decks.zib
            LogOut(Cyclone.PackZibFile(CONSTANTS.YGODATA_DECKS + CONSTANTS.UNPACKED_SUFFIX,
                                       Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, CONSTANTS.YGODATA_DECKS)));

            //Copy it to the YGODATA folder
            File.Copy(Path.Combine(CONSTANTS.PATCHED_YGODATA_OUT_FOLDER, CONSTANTS.YGODATA_DECKS),
                      Path.Combine(CONSTANTS.YGO_DATA_WORKING_FOLDER, CONSTANTS.YGODATA_DECKS), true);

            LogOut("Copied " + CONSTANTS.YGODATA_DECKS + " to " + CONSTANTS.YGO_DATA_WORKING_FOLDER + ".", Color.Blue);
        }