Esempio n. 1
0
        public static OsuStatus Convert(this OsuMemoryStatus status)
        {
            switch (status)
            {
            case OsuMemoryStatus.EditingMap:
                return(OsuStatus.Editing);

            case OsuMemoryStatus.MultiplayerResultsscreen:
            case OsuMemoryStatus.RankingTagCoop:
            case OsuMemoryStatus.RankingTeam:
            case OsuMemoryStatus.ResultsScreen:
                return(OsuStatus.ResultsScreen);

            case OsuMemoryStatus.MainMenu:
            case OsuMemoryStatus.SongSelect:
            case OsuMemoryStatus.SongSelectEdit:
            case OsuMemoryStatus.MultiplayerRoom:
            case OsuMemoryStatus.MultiplayerRooms:
            case OsuMemoryStatus.MultiplayerSongSelect:
            case OsuMemoryStatus.Tourney:
            case OsuMemoryStatus.OsuDirect:
                return(OsuStatus.Listening);

            case OsuMemoryStatus.Playing:
                return(OsuStatus.Playing);

            default:
                return(OsuStatus.Null);
            }
        }
Esempio n. 2
0
        private async void OsuRunningTimer_Tick(object sender, EventArgs e)
        {
            // check if osu!.exe is running
            var processes = Process.GetProcessesByName("osu!");

            if (processes.Length == 0)
            {
                gameLoaded = false;
            }
            else
            {
                if (gameLoaded == false) // @ posedge gameLoaded
                {
                    await Task.Run(() => Thread.Sleep(5000));

                    gameLoaded = true;
                }
                else if (gameLoaded == null)
                {
                    gameLoaded = true;
                }

                if (userSongsFolder == null || userSongsFolder == "")
                {
                    // Try to get osu songs folder
                    var osuExePath = processes[0].MainModule.FileName;
                    userSongsFolder = Path.Combine(Path.GetDirectoryName(osuExePath), "Songs");
                    Properties.Settings.Default.SongsFolder = userSongsFolder;
                    Properties.Settings.Default.Save();
                }
            }
            int intStatus = 0;

            osuReader.GetCurrentStatus(out intStatus);
            OsuMemoryStatus status = (OsuMemoryStatus)intStatus;

            if (status == OsuMemoryStatus.SongSelect || status == OsuMemoryStatus.MultiplayerRoom || status == OsuMemoryStatus.MultiplayerSongSelect)
            {
                mapSelectScreen = true;
            }
            else
            {
                mapSelectScreen = false;
            }

            if (mapSelectScreen && !hooked)
            {
                kbhook.hook();
                hooked = true;
            }
            if (!mapSelectScreen && hooked)
            {
                kbhook.unhook();
                hooked = false;
            }
        }
        public void Tick(IOsuMemoryReader reader, bool sendEvents)
        {
            _currentStatus = reader.GetCurrentStatus(out _);
            if (_lastStatusLog != _currentStatus)
            {
                _lastStatusLog = _currentStatus;
                //Console.WriteLine("status: {0} {1}", _currentStatus, _currentStatus == OsuMemoryStatus.Unknown ? num.ToString() : "");
            }

            if (_currentStatus != OsuMemoryStatus.NotRunning)
            {
                _currentMapId     = reader.GetMapId();
                _currentMapString = reader.GetSongString();
                OsuStatus status           = _currentStatus.Convert();
                var       gameMode         = reader.ReadSongSelectGameMode();
                var       mapHash          = reader.GetMapMd5Safe();
                var       mapSelectionMods = reader.GetMods();
                var       mapHashDiffers   = mapHash != null && _lastMapHash != null && _lastMapHash != mapHash;

                if (sendEvents &&
                    (_lastMapId != _currentMapId ||
                     _lastStatus != _currentStatus ||
                     _currentMapString != _lastMapString ||
                     gameMode != _lastGameMode ||
                     mapSelectionMods != _lastMapSelectionMods ||
                     mapHashDiffers)
                    )
                {
                    _lastMapId            = _currentMapId;
                    _lastStatus           = _currentStatus;
                    _lastMapString        = _currentMapString;
                    _lastGameMode         = gameMode;
                    _lastMapSelectionMods = mapSelectionMods;
                    _lastMapHash          = mapHash;


                    NewOsuEvent?.Invoke(this, new MapSearchArgs("OsuMemory")
                    {
                        MapId    = _currentMapId,
                        Status   = status,
                        Raw      = _currentMapString,
                        MapHash  = mapHash,
                        PlayMode = (PlayMode)gameMode,
                    });
                }

                _memoryDataProcessor.Tick(status, reader);
            }
        }
        public void Tick(OsuStatus status, OsuMemoryStatus rawStatus, StructuredOsuMemoryReader reader)
        {
            _notUpdatingTokens.WaitOne();
            _notUpdatingMemoryValues.Reset();
            lock (_lockingObject)
            {
                if (!ReferenceEquals(OsuMemoryData, reader.OsuMemoryAddresses))
                {
                    OsuMemoryData = reader.OsuMemoryAddresses;
                    _rawData.Play = OsuMemoryData.Player;
                }
                if ((OsuStatus)_liveTokens["status"].Token.Value != status)
                {
                    _liveTokens["status"].Token.Value = status;
                }

                _liveTokens["rawStatus"].Token.Value = rawStatus;

                if (status != OsuStatus.Playing && status != OsuStatus.Watching)
                {
                    var rawAudioTime = Retry.RetryMe(() =>
                                                     reader.ReadProperty(OsuMemoryData.GeneralData, nameof(GeneralData.AudioTime)), (val => val != null), 5);
                    if (int.TryParse(rawAudioTime?.ToString(), out var audioTime))
                    {
                        _rawData.PlayTime = audioTime;
                    }

                    reader.Read(OsuMemoryData.Skin);
                    UpdateLiveTokens(status);
                    _lastStatus = status;
                    _notUpdatingMemoryValues.Set();
                    return;
                }

                if (_lastStatus != OsuStatus.Playing && _lastStatus != OsuStatus.Watching)
                {
                    _newPlayStarted.Set();
                    Thread.Sleep(500);//Initial play delay
                }

                reader.Read(OsuMemoryData.Player);
                _rawData.PlayTime = OsuMemoryData.GeneralData.AudioTime;
                _liveTokens["time"].Update();

                _lastStatus = status;
            }

            _notUpdatingMemoryValues.Set();
        }
        public void Tick(OsuStatus status, OsuMemoryStatus rawStatus, StructuredOsuMemoryReader reader)
        {
            _notUpdatingTokens.WaitOne();
            _notUpdatingMemoryValues.Reset();
            lock (_lockingObject)
            {
                if (!ReferenceEquals(OsuMemoryData, reader.OsuMemoryAddresses))
                {
                    OsuMemoryData = reader.OsuMemoryAddresses;
                }
                if ((OsuStatus)_liveTokens["status"].Token.Value != status)
                {
                    _liveTokens["status"].Token.Value = status;
                }

                _liveTokens["rawStatus"].Token.Value = rawStatus;
                int playTime = OsuMemoryData.GeneralData.AudioTime;
                switch (status)
                {
                case OsuStatus.Playing:
                case OsuStatus.Watching:
                    if (_lastStatus != OsuStatus.Playing && _lastStatus != OsuStatus.Watching)
                    {
                        _newPlayStarted.Set();
                        Thread.Sleep(500);    //Initial play delay
                    }

                    reader.TryRead(OsuMemoryData.Player);
                    if (!ReferenceEquals(_rawData.Play, OsuMemoryData.Player))
                    {
                        _rawData.Play = OsuMemoryData.Player;
                    }

                    //TODO: support for live multiplayer leaderboard
                    if (!ReadLeaderboard)
                    {
                        //Read whole leaderboard once
                        if (reader.TryRead(OsuMemoryData.LeaderBoard))
                        {
                            ReadLeaderboard = true;
                            if (!ReferenceEquals(_rawData.LeaderBoard, OsuMemoryData.LeaderBoard))
                            {
                                _rawData.LeaderBoard = OsuMemoryData.LeaderBoard;
                            }
                        }
                    }
                    else
                    {
                        //Throttle whole leaderboard reads - Temporary solution until multiplayer detection is implemented, this should be only done in multiplayer
                        if (_nextLeaderBoardUpdate < DateTime.UtcNow)
                        {
                            reader.TryRead(OsuMemoryData.LeaderBoard);
                            _nextLeaderBoardUpdate = DateTime.UtcNow.AddMilliseconds(_settings.Get <int>(MultiplayerLeaderBoardUpdateRate));
                        }
                        else
                        {
                            //...then update main player data
                            if (OsuMemoryData.LeaderBoard.HasLeaderBoard)
                            {
                                reader.TryRead(OsuMemoryData.LeaderBoard.MainPlayer);
                            }
                        }
                    }

                    break;

                case OsuStatus.ResultsScreen:
                    ReadLeaderboard = false;
                    reader.TryRead(OsuMemoryData.ResultsScreen);
                    if (!ReferenceEquals(_rawData.Play, OsuMemoryData.ResultsScreen))
                    {
                        _rawData.Play = OsuMemoryData.ResultsScreen;
                    }

                    playTime = Convert.ToInt32(_rawData.PpCalculator?.BeatmapLength ?? 0);
                    break;

                default:
                    ReadLeaderboard      = false;
                    _rawData.LeaderBoard = new LeaderBoard();
                    reader.TryRead(OsuMemoryData.Skin);
                    _lastStatus = status;
                    break;
                }

                _rawData.PlayTime = playTime;
                _liveTokens["time"].Update();

                _lastStatus = status;
            }

            _notUpdatingMemoryValues.Set();
        }
