예제 #1
0
        internal void GetScoreResults()
        {
            if (!isInitialized)
            {
                return;
            }
            var rank      = Manipulator.ReadInt32(RESULTS_BASE_ADDRESS + 0xE8);
            var insurance = Manipulator.ReadByte(GAME_INFO_ADDRESS + 0x14);

            if (insurance != 0)
            {
                return;
            }

            // ========== Get Score Results ========== //

            var recordDate = DateTime.UtcNow;
            var resultBase = Manipulator.ReadInt64(RESULTS_BASE_ADDRESS + 0x100);

            var pvId       = Manipulator.ReadInt32(resultBase + 0x2c);
            var difficulty = Manipulator.ReadInt32(resultBase + 0x34);
            var edition    = Manipulator.ReadInt32(resultBase + 0x44);
            var modifier   = Manipulator.ReadInt32(resultBase + 0x70);

            var cntHitTypes    = Manipulator.ReadInt32Array(resultBase + 0x158, 5);
            var pctHitTypes    = Manipulator.ReadInt32Array(resultBase + 0x16c, 5);
            var combo          = Manipulator.ReadInt32(resultBase + 0x180);
            var challengeScore = Manipulator.ReadInt32(resultBase + 0x184);
            var holdScore      = Manipulator.ReadInt32(resultBase + 0x188);
            var score          = Manipulator.ReadInt32(resultBase + 0x18c);
            var percent        = Manipulator.ReadInt32(resultBase + 0x190);
            var slideScore     = Manipulator.ReadInt32(resultBase + 0x194);

            var songNameLen = Manipulator.ReadInt32(CURRENT_SONG_NAME_ADDRESS + 0x18);
            var songNameAdr = songNameLen < 0x10 ? CURRENT_SONG_NAME_ADDRESS : Manipulator.ReadInt64(CURRENT_SONG_NAME_ADDRESS);
            var songName    = Manipulator.ReadUtf8String(songNameAdr);

            // ========== Get Player Data ========== //

            var playerNameAdr = Manipulator.ReadInt64(PLAYER_NAME_ADDRESS);
            var playerName    = Manipulator.ReadUtf8String(playerNameAdr);
            var levelNameAdr  = Manipulator.ReadInt64(PLAYER_LEVEL_NAME_ADDRESS);
            var levelName     = Manipulator.ReadUtf8String(levelNameAdr);
            var level         = Manipulator.ReadInt32(PLAYER_LEVEL_ADDRESS);
            var plateId       = Manipulator.ReadInt32(PLAYER_PLATE_ID_ADDRESS);
            var plateEff      = Manipulator.ReadInt32(PLAYER_PLATE_EFF_ADDRESS);
            var moduleEquip   = Manipulator.ReadInt32Array(PLAYER_MODULE_EQUIP_ADDRESS, 6);

            // ========== Get High Score Record ========== //

            var entry            = playerScore.GetScoreEntry(pvId, difficulty, edition);
            int alltimeScore     = entry.AlltimeScore;
            int alltimePercent   = entry.AlltimePercent;
            int alltimeRank      = entry.AlltimeRank;
            int alltimeModifiers = entry.AlltimeModifiers;

            // ========== Process Score Data ========== //

            if (alltimeScore == -1)
            {
                alltimeScore = entry.Score;
            }
            if (alltimePercent == -1)
            {
                alltimePercent = entry.Percent;
            }
            if (alltimeRank == -1)
            {
                alltimeRank = entry.Rank;
            }
            if (alltimeModifiers == -1)
            {
                alltimeModifiers = entry.Modifiers > 0 ? 1 << (entry.Modifiers - 1) : 0;
            }

            var isNewScore   = (score > alltimeScore);
            var isNewPercent = (percent > alltimePercent);
            var isNewRank    = (rank > alltimeRank);

            var notes = new List <NoteScoreEntry>();

            for (int i = 0; i < 5; i++)
            {
                notes.Add(new NoteScoreEntry()
                {
                    Id      = i,
                    Count   = cntHitTypes[i],
                    Percent = pctHitTypes[i]
                });
            }

            // ========== Update Score History Record ========== //

            var record = new ScoreEntry()
            {
                PvId             = pvId,
                Difficulty       = difficulty,
                Edition          = edition,
                SongName         = songName.Trim(),
                PlayerName       = playerName.Trim(),
                LevelName        = levelName.Trim(),
                Level            = level,
                PlateId          = plateId,
                PlateEff         = plateEff,
                AlltimeScore     = (isNewScore) ? score : alltimeScore,
                AlltimePercent   = (isNewPercent) ? percent : alltimePercent,
                AlltimeRank      = (isNewRank) ? rank : alltimeRank,
                AlltimeModifiers = alltimeModifiers | ((rank > 1 && modifier > 0) ? (1 << (modifier - 1)) : 0),
                Rank             = rank,
                Score            = score,
                Percent          = percent,
                Modifiers        = modifier,
                Notes            = notes,
                Combo            = combo,
                ChallengeScore   = challengeScore,
                HoldScore        = holdScore,
                SlideScore       = slideScore,
                IsNewScore       = isNewScore ? 1 : 0,
                IsNewPercent     = isNewPercent ? 1 : 0,
                ModuleEquip      = moduleEquip,
                RecordDate       = recordDate,
            };

            scoreHistory.Scores.Add(record);

            // ========== Update High Score Record ========== //

            if (isNewPercent || (rank > 1 && (isNewScore || isNewRank)))
            {
                playerScore.UpdateScoreEntry(pvId, difficulty, edition, record);
            }

            // ========== Update Pd_Pv Record ========== //

            SaveCurrentPvSetting(pvId);
            UpdateSingleScoreCacheEntry(pvId, difficulty, edition);
            UpdateClearCounts();
            SaveScoreHistoryData();
        }
        internal void Initialize()
        {
            InjectPatches();
            ReadPlayerData();
            PlayerNameValue = new byte[21];
            var b_name = Encoding.UTF8.GetBytes(playerData.PlayerName);

            Buffer.BlockCopy(b_name, 0, PlayerNameValue, 0, b_name.Length);
            PlayerNameAddress = Manipulator.ReadInt64(PLAYER_NAME_ADDRESS);
            LevelNameValue    = new byte[29];
            var c_name = Encoding.UTF8.GetBytes(playerData.LevelName);

            Buffer.BlockCopy(c_name, 0, LevelNameValue, 0, c_name.Length);
            LevelNameAddress = Manipulator.ReadInt64(PLAYER_LEVEL_NAME_ADDRESS);
            Manipulator.WriteByte(PLAYER_LEVEL_NAME_ADDRESS + 0x10L, 0xFF); // thanks @vladkorotnev
            Manipulator.WriteByte(PLAYER_LEVEL_NAME_ADDRESS + 0x18L, 0x1F); // thanks @vladkorotnev
            if (playerData.Level < 1)
            {
                playerData.Level = 1;
            }
            if (playerData.ActVol < 0 || playerData.ActVol > 100)
            {
                playerData.ActVol = 100;
            }
            if (playerData.HpVol < 0 || playerData.HpVol > 100)
            {
                playerData.HpVol = 100;
            }
            // use_card = 1 // Required to allow for module selection
            if (playerData.UseCard)
            {
                Manipulator.WriteInt32(PLAYER_DATA_ADDRESS, 1);
            }
            // Allow player to select the module and extra items (by vladkorotnev)
            for (long i = 0; i < 128; i++)
            {
                Manipulator.WriteByte(MODULE_TABLE_START + i, 0xFF);
            }
            for (long i = 0; i < 128; i++)
            {
                Manipulator.WriteByte(ITEM_TABLE_START + i, 0xFF);
            }
            // Display interim rank and rhythm options
            Manipulator.WriteByte(PLAYER_RANK_DISP_ADDRESS, 1);
            // Display custom pv module options
            Manipulator.WriteByte(PLAYER_USE_PV_MODULE_ADDRESS, 1);
            // Discovered by vladkorotnev, improved by rakisaionji
            if (playerData.OptionDisp)
            {
                // Allow to use without use_card (by somewhatlurker)
                if (!playerData.UseCard)
                {
                    Manipulator.WritePatchNop(0x00000001405CB14A, 6);
                    Manipulator.WritePatchNop(0x0000000140136CFA, 6);
                }
                Manipulator.WriteByte(PLAYER_OPTION_DISP_ADDRESS, 1);
                Manipulator.WritePatchNop(0x00000001405CA0F5, 2);  // Allow it to be displayed
                Manipulator.WritePatchNop(0x00000001405CB1B3, 13); // Allow it to be set and used
                if (playerData.KeepOption)
                {
                    // It was reset when changing level or song, annoying so prevent it
                    Manipulator.WritePatchNop(0x00000001405C84EE, 6); // Prevent it to be reset
                    Manipulator.WritePatchNop(0x00000001405C84F9, 3); // Prevent it to be reset
                }
            }
            // Enable module selection without card (by lybxlpsv and crash5band) [WIP / NG]
            // if (!playerData.UseCard)
            // {
            //     Manipulator.WritePatch(0x00000001405C513B, new byte[] { 0x01 });
            //     Manipulator.WritePatch(0x000000014010523F, new byte[] { 0x30, 0xC0, 0x90 });
            // }
            // Display clear borders on the progress bar (by vladkorotnev)
            Manipulator.WriteByte(PLAYER_CLEAR_BORDER_ADDRESS, playerData.ClearBorder.ToByte());
            // First write of play start id, only once per starup
            // if (playerData.SetPlayData)
            // {
            //     playIdx = playerData.PlayDataId;
            //     if (playIdx < 10001 || playIdx == uint.MaxValue) playIdx = 10001;
            //     Manipulator.WriteUInt32(PLAYER_PLAY_ID_ADDRESS, playIdx);
            // }
            WritePlayerData();
        }