Пример #1
0
        public async Task Sync(CancellationToken token)
        {
            string bridge;

            try
            {
                token.ThrowIfCancellationRequested();
                bridge = await FindBridge();

                if (bridge == null)
                {
                    log.Error("No bridge found!");
                    return;
                }
                token.ThrowIfCancellationRequested();
                log.Info("Found bridge, pairing...");
                var keys = await LocalHueClient.RegisterAsync(bridge, "HueSaber", "BeatSaber", true);

                log.Info("Successfully paired!");
                token.ThrowIfCancellationRequested();
                prefs.SetString("HueSaber", "appKey", keys.Username);
                prefs.SetString("HueSaber", "clientKey", keys.StreamingClientKey);
                log.Info("Starting HueSaber...");
            } catch (Exception ex)
            {
                log.Error(ex);
                throw;
            }
            await Run(token, bridge);
        }
        public void Init(IPA.Logging.Logger log)
        {
            if (_init)
            {
                return;
            }
            _init = true;

            logger = log;

            harmonyInstance = HarmonyInstance.Create("slaynash.discordpresence");

            gameObject = Resources.FindObjectsOfTypeAll <MonoBehaviour>().First(c => c.GetType().Name == "PluginComponent");

            try
            {
                logger.Info("Initializing");

                logger.Info("Starting Discord RichPresence");
                var handlers = new DiscordRpc.EventHandlers();
                DiscordRpc.Initialize(DiscordAppID, ref handlers, false, string.Empty);

                logger.Info("Fetching nonpublic fields");
                _gameplayCoreSceneSetupDataField = typeof(SceneSetup <GameplayCoreSceneSetupData>).GetField("_sceneSetupData", BindingFlags.NonPublic | BindingFlags.Instance);
                _oneColorBeatmapCharacteristic   = typeof(GameplayCoreSceneSetup).GetField("_oneColorBeatmapCharacteristic", BindingFlags.NonPublic | BindingFlags.Instance);
#if DEBUG
                logger.Debug("Discord Presence - Field SceneSetup<GameplayCoreSceneSetupData>._sceneSetupData: " + _gameplayCoreSceneSetupDataField);
#endif
                if (_gameplayCoreSceneSetupDataField == null)
                {
                    logger.Error("Unable to fetch SceneSetup<GameplayCoreSceneSetupData>._sceneSetupData");
                    return;
                }

                logger.Info("Init done !");
            }
            catch (Exception e)
            {
                logger.Error("Unable to initialize plugin:\n" + e);
            }
        }
        private IEnumerator UpdatePresenceAfterFrame()
        {
            // Wait for next frame
            yield return(true);

            // Fetch all required objects
            _mainFlowCoordinator = Resources.FindObjectsOfTypeAll <MainFlowCoordinator>().FirstOrDefault();
            _gameplaySetup       = Resources.FindObjectsOfTypeAll <GameplayCoreSceneSetup>().FirstOrDefault();

            if (_z == null)
            {
                _z = Resources.FindObjectsOfTypeAll <Component>().FirstOrDefault(c => c != null && c.GetType().Name == "Z");
                if (_z == null)
                {
                    logger.Warn("No element of type \"Z\" found. Maybe the game isn't running a version of ScoreSaber supporting replay ?");
                }
            }

            if (_gameplaySetup != null)
            {
                _mainSetupData = _gameplayCoreSceneSetupDataField.GetValue(_gameplaySetup) as GameplayCoreSceneSetupData;
            }
#if DEBUG
            logger.Debug("_gameplaySetup: " + _gameplaySetup);
            logger.Debug("_gameplayCoreSceneSetupDataField: " + _gameplayCoreSceneSetupDataField);
            logger.Debug("_mainSetupData: " + _mainSetupData);
            GetFlowTypeHumanReadable(); // Used to debug print values
#endif
            // Check if every required object is found
            if (_mainSetupData == null || _gameplaySetup == null || _mainFlowCoordinator == null)
            {
                logger.Error("Error finding the scriptable objects required to update presence. (_mainSetupData: " + (_mainSetupData == null ? "N/A" : "OK") + ", _gameplaySetup: " + (_gameplaySetup == null ? "N/A" : "OK") + ", _mainFlowCoordinator: " + (_mainFlowCoordinator == null ? "N/A" : "OK"));
                Presence.details = "Playing";
                DiscordRpc.UpdatePresence(Presence);
                yield break;
            }

            // Set presence main values
            IDifficultyBeatmap diff = _mainSetupData.difficultyBeatmap;

            Presence.details = $"{diff.level.songName} | {diff.difficulty.Name()}";
            Presence.state   = "";

            if (_z != null)
            {
                //Console.WriteLine("--------------------------");
                FieldInfo[] fields = _z.GetType().GetFields((BindingFlags)(-1));
                foreach (FieldInfo fi in fields)
                {
                    if (fi.FieldType.Name == "Mode" && fi.GetValue(_z).ToString() == "Playback")
                    {
                        Presence.state += "[Replay] ";
                    }
                    //logger.Debug("Discord Presence - [" + fi.Name + ": " + fi.FieldType.Name + "] => " + fi.GetValue(_z));
                }
            }

            if (diff.level.levelID.Contains('∎'))
            {
                Presence.state += "Custom | ";
            }

            if (_mainSetupData.practiceSettings != null)
            {
                Presence.state += "Practice | ";
            }

            Presence.state += GetFlowTypeHumanReadable() + " ";
#if DEBUG
            logger.Debug("Discord Presence - diff.parentDifficultyBeatmapSet.beatmapCharacteristic: " + diff.parentDifficultyBeatmapSet.beatmapCharacteristic);
            logger.Debug("Discord Presence - _gameplaySetup._oneColorBeatmapCharacteristic: " + typeof(GameplayCoreSceneSetup).GetField("_oneColorBeatmapCharacteristic", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_gameplaySetup));
#endif
            // Update gamemode (Standard / One Saber / No Arrow)
            if (_mainSetupData.gameplayModifiers.noArrows || diff.parentDifficultyBeatmapSet.beatmapCharacteristic.ToString().ToLower().Contains("noarrow"))
            {
                _gamemode = GameMode.NoArrows;
            }
            else if (diff.parentDifficultyBeatmapSet.beatmapCharacteristic == (BeatmapCharacteristicSO)_oneColorBeatmapCharacteristic.GetValue(_gameplaySetup))
            {
                _gamemode = GameMode.OneSaber;
            }
            else
            {
                _gamemode = GameMode.Standard;
            }

            string gameplayModeText = _gamemode == GameMode.OneSaber ? "One Saber" : _gamemode == GameMode.NoArrows ? "No Arrow" : "Standard";
            Presence.state += gameplayModeText;

            // Set music speak
            if (_mainSetupData.practiceSettings != null)
            {
                if (_mainSetupData.practiceSettings.songSpeedMul != 1.0f)
                {
                    Presence.state += " | Speed x" + _mainSetupData.practiceSettings.songSpeedMul;
                }
            }
            else
            {
                if (_mainSetupData.gameplayModifiers.songSpeedMul != 1.0f)
                {
                    Presence.state += " | Speed x" + _mainSetupData.gameplayModifiers.songSpeedMul;
                }
            }

            // Set common gameplay modifiers
            if (_mainSetupData.gameplayModifiers.noFail)
            {
                Presence.state += " | No Fail";
            }
            if (_mainSetupData.gameplayModifiers.instaFail)
            {
                Presence.state += " | Instant Fail";
            }
            if (_mainSetupData.playerSpecificSettings.swapColors)
            {
                Presence.state += " | Mirrored";
            }
            if (_mainSetupData.gameplayModifiers.disappearingArrows)
            {
                Presence.state += " | Disappearing Arrows";
            }
            if (_mainSetupData.gameplayModifiers.ghostNotes)
            {
                Presence.state += " | Ghost Notes";
            }


            Presence.largeImageKey  = "default";
            Presence.largeImageText = "Beat Saber";
            Presence.smallImageKey  = GetFlowTypeHumanReadable() == "Party" ? "party" : _gamemode == GameMode.OneSaber ? "one_saber" : _gamemode == GameMode.NoArrows ? "no_arrows" : "solo";
            Presence.smallImageText = gameplayModeText;
            Presence.startTimestamp = (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;

            // Set startTimestamp offset if we are in training mode
            if (_mainSetupData.practiceSettings != null)
            {
#if DEBUG
                logger.Debug("Discord Presence - _mainSetupData.practiceSettings.startSongTime: " + _mainSetupData.practiceSettings.startSongTime);
#endif
                if (_mainSetupData.practiceSettings.startInAdvanceAndClearNotes)
                {
                    Presence.startTimestamp -= (long)Mathf.Max(0f, _mainSetupData.practiceSettings.startSongTime - 3f);
                }
                else
                {
                    Presence.startTimestamp -= (long)_mainSetupData.practiceSettings.startSongTime;
                }
            }

            DiscordRpc.UpdatePresence(Presence);
        }