Esempio n. 6
0
        public void Tick(List <StructuredOsuMemoryReader> clientReaders, bool sendEvents)
        {
            var reader  = clientReaders[0];
            var osuData = reader.OsuMemoryAddresses;

            if (!reader.TryRead(osuData.GeneralData))
            {
                return;
            }

            _currentStatus = osuData.GeneralData.OsuStatus;
            if (_lastStatusLog != _currentStatus)
            {
                _lastStatusLog = _currentStatus;
                //Console.WriteLine("status: {0} {1}", _currentStatus, _currentStatus == OsuMemoryStatus.Unknown ? num.ToString() : "");
            }

            if (_currentStatus == OsuMemoryStatus.NotRunning)
            {
                return;
            }

            if (!reader.TryRead(osuData.Beatmap))
            {
                return;
            }

            if (!reader.TryReadProperty(osuData.Player, nameof(Player.IsReplay), out var rawIsReplay))
            {
                return;
            }

            _currentMapId = osuData.Beatmap.Id;
            var isReplay = (bool)rawIsReplay;

            OsuStatus status = _currentStatus.Convert();

            status = status == OsuStatus.Playing && isReplay
                ? OsuStatus.Watching
                : status;

            var gameMode = osuData.GeneralData.GameMode;
            var mapHash  = osuData.Beatmap.Md5;

            var mods = osuData.GeneralData.Mods;

            if (status == OsuStatus.Playing || status == OsuStatus.Watching)
            {
                if (!reader.TryReadProperty(osuData.Player, nameof(Player.Mods), out var rawMods) || rawMods == null)
                {
                    return;
                }

                mods = ((Mods)rawMods).Value;
            }
            else if (status == OsuStatus.ResultsScreen)
            {
                if (!reader.TryReadProperty(osuData.ResultsScreen, nameof(ResultsScreen.Mods), out var rawMods) || rawMods == null)
                {
                    return;
                }

                mods = ((Mods)rawMods).Value;
            }

            if (Helpers.IsInvalidCombination((CollectionManager.DataTypes.Mods)mods))
            {
                return;
            }

            var retries     = osuData.GeneralData.Retries;
            var currentTime = osuData.GeneralData.AudioTime;

            var          mapHashDiffers      = mapHash != null && _lastMapHash != null && _lastMapHash != mapHash;
            var          mapIdDiffers        = _lastMapId != _currentMapId;
            var          memoryStatusDiffers = _lastStatus != _currentStatus;
            var          gameModeDiffers     = gameMode != _lastGameMode;
            var          modsDiffer          = mods != _lastSentMods;
            OsuEventType?osuEventType        = null;

            //"good enough" replay retry detection.
            if (isReplay && _currentStatus == OsuMemoryStatus.Playing && _lastTime > currentTime && DateTime.UtcNow > _nextReplayRetryAllowedAt)
            {
                osuEventType = OsuEventType.PlayChange;
                _nextReplayRetryAllowedAt = DateTime.UtcNow.AddMilliseconds(500);
            }

            _lastTime = currentTime;
            var playInitialized = (status != OsuStatus.Watching && status != OsuStatus.Playing) || mods != -1;

            if (sendEvents && playInitialized && (
                    osuEventType.HasValue ||
                    mapIdDiffers || memoryStatusDiffers ||
                    mapHashDiffers || gameModeDiffers || modsDiffer ||
                    retries != _lastRetries
                    )
                )
            {
                if (!osuEventType.HasValue || modsDiffer)
                {
                    osuEventType =
                        mapIdDiffers || mapHashDiffers || gameModeDiffers || modsDiffer ? OsuEventType.MapChange //different mapId/hash/mode/mods(changed stats) = different map
                        : memoryStatusDiffers ? OsuEventType.SceneChange                                         //memory scene(status) change = Scene change
                        : _currentStatus == OsuMemoryStatus.Playing ? OsuEventType.PlayChange                    // map retry
                        : OsuEventType.MapChange;                                                                //bail
                }

                _lastMapId    = _currentMapId;
                _lastStatus   = _currentStatus;
                _lastRetries  = retries;
                _lastGameMode = gameMode;
                _lastMapHash  = mapHash;
                _lastSentMods = mods;
                var rawString = Retry.RetryMe(
                    () =>
                {
                    var validRead = reader.TryReadProperty(osuData.Beatmap, nameof(CurrentBeatmap.MapString), out var result);
                    return(validRead, (string)result);
                },
                    s => (s.validRead, s.Item2), 5) ?? string.Empty;

                NewOsuEvent?.Invoke(this, new MemoryMapSearchArgs(osuEventType.Value)
                {
                    MapId    = _currentMapId,
                    Status   = status,
                    Raw      = rawString,
                    MapHash  = mapHash,
                    PlayMode = (PlayMode)gameMode,
                    Mods     = mods
                });
            }

            for (int i = 0; i < clientReaders.Count; i++)
            {
                _memoryDataProcessors[i].Tick(status, _currentStatus, clientReaders[i]);
            }
        }
