Пример #1
0
        private string GetFiles()
        {
            var tempPath = ConfigDirectoryPath;

            if (Directory.Exists(tempPath))
            {
                Directory.Delete(tempPath, true);
            }

            Directory.CreateDirectory(tempPath);

            var service = new CompanyServiceClient();
            var stream  = service.GetCompanyFiles(Company.Id, "assets");
            var zipFile = Path.Combine(tempPath, "out.zip");

            using (Stream file = File.OpenWrite(zipFile))
            {
                CopyStream(stream, file);
            }

            using (var unzip = new Unzip(zipFile))
            {
                unzip.ExtractToDirectory(tempPath);
            }

            File.Delete(zipFile);


            CreateConfigFile(Path.Combine(tempPath, "settings.json"), s => s.IsClientSetting);
            CreateConfigFile(Path.Combine(tempPath, "allSettings.json"), s => true);

            return(tempPath);
        }
Пример #2
0
 private void UnzipFile(byte[] data, string directory)
 {
     using (MemoryStream ms = new MemoryStream(data))
     {
         using (var unzip = new Unzip(ms))
         {
             unzip.ExtractToDirectory(directory);
         }
     }
 }
Пример #3
0
        public static Task DownloadSdk(GitOptions options)
        {
            return(Task.Run(async() =>
            {
                var url = options.GitUrl + "/archive/development.zip";

                var folderPath = options.RootFolder;
                var fileName = options.FileName.Replace(".zip", "") + "-development";

                string zipPath, filePath;
                //if (!IsLinux)
                //{
                zipPath = string.Format("{0}\\{1}", folderPath, fileName);
                filePath = string.Format("{0}.zip", zipPath);
                //}

                if (options.ReplaceExisting)
                {
                    if (File.Exists(filePath))
                    {
                        File.Delete(filePath);
                    }

                    if (Directory.Exists(zipPath))
                    {
                        Directory.Delete(zipPath, true);
                    }
                }


                using (var client = new HttpClient())
                {
                    var result = await client.GetAsync(url);
                    result.EnsureSuccessStatusCode();
                    using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        await result.Content.CopyToAsync(fileStream);
                        fileStream.Close();
                    }
                }

                if (File.Exists(filePath))
                {
                    var unzip = new Unzip(filePath);
                    unzip.ExtractToDirectory(folderPath);
                }
            }));
        }
        /// <summary>
        /// Downloads the newest gamedata available online.
        /// </summary>
        /// <returns>true if the download was successfull, else false.</returns>
        private async Task <bool> DownloadMapFiles()
        {
            HttpResponseMessage response = await http.GetAsync(string.Concat(
                                                                   Constants.Update.ServerAddress,
                                                                   Constants.Update.MapDataEndpoint
                                                                   ));

            if (!response.IsSuccessStatusCode)
            {
                return(false);
            }

            using (var stream = await response.Content.ReadAsStreamAsync())
            {
                using (var unzip = new Unzip(stream))
                {
                    unzip.ExtractToDirectory(Game.FileSystem.UserDirectory);
                }
            }

            return(true);
        }
