forum

Read Accuracy/Combo/Total Score from .osr file (osu! replay)

posted
Total Posts
9
Topic Starter
Woddles
Been working on a website project for osu for a little while now, all I am left to do till I can finish up the website is figure out how to get the Accuracy, highest Combo and Total Score from the replay file itself (if this is even possible). If this isn't directly available (which I assume most of it isn't since the majority of the replay file is (afaik) timing and position of hitting notes during the song (?).

How do I go about calculating/retrieving this information? Or if there are any premade functions people already use for their own site, I'd greatly appreciate some of your insight into how to do this for my own site!

Thanks alot everyone, many things I've found on the forums/pming helpful users have been amazing help. (:
Piotrekol
p/1953286

statementreply wrote:

My guesses:
SPOILER
Replay file
00000000h: 00                                              ; .
Game mode: 00: osu! standard, 01: taiko, 02: ctb, 03: osu!mania
00000001h: 18 06 33 01                                     ; ..3.
File format version or something like this
00000005h: 0B 20 34 65 63 61 65 33 61 30 31 33 33 35 33 64 ; . 4ecae3a013353d
00000015h: 33 39 63 37 64 31 33 33 32 62 32 30 36 31 65 62 ; 39c7d1332b2061eb
00000025h: 39 61 ; 9a
0x0B
Chunk length in ULEB128
MD5 of .osu file
00000027h: 0B 0E 73 74 61 74 65 6D 65 6E 74 72 65 70 6C 79 ; ..statementreply
0x0B
Chunk length in ULEB128
Player
00000037h: 0B 20 66 31 63 64 63 62 65 63 37 34 35 35 31 62 ; . f1cdcbec74551b
00000047h: 65 32 36 34 36 65 66 38 35 62 61 33 65 64 61 66 ; e2646ef85ba3edaf
00000057h: 64 36 ; d6
0x0B
Chunk length in ULEB128
MD5 of something derived from replay
00000059h: D9 00                                           ; ..
300
0000005bh: 00 00                                           ; ..
100 (taiko: 150, osu!mania: 200)
0000005dh: 00 00                                           ; ..
50
0000005fh: 2D 00                                           ; -.
Geki (osu!mania: MAX)
00000061h: 00 00                                           ; ..
Katu (osu!mania: 100)
00000063h: 00 00                                           ; ..
Miss
00000065h: 73 7E 20 00                                     ; s~ .
Total score
00000069h: 7B 01                                           ; {.
Max combo
0000006bh: 01                                              ; .
Perfect or not
0000006ch: 2C 40 00 00                                     ; ,@..
Mods:
0x1: No fail
0x2: Easy
0x4: No video
0x8: Hidden
0x10: Hard rock
0x20: Sudden death
0x40: Double time
0x80: Relax
0x100: Half time
0x200: Nightcore (Nightcore = 0x0240 = Nightcore + Double time)
0x400: Flashlight
0x800: Auto
0x1000: Spun out
0x2000: Auto pilot
0x4000: Perfect (Perfect = 0x4020 = Perfect + No fail)
0x8000: 4K
0x10000: 5K
0x20000: 6K
0x40000: 7K
0x80000: 8K
00000070h: 0B DC 02 31 34 33 37 30 7C 31 2C 31 36 36 32 31 ; ...14370|1,16621
00000080h: 7C 31 2C 31 38 36 38 31 7C 31 2C 32 31 31 31 39 ; |1,18681|1,21119
00000090h: 7C 31 2C 32 33 33 37 31 7C 31 2C 32 35 36 32 32 ; |1,23371|1,25622
000000a0h: 7C 31 2C 32 37 38 36 39 7C 31 2C 33 30 31 32 31 ; |1,27869|1,30121
000000b0h: 7C 31 2C 33 32 33 37 30 7C 31 2C 33 34 36 32 30 ; |1,32370|1,34620
000000c0h: 7C 31 2C 33 37 32 34 38 7C 31 2C 33 39 32 38 34 ; |1,37248|1,39284
000000d0h: 7C 31 2C 34 31 33 37 30 7C 31 2C 34 33 36 32 30 ; |1,41370|1,43620
000000e0h: 7C 31 2C 34 35 38 37 30 7C 31 2C 34 38 31 32 30 ; |1,45870|1,48120
000000f0h: 7C 31 2C 35 30 31 36 38 7C 31 2C 35 32 34 33 33 ; |1,50168|1,52433
00000100h: 7C 31 2C 35 34 36 38 33 7C 31 2C 35 36 37 33 34 ; |1,54683|1,56734
00000110h: 7C 31 2C 35 38 38 30 37 7C 31 2C 36 30 38 37 30 ; |1,58807|1,60870
00000120h: 7C 31 2C 36 32 39 33 31 7C 31 2C 36 35 31 38 31 ; |1,62931|1,65181
00000130h: 7C 31 2C 36 37 34 33 34 7C 31 2C 36 39 38 36 39 ; |1,67434|1,69869
00000140h: 7C 31 2C 37 32 31 32 30 7C 31 2C 37 34 31 37 35 ; |1,72120|1,74175
00000150h: 7C 31 2C 37 36 32 34 35 7C 31 2C 37 38 33 30 35 ; |1,76245|1,78305
00000160h: 7C 31 2C 38 30 33 37 30 7C 31 2C 38 32 38 30 38 ; |1,80370|1,82808
00000170h: 7C 31 2C 38 34 38 37 31 7C 31 2C 38 36 39 33 32 ; |1,84871|1,86932
00000180h: 7C 31 2C 38 39 31 38 33 7C 31 2C 39 31 38 30 36 ; |1,89183|1,91806
00000190h: 7C 31 2C 39 33 38 37 30 7C 31 2C 39 35 39 33 32 ; |1,93870|1,95932
000001a0h: 7C 31 2C 39 38 33 37 31 7C 31 2C 31 30 30 34 31 ; |1,98371|1,10041
000001b0h: 39 7C 31 2C 31 30 32 38 37 30 7C 31 2C 31 30 35 ; 9|1,102870|1,105
000001c0h: 30 32 37 7C 31 2C 31 30 36 38 30 37 7C 31 2C ; 027|1,106807|1,
0x0B
Chunk length in ULEB128
HP vs. time graph
000001cfh: 32 5F 87 9C F0 8E CF 08                         ; 2_......
Date/time

EDIT: Fixed typo
EDIT2: VLQ ULEB128
Topic Starter
Woddles

Piotrekol wrote:

http://osu.ppy.sh/forum/p/1953286

statementreply wrote:

My guesses:
SPOILER
Replay file
00000000h: 00                                              ; .
Game mode: 00: osu! standard, 01: taiko, 02: ctb, 03: osu!mania
00000001h: 18 06 33 01                                     ; ..3.
File format version or something like this
00000005h: 0B 20 34 65 63 61 65 33 61 30 31 33 33 35 33 64 ; . 4ecae3a013353d
00000015h: 33 39 63 37 64 31 33 33 32 62 32 30 36 31 65 62 ; 39c7d1332b2061eb
00000025h: 39 61 ; 9a
0x0B
Chunk length in ULEB128
MD5 of .osu file
00000027h: 0B 0E 73 74 61 74 65 6D 65 6E 74 72 65 70 6C 79 ; ..statementreply
0x0B
Chunk length in ULEB128
Player
00000037h: 0B 20 66 31 63 64 63 62 65 63 37 34 35 35 31 62 ; . f1cdcbec74551b
00000047h: 65 32 36 34 36 65 66 38 35 62 61 33 65 64 61 66 ; e2646ef85ba3edaf
00000057h: 64 36 ; d6
0x0B
Chunk length in ULEB128
MD5 of something derived from replay
00000059h: D9 00                                           ; ..
300
0000005bh: 00 00                                           ; ..
100 (taiko: 150, osu!mania: 200)
0000005dh: 00 00                                           ; ..
50
0000005fh: 2D 00                                           ; -.
Geki (osu!mania: MAX)
00000061h: 00 00                                           ; ..
Katu (osu!mania: 100)
00000063h: 00 00                                           ; ..
Miss
00000065h: 73 7E 20 00                                     ; s~ .
Total score
00000069h: 7B 01                                           ; {.
Max combo
0000006bh: 01                                              ; .
Perfect or not
0000006ch: 2C 40 00 00                                     ; ,@..
Mods:
0x1: No fail
0x2: Easy
0x4: No video
0x8: Hidden
0x10: Hard rock
0x20: Sudden death
0x40: Double time
0x80: Relax
0x100: Half time
0x200: Nightcore (Nightcore = 0x0240 = Nightcore + Double time)
0x400: Flashlight
0x800: Auto
0x1000: Spun out
0x2000: Auto pilot
0x4000: Perfect (Perfect = 0x4020 = Perfect + No fail)
0x8000: 4K
0x10000: 5K
0x20000: 6K
0x40000: 7K
0x80000: 8K
00000070h: 0B DC 02 31 34 33 37 30 7C 31 2C 31 36 36 32 31 ; ...14370|1,16621
00000080h: 7C 31 2C 31 38 36 38 31 7C 31 2C 32 31 31 31 39 ; |1,18681|1,21119
00000090h: 7C 31 2C 32 33 33 37 31 7C 31 2C 32 35 36 32 32 ; |1,23371|1,25622
000000a0h: 7C 31 2C 32 37 38 36 39 7C 31 2C 33 30 31 32 31 ; |1,27869|1,30121
000000b0h: 7C 31 2C 33 32 33 37 30 7C 31 2C 33 34 36 32 30 ; |1,32370|1,34620
000000c0h: 7C 31 2C 33 37 32 34 38 7C 31 2C 33 39 32 38 34 ; |1,37248|1,39284
000000d0h: 7C 31 2C 34 31 33 37 30 7C 31 2C 34 33 36 32 30 ; |1,41370|1,43620
000000e0h: 7C 31 2C 34 35 38 37 30 7C 31 2C 34 38 31 32 30 ; |1,45870|1,48120
000000f0h: 7C 31 2C 35 30 31 36 38 7C 31 2C 35 32 34 33 33 ; |1,50168|1,52433
00000100h: 7C 31 2C 35 34 36 38 33 7C 31 2C 35 36 37 33 34 ; |1,54683|1,56734
00000110h: 7C 31 2C 35 38 38 30 37 7C 31 2C 36 30 38 37 30 ; |1,58807|1,60870
00000120h: 7C 31 2C 36 32 39 33 31 7C 31 2C 36 35 31 38 31 ; |1,62931|1,65181
00000130h: 7C 31 2C 36 37 34 33 34 7C 31 2C 36 39 38 36 39 ; |1,67434|1,69869
00000140h: 7C 31 2C 37 32 31 32 30 7C 31 2C 37 34 31 37 35 ; |1,72120|1,74175
00000150h: 7C 31 2C 37 36 32 34 35 7C 31 2C 37 38 33 30 35 ; |1,76245|1,78305
00000160h: 7C 31 2C 38 30 33 37 30 7C 31 2C 38 32 38 30 38 ; |1,80370|1,82808
00000170h: 7C 31 2C 38 34 38 37 31 7C 31 2C 38 36 39 33 32 ; |1,84871|1,86932
00000180h: 7C 31 2C 38 39 31 38 33 7C 31 2C 39 31 38 30 36 ; |1,89183|1,91806
00000190h: 7C 31 2C 39 33 38 37 30 7C 31 2C 39 35 39 33 32 ; |1,93870|1,95932
000001a0h: 7C 31 2C 39 38 33 37 31 7C 31 2C 31 30 30 34 31 ; |1,98371|1,10041
000001b0h: 39 7C 31 2C 31 30 32 38 37 30 7C 31 2C 31 30 35 ; 9|1,102870|1,105
000001c0h: 30 32 37 7C 31 2C 31 30 36 38 30 37 7C 31 2C ; 027|1,106807|1,
0x0B
Chunk length in ULEB128
HP vs. time graph
000001cfh: 32 5F 87 9C F0 8E CF 08                         ; 2_......
Date/time

EDIT: Fixed typo
EDIT2: VLQ ULEB128
Yes I've already seen this, but to me this doesn't mean alot since I don't understand the whole 'hexadecimal' stuffs. Also the HP vs. Time graph, I see that info in each replay file pretty clearly but have no idea how to 'convert' it persey, to a readable/printable format so that I can summarize it into total score/accuracy.

Thanks for the input.
Bauxe

Woddles wrote:

Yes I've already seen this, but to me this doesn't mean alot since I don't understand the whole 'hexadecimal' stuffs. Also the HP vs. Time graph, I see that info in each replay file pretty clearly but have no idea how to 'convert' it persey, to a readable/printable format so that I can summarize it into total score/accuracy.

Thanks for the input.
You might need to learn about it then. They are stored as hexadecimal, so you will need to be reading them as hexadecimal.
Topic Starter
Woddles

Bauxe wrote:

Woddles wrote:

Yes I've already seen this, but to me this doesn't mean alot since I don't understand the whole 'hexadecimal' stuffs. Also the HP vs. Time graph, I see that info in each replay file pretty clearly but have no idea how to 'convert' it persey, to a readable/printable format so that I can summarize it into total score/accuracy.

Thanks for the input.
You might need to learn about it then. They are stored as hexadecimal, so you will need to be reading them as hexadecimal.
I read up about hexadecimal for a while today, as well as trying to use the info from the linked thread above to try and get the info I need.

Buuut this is where this confused me even more. Things like this made no sense to me:
00000065h: 73 7E 20 00                                     ; s~ .
Total score


Yes, I can find this block of hexademical data in each replay file easily, but I don't understand how it translates to the total score of that replay file? I'm probably missing something extremely obvious here and I'm going to look very stupid shortly, but I really am a tad lost when it comes to hex references like these because first of all I don't even know how the OP originally figured out what each section of bytes represented in the replay file, nor how you actually are able to get any values from these small sections of bytes.

I at least know how to read and write hex now (thanks to this video). Well, slowly progressing and asking questions is always the way to go when you're stuck in programming! (:
Topic Starter
Woddles
Bumping in hopes there is someone who can help me figure this out at all.
MillhioreF
Some data structures are [google:1337]little endian[/google:1337], which basically means that their bytes are read backwards. In your example, you would want to read 73 7E 20 00 as 00 20 7E 73, which translates to 2,129,523 (a much more reasonable score for an osu! map)

When it comes to figuring arbitrary values out, you basically have to look for numbers that you know are stored in the file somewhere, and then search for the raw values of said things in hexadecimal. It's a heck of a lot harder when encryption is involved.
Topic Starter
Woddles

MillhioreF wrote:

Some data structures are [google:1337]little endian[/google:1337], which basically means that their bytes are read backwards. In your example, you would want to read 73 7E 20 00 as 00 20 7E 73, which translates to 2,129,523 (a much more reasonable score for an osu! map)

When it comes to figuring arbitrary values out, you basically have to look for numbers that you know are stored in the file somewhere, and then search for the raw values of said things in hexadecimal. It's a heck of a lot harder when encryption is involved.
Thank you SO much! I was reading about little edian when reading up on hexadecimal but never even thought that it would be used here. Finally have it figured out!

I guess the only issue now is, when I have to check older replay files for their total scores, it's a tad harder because I have to find where exactly the score is stored each time per version of replay.

This has helped me so immensely though, can't thank you enough for your time to post! c:
Darkimmortal

Woddles wrote:

MillhioreF wrote:

Some data structures are [google:1337]little endian[/google:1337], which basically means that their bytes are read backwards. In your example, you would want to read 73 7E 20 00 as 00 20 7E 73, which translates to 2,129,523 (a much more reasonable score for an osu! map)

When it comes to figuring arbitrary values out, you basically have to look for numbers that you know are stored in the file somewhere, and then search for the raw values of said things in hexadecimal. It's a heck of a lot harder when encryption is involved.
Thank you SO much! I was reading about little edian when reading up on hexadecimal but never even thought that it would be used here. Finally have it figured out!

I guess the only issue now is, when I have to check older replay files for their total scores, it's a tad harder because I have to find where exactly the score is stored each time per version of replay.

This has helped me so immensely though, can't thank you enough for your time to post! c:
You can parse the majority of it very lazily with regex, no need for a full implementation. A fixed position per version is definitely the wrong approach with the amount of variable length fields
Please sign in to reply.

New reply