Esempio n. 7
0
        public void Tick(IOsuMemoryReader reader, bool sendEvents)
        {
            _currentStatus = reader.GetCurrentStatus(out _);
            if (_lastStatusLog != _currentStatus)
            {
                _lastStatusLog = _currentStatus;
                //Console.WriteLine("status: {0} {1}", _currentStatus, _currentStatus == OsuMemoryStatus.Unknown ? num.ToString() : "");
            }

            if (_currentStatus != OsuMemoryStatus.NotRunning)
            {
                _currentMapId = reader.GetMapId();
                var       isReplay = reader.IsReplay();
                OsuStatus status   = _currentStatus.Convert();
                status = status == OsuStatus.Playing && isReplay
                    ? OsuStatus.Watching
                    : status;

                var gameMode         = reader.ReadSongSelectGameMode();
                var mapHash          = reader.GetMapMd5Safe();
                var mapSelectionMods = reader.GetMods();
                var playingMods      = status == OsuStatus.Playing || status == OsuStatus.Watching
                    ? reader.GetPlayingMods()
                    : -1;
                var retries     = reader.GetRetrys();
                var currentTime = reader.ReadPlayTime();

                var          mapHashDiffers         = mapHash != null && _lastMapHash != null && _lastMapHash != mapHash;
                var          mapIdDiffers           = _lastMapId != _currentMapId;
                var          memoryStatusDiffers    = _lastStatus != _currentStatus;
                var          gameModeDiffers        = gameMode != _lastGameMode;
                var          mapSelectionModsDiffer = mapSelectionMods != _lastMapSelectionMods;
                var          playingModsDiffer      = (status == OsuStatus.Watching || status == OsuStatus.Playing) && playingMods != _lastPlayingMods;
                OsuEventType?osuEventType           = null;
                //"good enough" replay retry detection.
                if (isReplay && _currentStatus == OsuMemoryStatus.Playing && _lastTime > currentTime && DateTime.UtcNow > _nextReplayRetryAllowedAt)
                {
                    osuEventType = OsuEventType.PlayChange;
                    _nextReplayRetryAllowedAt = DateTime.UtcNow.AddMilliseconds(500);
                }

                _lastTime = currentTime;
                var playInitialized = (status != OsuStatus.Watching && status != OsuStatus.Playing) || playingMods != -1;
                if (sendEvents && playInitialized && (
                        osuEventType.HasValue ||
                        mapIdDiffers || memoryStatusDiffers ||
                        mapHashDiffers || gameModeDiffers ||
                        mapSelectionModsDiffer ||
                        retries != _lastRetries
                        )
                    )
                {
                    if (!osuEventType.HasValue || playingModsDiffer)
                    {
                        osuEventType =
                            mapIdDiffers || mapHashDiffers || gameModeDiffers || mapSelectionModsDiffer || playingModsDiffer ? OsuEventType.MapChange //different mapId/hash/mode/mods(changed stats) = different map
                            : memoryStatusDiffers ? OsuEventType.SceneChange                                                                          //memory scene(status) change = Scene change
                            : _currentStatus == OsuMemoryStatus.Playing ? OsuEventType.PlayChange                                                     // map retry
                            : OsuEventType.MapChange;                                                                                                 //bail
                    }

                    _lastMapId            = _currentMapId;
                    _lastStatus           = _currentStatus;
                    _lastRetries          = retries;
                    _lastGameMode         = gameMode;
                    _lastMapSelectionMods = mapSelectionMods;
                    _lastMapHash          = mapHash;
                    _lastPlayingMods      = playingMods;

                    NewOsuEvent?.Invoke(this, new MapSearchArgs("OsuMemory", osuEventType.Value)
                    {
                        MapId    = _currentMapId,
                        Status   = status,
                        Raw      = reader.GetSongString(),
                        MapHash  = mapHash,
                        PlayMode = (PlayMode)gameMode,
                    });
                }

                _memoryDataProcessor.Tick(status, reader);
            }
        }
        public void Tick(List <StructuredOsuMemoryReader> clientReaders, bool sendEvents)
        {
            var reader  = clientReaders[0];
            var osuData = reader.OsuMemoryAddresses;

            reader.Read(osuData.GeneralData);
            _currentStatus = osuData.GeneralData.OsuStatus;
            if (_lastStatusLog != _currentStatus)
            {
                _lastStatusLog = _currentStatus;
                //Console.WriteLine("status: {0} {1}", _currentStatus, _currentStatus == OsuMemoryStatus.Unknown ? num.ToString() : "");
            }

            if (_currentStatus == OsuMemoryStatus.NotRunning)
            {
                return;
            }

            reader.Read(osuData.Beatmap);
            _currentMapId = osuData.Beatmap.Id;
            var isReplay = (bool?)reader.ReadProperty(osuData.Player, nameof(Player.IsReplay));

            if (isReplay == null)
            {
                return;
            }

            OsuStatus status = _currentStatus.Convert();

            status = status == OsuStatus.Playing && isReplay.Value
                ? OsuStatus.Watching
                : status;

            var gameMode         = osuData.GeneralData.GameMode;
            var mapHash          = osuData.Beatmap.Md5;
            var mapSelectionMods = osuData.GeneralData.Mods;
            var playingMods      = -1;

            if (status == OsuStatus.Playing || status == OsuStatus.Watching)
            {
                var mods = ((Mods)reader.ReadProperty(osuData.Player, nameof(Player.Mods)))?.Value;
                if (mods == null)
                {
                    return;
                }

                playingMods = mods.Value;
            }
            var retries     = osuData.GeneralData.Retries;
            var currentTime = osuData.GeneralData.AudioTime;

            var          mapHashDiffers         = mapHash != null && _lastMapHash != null && _lastMapHash != mapHash;
            var          mapIdDiffers           = _lastMapId != _currentMapId;
            var          memoryStatusDiffers    = _lastStatus != _currentStatus;
            var          gameModeDiffers        = gameMode != _lastGameMode;
            var          mapSelectionModsDiffer = mapSelectionMods != _lastMapSelectionMods;
            var          playingModsDiffer      = (status == OsuStatus.Watching || status == OsuStatus.Playing) && playingMods != _lastPlayingMods;
            OsuEventType?osuEventType           = null;

            //"good enough" replay retry detection.
            if (isReplay.Value && _currentStatus == OsuMemoryStatus.Playing && _lastTime > currentTime && DateTime.UtcNow > _nextReplayRetryAllowedAt)
            {
                osuEventType = OsuEventType.PlayChange;
                _nextReplayRetryAllowedAt = DateTime.UtcNow.AddMilliseconds(500);
            }

            _lastTime = currentTime;
            var playInitialized = (status != OsuStatus.Watching && status != OsuStatus.Playing) || playingMods != -1;

            if (sendEvents && playInitialized && (
                    osuEventType.HasValue ||
                    mapIdDiffers || memoryStatusDiffers ||
                    mapHashDiffers || gameModeDiffers ||
                    mapSelectionModsDiffer || playingModsDiffer ||
                    retries != _lastRetries
                    )
                )
            {
                if (!osuEventType.HasValue || playingModsDiffer)
                {
                    osuEventType =
                        mapIdDiffers || mapHashDiffers || gameModeDiffers || mapSelectionModsDiffer || playingModsDiffer ? OsuEventType.MapChange //different mapId/hash/mode/mods(changed stats) = different map
                        : memoryStatusDiffers ? OsuEventType.SceneChange                                                                          //memory scene(status) change = Scene change
                        : _currentStatus == OsuMemoryStatus.Playing ? OsuEventType.PlayChange                                                     // map retry
                        : OsuEventType.MapChange;                                                                                                 //bail
                }

                _lastMapId            = _currentMapId;
                _lastStatus           = _currentStatus;
                _lastRetries          = retries;
                _lastGameMode         = gameMode;
                _lastMapSelectionMods = mapSelectionMods;
                _lastMapHash          = mapHash;
                _lastPlayingMods      = playingMods;

                var rawString = Retry.RetryMe(() => (string)reader.ReadProperty(osuData.Beatmap, nameof(CurrentBeatmap.Md5)),
                                              s => (System.Text.Encoding.UTF8.GetByteCount(s ?? string.Empty) == s?.Length), 5) ?? string.Empty;

                NewOsuEvent?.Invoke(this, new MemoryMapSearchArgs(osuEventType.Value)
                {
                    MapId    = _currentMapId,
                    Status   = status,
                    Raw      = rawString,
                    MapHash  = mapHash,
                    PlayMode = (PlayMode)gameMode,
                    Mods     = playingMods != -1 ? playingMods : mapSelectionMods
                });
            }

            for (int i = 0; i < clientReaders.Count; i++)
            {
                _memoryDataProcessors[i].Tick(status, _currentStatus, clientReaders[i]);
            }
        }