Пример #5
0
        private List <CustomSongInfo> RetrieveAllSongs()
        {
            var customSongInfos = new List <CustomSongInfo>();
            var path            = Environment.CurrentDirectory;

            path = path.Replace('\\', '/');

            var currentHashes = new List <string>();
            var cachedSongs   = new string[0];

            if (Directory.Exists(path + "/CustomSongs/.cache"))
            {
                cachedSongs = Directory.GetDirectories(path + "/CustomSongs/.cache");
            }
            else
            {
                Directory.CreateDirectory(path + "/CustomSongs/.cache");
            }

            var songZips = Directory.GetFiles(path + "/CustomSongs")
                           .Where(x => x.ToLower().EndsWith(".zip") || x.ToLower().EndsWith(".beat")).ToArray();

            foreach (var songZip in songZips)
            {
                Log("Found zip: " + songZip);
                //Check cache if zip already is extracted
                string hash;
                if (Utils.CreateMD5FromFile(songZip, out hash))
                {
                    currentHashes.Add(hash);
                    if (cachedSongs.Any(x => x.Contains(hash)))
                    {
                        continue;
                    }

                    using (var unzip = new Unzip(songZip))
                    {
                        unzip.ExtractToDirectory(path + "/CustomSongs/.cache/" + hash);
                        Log("Extracted to " + path + "/CustomSongs/.cache/" + hash);
                    }
                }
                else
                {
                    Log("Error reading zip " + songZip);
                }
            }

            var songFolders = Directory.GetDirectories(path + "/CustomSongs").ToList();
            var songCaches  = Directory.GetDirectories(path + "/CustomSongs/.cache");

            foreach (var song in songFolders)
            {
                var results = Directory.GetFiles(song, "info.json", SearchOption.AllDirectories);
                if (results.Length == 0)
                {
                    Log("Custom song folder '" + song + "' is missing info.json!");
                    continue;
                }

                foreach (var result in results)
                {
                    var songPath = Path.GetDirectoryName(result).Replace('\\', '/');
                    customSongInfos.Add(GetCustomSongInfo(songPath));
                }
            }

            foreach (var song in songCaches)
            {
                var hash = Path.GetFileName(song);
                if (!currentHashes.Contains(hash))
                {
                    //Old cache
                    Log("Deleting old cache: " + song);
                    Directory.Delete(song, true);
                }
            }

            return(customSongInfos);
        }
Пример #6
0
        private IEnumerator DoUpdate()
        {
            UnityWebRequest www = null;

            try
            {
                DisplayText("Downloading update...");

                www = UnityWebRequest.Get(Module.VersionForUpdate.downloadUrl);
                www.downloadHandler = new DownloadHandlerBuffer();
            }
            catch (Exception e)
            {
                Terminal.Log(e.Message + " " + e.StackTrace);
                SetPage(typeof(MainPage));
            }

            if (www != null)
            {
                yield return www.SendWebRequest();

                while (!www.downloadHandler.isDone)
                    yield return null;

                try
                {
                    if (!www.isHttpError && !www.isNetworkError)
                    {
                        DisplayText("Extracting update...");
                        string outFile = Path.GetTempFileName();

                        List<(string from, string to)> renamed = new List<(string, string)>();

                        try
                        {
                            File.WriteAllBytes(outFile, www.downloadHandler.data);

                            //rename currently used DLLs
                            foreach (string file in Directory.GetFiles(Module.ModulePath, "*.dll"))
                            {
                                if (Path.GetFileName(file).StartsWith("DVRouteManager"))
                                    continue;

                                string renameTo = file + ".old";
                                File.Delete(renameTo);
                                System.IO.File.Move(file, renameTo);
                                renamed.Add((file, renameTo));
                            }

                            using (Unzip unzip = new Unzip(outFile))
                            {
                                var destPath = Module.ModulePath;
                                if (Directory.Exists(destPath))
                                    destPath = Path.GetDirectoryName(destPath); //remove trailing \ if it is present

                                destPath = Path.GetDirectoryName(destPath); //get parent directory

                                unzip.ExtractToDirectory(destPath); 
                            }

                            DisplayText("Done, update applies after game restart", "OK");

                            updateFinished = true;
                        }
                        catch(Exception exc)
                        {
                            Terminal.Log(exc.Message + ": " + exc.StackTrace);

                            //restore renamed files
                            foreach (var renamedFile in renamed)
                            {
                                System.IO.File.Move(renamedFile.to, renamedFile.from);
                            }
                        }
                        finally
                        {
                            File.Delete(outFile);
                        }
                    }
                }
                catch (Exception e)
                {
                    Terminal.Log(e.Message + " " + e.StackTrace);
                    SetPage(typeof(MainPage));
                }
            }
            else
            {
                SetPage(typeof(MainPage));
            }


        }
