public static PracticeSettings ConvertPractice(PartyPanelShared.Models.PracticeSettings practiceSettings)
        {
            Logger.Debug(practiceSettings.songSpeed.ToString());
            PracticeSettings newSettings = new PracticeSettings(0f, practiceSettings.songSpeed / 10000);

            return(newSettings);
        }
        public static GameplayModifiers ConvertModifiers(PartyPanelShared.Models.GameplayModifiers mods, GameplayModifiers copy)
        {
            GameplayModifiers newMods = copy;

            foreach (FieldInfo fi in typeof(GameplayModifiers).GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
            {
                try
                {
                    object val2 = mods.GetField(fi.Name.Substring(fi.Name.IndexOf("_") + 1));
                    if (fi.Name.Contains("Type") || fi.Name.Contains("speed") || fi.Name == "_fastNotes")
                    {
                        continue;
                    }
                    Logger.Debug(fi.Name);
                    fi.SetValue(newMods, val2);
                }
                catch (Exception)
                {
                    continue;
                }
            }
            return(newMods);
        }
        public static async void PlaySong(IPreviewBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, PlaySong packet)
        {
            flow = (SoloFreePlayFlowCoordinator)Resources.FindObjectsOfTypeAll <MainFlowCoordinator>().First().GetField("_soloFreePlayFlowCoordinator");
            Action <IBeatmapLevel> SongLoaded = (loadedLevel) =>
            {
                Logger.Debug("G");
                MenuTransitionsHelper _menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelper>().First();
                IDifficultyBeatmap    diffbeatmap         = loadedLevel.beatmapLevelData.GetDifficultyBeatmap(characteristic, difficulty);
                Logger.Debug("L");
                GameplaySetupViewController gameplaySetupViewController = (GameplaySetupViewController)typeof(SinglePlayerLevelSelectionFlowCoordinator).GetField("_gameplaySetupViewController", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(flow);
                Logger.Debug("D");
                OverrideEnvironmentSettings environmentSettings = gameplaySetupViewController.environmentOverrideSettings;
                ColorScheme scheme = gameplaySetupViewController.colorSchemesSettings.GetSelectedColorScheme();
                //GameplayModifiers modifiers = gameplaySetupViewController.gameplayModifiers;
                PlayerSpecificSettings settings = gameplaySetupViewController.playerSettings;
                //TODO: re add modifier customizability

                PracticeSettings  practiceSettings = ConvertPractice(packet.practiceSettings);
                GameplayModifiers modifiers        = ConvertModifiers(packet.gameplayModifiers, gameplaySetupViewController.gameplayModifiers);
                Logger.Debug(diffbeatmap.level.levelID + " " + scheme.colorSchemeId);
                _menuSceneSetupData.StartStandardLevel(
                    "Solo",
                    diffbeatmap,
                    diffbeatmap.level,
                    environmentSettings,
                    scheme,
                    modifiers,
                    settings,
                    practiceSettings,
                    "Menu",
                    false,
                    null,
                    new Action <StandardLevelScenesTransitionSetupDataSO, LevelCompletionResults>((StandardLevelScenesTransitionSetupDataSO q, LevelCompletionResults r) => { })
                    );
            };

            if (flow == null || flow.gameObject == null || !flow.gameObject.activeInHierarchy)
            {
                Button button = Resources.FindObjectsOfTypeAll <Button>().Where(x => x != null && x.name == "SoloButton").First();
                button.onClick.Invoke();
            }
            if ((level is PreviewBeatmapLevelSO && await HasDLCLevel(level.levelID)) ||
                level is CustomPreviewBeatmapLevel)
            {
                Logger.Debug("Loading DLC/Custom level...");
                var result = await GetLevelFromPreview(level);

                if (!(result?.isError == true))
                {
                    SongLoaded(result?.beatmapLevel);
                    return;
                }
                Logger.Debug("You Suck Idiot");
            }
            else if (level is BeatmapLevelSO)
            {
                Logger.Debug("Reading OST data without songloader...");
                SongLoaded(level as IBeatmapLevel);
            }
            else
            {
                Logger.Debug($"Skipping unowned DLC ({level.songName})");
            }
        }