/// <summary> /// Get all the bytes to create a .osr file. /// </summary> /// <param name="_m">The mode the score was played in.</param> /// <param name="_b">The beatmap ID (not beatmap set ID!) in which the replay was played.</param> /// <param name="_u">The user that has played the beatmap.</param> /// <param name="t">Change the function to the one that returns bytes.</param> /// <param name="_mods">Specify a mod or mod combination (See https://github.com/ppy/osu-api/wiki#mods )</param> /// <param name="_count">This will specify which score to select.</param> /// <returns>.osr file bytes.</returns> public async Task <byte[]> GetReplay(mode _m, string _u, int _b, int _mods = 0, int _count = 0) { var replay = await GetReplay(_m, _b, _u); var sc = await GetScore(_b, _u, _m, _mods); var bt = await GetBeatmap(_b, _isSet : false); var score = sc[_count]; var beatmap = bt[0]; var bin = new BinHandler(); var binWriter = new BinaryWriter(new MemoryStream()); var binReader = new BinaryReader(binWriter.BaseStream); var replayHashData = bin.MD5Hash(score.maxcombo + "osu" + score.username + beatmap.file_md5 + score.score + score.rank); var content = Convert.FromBase64String(replay.content); var mode = Convert.ToInt32(_m).ToString(); // Begin bin.writeByte(binWriter, mode); // Write osu mode. bin.writeInteger(binWriter, 0.ToString()); // Write osu version. (Unknown) bin.writeString(binWriter, beatmap.file_md5); // Write beatmap MD5. bin.writeString(binWriter, score.username); // Write username. bin.writeString(binWriter, replayHashData); // Write replay MD5. bin.writeShort(binWriter, score.count300); // Write 300s count. bin.writeShort(binWriter, score.count100); // Write 100s count. bin.writeShort(binWriter, score.count50); // Write 50s count. bin.writeShort(binWriter, score.countgeki); // Write geki count. bin.writeShort(binWriter, score.countkatu); // Write katu count. bin.writeShort(binWriter, score.countmiss); // Write miss count. bin.writeInteger(binWriter, score.score); // Write score. bin.writeShort(binWriter, score.maxcombo); // Write maxcombo. bin.writeByte(binWriter, score.perfect); // Write if the score is perfect or not. bin.writeInteger(binWriter, score.enabled_mods); // Write which mods where enabled. bin.writeString(binWriter, ""); // Write lifebar hp. (Unknown) bin.writeDate(binWriter, score.date); // Write replay timestamp. bin.writeInteger(binWriter, content.Length.ToString()); // Write replay content lenght. // Content binWriter.Write(content); // Write replay content. // Final binWriter.Write(Convert.ToInt64(score.score_id)); // Write score id. binWriter.Write(BitConverter.GetBytes(Convert.ToUInt32(0)), 4, 0); // Write null byte. binReader.BaseStream.Position = 0; int streamLenght = (int)binReader.BaseStream.Length; // [WARNING!] // The Get Replay Data from osu!api dosen't have a parameter to retrieve a certain replay. // It is possible that the movement of the cursor to be wrong because of that. // There is no way to fix it until such parameter is added. return(binReader.ReadBytes(streamLenght)); }
/// <summary> /// Return all the bytes needed to create a .osr file. /// </summary> /// <param name="_m">The mode the score was played in.</param> /// <param name="_b">The beatmap ID (not beatmap set ID!) in which the replay was played.</param> /// <param name="_u">The user that has played the beatmap.</param> /// <param name="_mods">Specify a mod or mod combination (See https://github.com/ppy/osu-api/wiki#mods )</param> /// <returns>.osr file bytes.</returns> public byte[] GetReplay(mode _m, string _u, long _b, long?_mods = null) { var replay = GetReplay(_m, _b, _u, _mods); var sc = GetScore(_b, _u, _m, _mods); var bt = GetBeatmap(_b, _isSet: false); var score = sc[0]; var beatmap = bt[0]; var binWriter = new BinaryWriter(new MemoryStream()); var bin = new BinHandler(binWriter); var binReader = new BinaryReader(binWriter.BaseStream); var replayHashData = bin.MD5Hash(score.maxcombo + "osu" + score.username + beatmap.MD5 + score.score + score.rank); var content = Convert.FromBase64String(replay.content); var mode = Convert.ToInt32(_m).ToString(); // Begin bin.writeByte(mode); // Write osu mode. bin.writeInteger(0); // Write osu version. (Unknown) bin.writeString(beatmap.MD5); // Write beatmap MD5. bin.writeString(score.username); // Write username. bin.writeString(replayHashData); // Write replay MD5. bin.writeShort(score.count300); // Write 300s count. bin.writeShort(score.count100); // Write 100s count. bin.writeShort(score.count50); // Write 50s count. bin.writeShort(score.countgeki); // Write geki count. bin.writeShort(score.countkatu); // Write katu count. bin.writeShort(score.countmiss); // Write miss count. bin.writeInteger(score.score); // Write score. bin.writeShort(score.maxcombo); // Write maxcombo. bin.writeByte((score.perfect ? 1:0).ToString()); // Write if the score is perfect or not. if (score.enabled_mods == null) { bin.writeInteger(null); // Write null int if no mods were enabled. } else { bin.writeInteger(Convert.ToInt32(modsCalculator( // Use mods calculator to get the long for enabled mods. score.enabled_mods.ToList() // Cast mods array to List. ))); // Cast the long to string then write enabled mods. } bin.writeString(""); // Write lifebar hp. (Unknown) bin.writeDate(score.date); // Write replay timestamp. bin.writeInteger(content.Length); // Write replay content lenght. // Content binWriter.Write(content); // Write replay content. // Final binWriter.Write(Convert.ToInt64(score.score_id)); // Write score id. binWriter.Write(BitConverter.GetBytes(Convert.ToUInt32(0)), 4, 0); // Write null byte. binReader.BaseStream.Position = 0; int streamLenght = (int)binReader.BaseStream.Length; // [WARNING!] // The Get Replay Data from osu!api dosen't have a parameter to retrieve a certain replay. // It is possible that the movement of the cursor to be wrong because of that. // There is no way to fix it until such parameter is added. return(binReader.ReadBytes(streamLenght)); }