Пример #7
0
        private void RetrieveAllSongsAsync(Action <CustomSongInfo> task, ThreadStart onFinished = null)
        {
            handler.Dispatch(() => {
                var path = Environment.CurrentDirectory;
                path     = path.Replace('\\', '/');

                var currentHashes = new List <string>();
                var cachedSongs   = new string[0];
                if (Directory.Exists(path + "/CustomSongs/.cache"))
                {
                    cachedSongs = Directory.GetDirectories(path + "/CustomSongs/.cache");
                }
                else
                {
                    Directory.CreateDirectory(path + "/CustomSongs/.cache");
                }

                var songZips = Directory.GetFiles(path + "/CustomSongs")
                               .Where(x => x.ToLower().EndsWith(".zip") || x.ToLower().EndsWith(".beat"))
                               .ToArray();
                foreach (var songZip in songZips)
                {
                    Log("Found zip: " + songZip);
                    //Check cache if zip already is extracted
                    string hash;
                    if (Utils.CreateMD5FromFile(songZip, out hash))
                    {
                        currentHashes.Add(hash);
                        if (cachedSongs.Any(x => x.Contains(hash)))
                        {
                            continue;
                        }

                        using (var unzip = new Unzip(songZip)) {
                            unzip.ExtractToDirectory(path + "/CustomSongs/.cache/" + hash);
                            Log("Extracted to " + path + "/CustomSongs/.cache/" + hash);
                        }
                    }
                    else
                    {
                        Log("Error reading zip " + songZip);
                    }
                }

                var songFolders = Directory.GetDirectories(path + "/CustomSongs").ToList();
                var songCaches  = Directory.GetDirectories(path + "/CustomSongs/.cache");

                foreach (var song in songFolders)
                {
                    LoadSong(song, task);
                }

                foreach (var song in songCaches)
                {
                    var hash = Path.GetFileName(song);
                    if (!currentHashes.Contains(hash))
                    {
                        //Old cache
                        Log("Deleting old cache: " + song);
                        Directory.Delete(song, true);
                    }
                }

                if (onFinished != null)
                {
                    handler.Post(onFinished);
                }
            });
        }
Пример #8
0
        private void RetrieveAllSongs(bool fullRefresh)
        {
            var stopwatch = new Stopwatch();

            if (fullRefresh)
            {
                CustomLevels.Clear();
                CustomWIPLevels.Clear();
                CachedWIPLevels.Clear();
                Collections.levelHashDictionary.Clear();
                Collections.hashLevelDictionary.Clear();
                foreach (var folder in SeperateSongFolders)
                {
                    folder.Levels.Clear();
                }
            }
            HashSet <string> foundSongPaths = fullRefresh ? new HashSet <string>() : new HashSet <string>(Hashing.cachedSongHashData.Keys);

            var baseProjectPath  = CustomLevelPathHelper.baseProjectPath;
            var customLevelsPath = CustomLevelPathHelper.customLevelsDirectoryPath;

            Action job = delegate
            {
                try
                {
                    var path = CustomLevelPathHelper.baseProjectPath;
                    path = path.Replace('\\', '/');

                    if (!Directory.Exists(customLevelsPath))
                    {
                        Directory.CreateDirectory(customLevelsPath);
                    }

                    if (!Directory.Exists(baseProjectPath + "/CustomWIPLevels"))
                    {
                        Directory.CreateDirectory(baseProjectPath + "/CustomWIPLevels");
                    }
                    if (fullRefresh)
                    {
                        try
                        {
                            var cachePath = path + "/CustomWIPLevels/Cache";
                            if (!Directory.Exists(cachePath))
                            {
                                Directory.CreateDirectory(cachePath);
                            }
                            var cache = new DirectoryInfo(cachePath);
                            foreach (var file in cache.GetFiles())
                            {
                                file.Delete();
                            }
                            foreach (var folder in cache.GetDirectories())
                            {
                                folder.Delete(true);
                            }
                            var zips = Directory.GetFiles(path + "/CustomWIPLevels", "*.zip", SearchOption.TopDirectoryOnly);
                            foreach (var zip in zips)
                            {
                                var unzip = new Unzip(zip);
                                try
                                {
                                    unzip.ExtractToDirectory(cachePath + "/" + new FileInfo(zip).Name);
                                }
                                catch (Exception ex)
                                {
                                    Logging.logger.Warn("Failed to extract zip: " + zip + ": " + ex);
                                }
                                unzip.Dispose();
                            }

                            var cacheFolders = Directory.GetDirectories(cachePath).ToArray();
                            foreach (var cachedFolder in cacheFolders)
                            {
                                var results = Directory.GetFiles(cachedFolder, "info.dat", SearchOption.AllDirectories);
                                if (results.Length == 0)
                                {
                                    Logging.Log("Folder: '" + cachedFolder + "' is missing info.dat files!", LogSeverity.Notice);
                                    continue;
                                }
                                foreach (var result in results)
                                {
                                    try
                                    {
                                        var songPath = Path.GetDirectoryName(result.Replace('\\', '/'));
                                        if (!fullRefresh)
                                        {
                                            if (CachedWIPLevels.ContainsKey(songPath))
                                            {
                                                var c = CachedWIPLevels[songPath];//.FirstOrDefault(x => x.customLevelPath == songPath);
                                                if (c != null)
                                                {
                                                    continue;
                                                }
                                            }
                                        }
                                        StandardLevelInfoSaveData saveData = GetStandardLevelInfoSaveData(songPath);
                                        if (saveData == null)
                                        {
                                            continue;
                                        }

                                        HMMainThreadDispatcher.instance.Enqueue(delegate
                                        {
                                            if (_loadingCancelled)
                                            {
                                                return;
                                            }
                                            var level = LoadSong(saveData, songPath, out string hash);
                                            if (level != null)
                                            {
                                                CachedWIPLevels[songPath] = level;
                                            }
                                        });
                                    }
                                    catch (Exception ex)
                                    {
                                        Logging.logger.Notice("Failed to load song from " + cachedFolder + ": " + ex);
                                    }
                                }
                            }
                        }
Пример #9
0
        private void RetrieveAllSongs(bool fullRefresh)
        {
            var stopwatch = new Stopwatch();
            var levelList = new List <CustomLevel>();

            if (fullRefresh)
            {
                _customLevelPool.ReturnAll();
                _beatmapDataPool.ReturnAll();
                CustomLevels.Clear();
            }

            Action job = delegate
            {
                try
                {
                    stopwatch.Start();
                    var path = Environment.CurrentDirectory;
                    path = path.Replace('\\', '/');

                    var currentHashes = new List <string>();
                    var cachedSongs   = new string[0];
                    if (Directory.Exists(path + "/CustomSongs/.cache"))
                    {
                        cachedSongs = Directory.GetDirectories(path + "/CustomSongs/.cache");
                    }
                    else
                    {
                        Directory.CreateDirectory(path + "/CustomSongs/.cache");
                    }

                    var songZips = Directory.GetFiles(path + "/CustomSongs")
                                   .Where(x => x.ToLower().EndsWith(".zip") || x.ToLower().EndsWith(".beat")).ToArray();
                    foreach (var songZip in songZips)
                    {
                        //Check cache if zip already is extracted
                        string hash;
                        if (Utils.CreateMD5FromFile(songZip, out hash))
                        {
                            currentHashes.Add(hash);
                            if (cachedSongs.Any(x => x.Contains(hash)))
                            {
                                continue;
                            }

                            using (var unzip = new Unzip(songZip))
                            {
                                unzip.ExtractToDirectory(path + "/CustomSongs/.cache/" + hash);
                            }
                        }
                        else
                        {
                            Log("Error reading zip " + songZip, LogSeverity.Warn);
                        }
                    }

                    var songFolders = Directory.GetDirectories(path + "/CustomSongs").ToList();
                    var songCaches  = Directory.GetDirectories(path + "/CustomSongs/.cache");

                    float i = 0;
                    foreach (var song in songFolders)
                    {
                        i++;
                        var results = Directory.GetFiles(song, "info.json", SearchOption.AllDirectories);
                        if (results.Length == 0)
                        {
                            Log("Custom song folder '" + song + "' is missing info.json files!", LogSeverity.Warn);
                            continue;
                        }


                        foreach (var result in results)
                        {
                            var songPath = Path.GetDirectoryName(result).Replace('\\', '/');
                            if (!fullRefresh)
                            {
                                if (CustomLevels.Any(x => x.customSongInfo.path == songPath))
                                {
                                    continue;
                                }
                            }

                            var customSongInfo = GetCustomSongInfo(songPath);
                            if (customSongInfo == null)
                            {
                                continue;
                            }
                            var id = customSongInfo.GetIdentifier();
                            if (CustomLevels.Any(x => x.levelID == id && x.customSongInfo != customSongInfo))
                            {
                                Log("Duplicate song found at " + customSongInfo.path, LogSeverity.Warn);
                                continue;
                            }

                            var i1 = i;
                            HMMainThreadDispatcher.instance.Enqueue(delegate
                            {
                                if (_loadingCancelled)
                                {
                                    return;
                                }
                                LoadSong(customSongInfo, levelList);
                                LoadingProgress = i1 / songFolders.Count;
                            });
                        }
                    }

                    foreach (var song in songCaches)
                    {
                        var hash = Path.GetFileName(song);
                        if (!currentHashes.Contains(hash))
                        {
                            //Old cache
                            Directory.Delete(song, true);
                        }
                    }
                }
                catch (Exception e)
                {
                    Log("RetrieveAllSongs failed:", LogSeverity.Error);
                    Log(e.ToString(), LogSeverity.Error);
                    throw;
                }
            };

            Action finish = delegate
            {
                stopwatch.Stop();
                Log("Loaded " + levelList.Count + " new songs in " + stopwatch.Elapsed.Seconds + " seconds");

                CustomLevels.AddRange(levelList);
                var orderedList = CustomLevels.OrderBy(x => x.songName);
                CustomLevels = orderedList.ToList();

                foreach (var customLevel in CustomLevels)
                {
                    if (customLevel.customSongInfo.oneSaber)
                    {
                        _oneSaberLevelCollection.LevelList.Add(customLevel);
                    }
                    else
                    {
                        _standardLevelCollection.LevelList.Add(customLevel);
                        _noArrowsLevelCollection.LevelList.Add(customLevel);
                        _partyLevelCollection.LevelList.Add(customLevel);
                    }
                }

                AreSongsLoaded  = true;
                AreSongsLoading = false;
                LoadingProgress = 1;

                _loadingTask = null;

                if (SongsLoadedEvent != null)
                {
                    SongsLoadedEvent(this, CustomLevels);
                }
            };

            _loadingTask = new HMTask(job, finish);
            _loadingTask.Run();
        }
Пример #10
0
        public static void Main(string[] args)
        {
            var finalargs = new List <string>(args);

            if (!finalargs.Contains("-d"))
            {
                finalargs.Add("-d");
                finalargs.Add(Directory.GetCurrentDirectory());
            }

            if (!finalargs.Contains("-h"))
            {
                finalargs.Add("-h");
                finalargs.Add(HOME);
            }

            args = finalargs.ToArray();

            bool doUpdate = args.Length > 0 && args[0] == "update";

            if (!Directory.Exists(HOME) || (doUpdate))
            {
                if (Directory.Exists(HOME))
                {
                    Console.Write("Deleting " + HOME);
                    DirectoryDelete(HOME);
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.WriteLine(" [DONE]");
                    Console.ResetColor();
                }

                if (args.Length > 1)
                {
                    Console.Write("Copying " + args[1]);
                    DirectoryCopy(args [1], HOME);
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.WriteLine(" [DONE]");
                    Console.ResetColor();
                    Console.WriteLine("Installed to " + HOME);
                    return;
                }

                Console.Write("Downloading " + URL);

                using (var client = new WebClient()) {
                    client.DownloadFile(URL, ZIP);
                }

                Console.ForegroundColor = ConsoleColor.Magenta;
                Console.WriteLine(" [DONE]");
                Console.ResetColor();

                Console.Write("Extracting " + ZIP);
                using (var unzip = new Unzip(ZIP)) {
                    unzip.ExtractToDirectory(HOME_DIR);
                }

                Directory.Move(HOME_ORIG, HOME);
                File.Delete(ZIP);

                Console.ForegroundColor = ConsoleColor.Magenta;
                Console.WriteLine(" [DONE]");
                Console.ResetColor();
                Console.WriteLine("Installed to " + HOME);

                if (doUpdate)
                {
                    return;
                }
            }

            Assembly.LoadFile(Path.Combine(BOOT, "KopiLua.dll"));
            Assembly.LoadFile(Path.Combine(BOOT, "Microsoft.Web.XmlTransform.dll"));
            Assembly.LoadFile(Path.Combine(BOOT, "NLua.dll"));
            Assembly.LoadFile(Path.Combine(BOOT, "NuGet.Core.dll"));

            var kaizo = Assembly.LoadFile(Path.Combine(BOOT, "kaizo.exe"));

            kaizo.GetType("Kaizo.MainClass").GetMethod("Main", BindingFlags.Public | BindingFlags.Static).Invoke(null, new[] { finalargs.ToArray() });
        }
Пример #11
0
        private void RetrieveAllSongs(bool fullRefresh)
        {
            var stopwatch = new Stopwatch();
            var levelList = new List <CustomLevel>();

            if (fullRefresh)
            {
                _customLevelPool.ReturnAll();
                _beatmapDataPool.ReturnAll();
                CustomLevels.Clear();
            }

            Action job = delegate
            {
                try
                {
                    stopwatch.Start();
                    var path = Environment.CurrentDirectory;
                    path = path.Replace('\\', '/');

                    var currentHashes = new List <string>();
                    var cachedHashes  = new List <string>();
                    var cachedSongs   = new string[0];

                    if (Directory.Exists(path + "/CustomSongs/.cache"))
                    {
                        cachedSongs = Directory.GetDirectories(path + "/CustomSongs/.cache");
                    }
                    else
                    {
                        Directory.CreateDirectory(path + "/CustomSongs/.cache");
                    }


                    var songZips = Directory.GetFiles(path + "/CustomSongs")
                                   .Where(x => x.ToLower().EndsWith(".zip") || x.ToLower().EndsWith(".beat") || x.ToLower().EndsWith(".bmap")).ToArray();
                    foreach (var songZip in songZips)
                    {
                        //Check cache if zip already is extracted
                        string hash;
                        string trimmedZip = songZip;
                        trimmedZip = Utils.TrimEnd(trimmedZip, ".zip");
                        trimmedZip = Utils.TrimEnd(trimmedZip, ".beat");
                        trimmedZip = Utils.TrimEnd(trimmedZip, ".bmap");
                        if (Utils.CreateMD5FromFile(songZip, out hash))
                        {
                            using (var unzip = new Unzip(songZip))
                            {
                                try
                                {
                                    if (Directory.Exists(trimmedZip))
                                    {
                                        Log("Directory for Zip already exists, Extracting Zip to Cache instead.");
                                        cachedHashes.Add(hash);
                                        if (cachedSongs.Any(x => x.Contains(hash)))
                                        {
                                            continue;
                                        }
                                        unzip.ExtractToDirectory(path + "/CustomSongs/.cache/" + hash);
                                    }
                                    else
                                    {
                                        unzip.ExtractToDirectory(path + "/CustomSongs/" + trimmedZip.Replace(path + "/CustomSongs\\", ""));
                                        //Add hash if successfully extracted
                                        currentHashes.Add(hash);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Log("Error extracting zip " + songZip + "\n" + e, LogSeverity.Warn);
                                }
                            }
                        }
                        else
                        {
                            Log("Error reading zip " + songZip, LogSeverity.Warn);
                        }
                    }


                    var songFolders = Directory.GetDirectories(path + "/CustomSongs").ToList();
                    var songCaches  = Directory.GetDirectories(path + "/CustomSongs/.cache");

                    foreach (var songZip in songZips)
                    {
                        //Delete zip if successfully extracted
                        string hash;
                        if (Utils.CreateMD5FromFile(songZip, out hash))
                        {
                            if (currentHashes.Contains(hash))
                            {
                                Log("Zip Successfully Extracted, deleting zip.");
                                File.SetAttributes(songZip, FileAttributes.Normal);
                                File.Delete(songZip);
                            }
                        }
                    }

                    foreach (var song in songCaches)
                    {
                        var hash = Path.GetFileName(song);
                        if (!cachedHashes.Contains(hash))
                        {
                            //Old cache
                            Directory.Delete(song, true);
                        }
                    }



                    var loadedIDs = new List <string>();

                    float i = 0;
                    foreach (var song in songFolders)
                    {
                        i++;
                        var results = Directory.GetFiles(song, "info.json", SearchOption.AllDirectories);
                        if (results.Length == 0)
                        {
                            Log("Custom song folder '" + song + "' is missing info.json files!", LogSeverity.Warn);
                            continue;
                        }


                        foreach (var result in results)
                        {
                            try
                            {
                                var songPath = Path.GetDirectoryName(result).Replace('\\', '/');
                                if (!fullRefresh)
                                {
                                    if (CustomLevels.Any(x => x.customSongInfo.path == songPath))
                                    {
                                        continue;
                                    }
                                }

                                var customSongInfo = GetCustomSongInfo(songPath);

                                if (customSongInfo == null)
                                {
                                    continue;
                                }
                                var id = customSongInfo.GetIdentifier();
                                if (loadedIDs.Any(x => x == id))
                                {
                                    Log("Duplicate song found at " + customSongInfo.path, LogSeverity.Warn);
                                    continue;
                                }

                                loadedIDs.Add(id);

                                if (CustomPlatformsPresent && customSongPlatforms)
                                {
                                    if (customSongInfo.customEnvironment != null)
                                    {
                                        if (findCustomEnvironment(customSongInfo.customEnvironment) == -1)
                                        {
                                            Console.WriteLine("CustomPlatform not found: " + customSongInfo.customEnvironment);
                                            if (customSongInfo.customEnvironmentHash != null)
                                            {
                                                Console.WriteLine("Downloading with hash: " + customSongInfo.customEnvironmentHash);
                                                StartCoroutine(downloadCustomPlatform(customSongInfo.customEnvironmentHash, customSongInfo.customEnvironment));
                                            }
                                        }
                                    }
                                }

                                var i1 = i;
                                HMMainThreadDispatcher.instance.Enqueue(delegate
                                {
                                    if (_loadingCancelled)
                                    {
                                        return;
                                    }
                                    var level = LoadSong(customSongInfo);
                                    if (level != null)
                                    {
                                        levelList.Add(level);
                                    }

                                    LoadingProgress = i1 / songFolders.Count;
                                });
                            }
                            catch (Exception e)
                            {
                                Log("Failed to load song folder: " + result, LogSeverity.Warn);
                                Log(e.ToString(), LogSeverity.Warn);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Log("RetrieveAllSongs failed:", LogSeverity.Error);
                    Log(e.ToString(), LogSeverity.Error);
                }
            };

            Action finish = delegate
            {
                stopwatch.Stop();
                Log("Loaded " + levelList.Count + " new songs in " + stopwatch.Elapsed.Seconds + " seconds");

                CustomLevels.AddRange(levelList);
                var orderedList = CustomLevels.OrderBy(x => x.songName);
                CustomLevels = orderedList.ToList();

                foreach (var customLevel in CustomLevels)
                {
                    CustomLevelCollectionSO.AddCustomLevel(customLevel);
                }

                AreSongsLoaded  = true;
                AreSongsLoading = false;
                LoadingProgress = 1;

                _loadingTask = null;

                if (SongsLoadedEvent != null)
                {
                    SongsLoadedEvent(this, CustomLevels);
                }
            };

            _loadingTask = new HMTask(job, finish);
            _loadingTask.Run();
        }