Fixed replay length (it is not ULEB)

This commit is contained in:
Emily 2019-03-17 02:57:48 +01:00
parent fc5bd5dc00
commit 15c80aae66
5 changed files with 43 additions and 24 deletions

View File

@ -24,8 +24,17 @@ class ReplayFrame:
raise Exception("Buttons are out of range")
self.buttons = buttons
@staticmethod
def _float_convert(f):
if f % 1 == 0:
return repr(int(f))
return repr(round(f, 1))
def __str__(self):
return "%d|%s|%s|%d," % (self.delta, repr(self.x), repr(self.y), self.buttons)
return "%d|%s|%s|%d," % (self.delta,
self._float_convert(self.x),
self._float_convert(self.y),
self.buttons)
def __bytes__(self):
return str(self).encode()

View File

@ -1,10 +1,9 @@
SSH = 0
SH = 1
SS = 2
S = 3
A = 4
B = 5
C = 6
D = 7
F = 8
N = 9
SSH = b"XH"
SH = b"SH"
SS = b"X"
S = b"S"
A = b"A"
B = b"B"
C = b"C"
D = b"D"
F = b"F"

View File

@ -105,6 +105,7 @@ class Serializable:
def pack(self, byte_order = BYTEORDER_LITTLE):
struct_fmt = byte_order + self.get_struct_fmt()
#print(struct_fmt, self.get_value())
return struct.pack(struct_fmt, *self.get_value())
class Serializer:

View File

@ -1,6 +1,7 @@
import struct
import string
import lzma
#import lzma
import pylzma # Required cause pythons standard library lzma has missing support
from .frame import ReplayFrame
@ -14,9 +15,13 @@ from io import BufferedReader
from os.path import isfile
from hashlib import md5 as _md5
import traceback
def md5_str(data):
print(data)
if type(data) is str:
data = data.encode("ascii")
print(_md5(data).hexdigest().encode())
return _md5(data).hexdigest().encode()
def md5_file(file):
@ -31,14 +36,13 @@ def md5_file(file):
hash.update(chunk)
return hash.hexdigest()
def append_and_compress(data):
return lzma_compress(data + b"-12345|0|0|1337,")
def lzma_compress(data):
return encode_uleb(len(data)) + lzma.compress(data + b"-12345|0|0|1337,", format = lzma.FORMAT_ALONE, filters = [
{
"id": lzma.FILTER_LZMA1,
"preset": lzma.PRESET_DEFAULT,
"dict_size": 1 << 21
}
])
comp = pylzma.compress(data, dictionary = 21, fastBytes = 255, eos = False)
comp = comp[:5] + struct.pack(b"<Q", len(data)) + comp[5:] # Append uncompressed length
return struct.pack("<I", len(comp)) + comp # For some odd ass reason this doesnt use ULEB
class Replay:
_mode = Serializable(osuModes.STANDARD, TYPE_BYTE)
@ -61,9 +65,10 @@ class Replay:
_lifebar_graph = Serializable(b"0|1,", TYPE_STRING)
_timestamp = Serializable(0, TYPE_ULLONG)
_online_score_id= Serializable(0, TYPE_ULLONG)
_replay_data = Serializable(b"", TYPE_BYTESTREAM, post = lzma_compress)
_replay_data = Serializable(b"", TYPE_BYTESTREAM, post = append_and_compress)
_online_score_id= Serializable(0, TYPE_ULLONG)
# Marker (Only used as attribute section marker for auto-serializing)
_end_of_attributes = None
@ -109,6 +114,8 @@ class Replay:
self._beatmap_hash.value = md5_file(f)
def set_player_name(self, player_name):
if type(player_name) is str:
player_name = player_name.encode()
self._player_name.value = player_name
def set_score_hash(self, md5_hash):
@ -151,6 +158,9 @@ class Replay:
self._timestamp.value = timestamp
def set_online_score_id(self, online_score_id):
self._online_score_id.value = online_score_id
# --------------------------------------------------------------------------
# Update variables ---------------------------------------------------------
@ -160,8 +170,8 @@ class Replay:
def update_score_hash(self):
self.set_score_hash(
md5_str("%d%s%s%s%d%d" % (
self._combo.value, "osu", self._player_name.value,
md5_str(b"%d%b%b%b%d%b" % (
self._combo.value, b"osu", self._player_name.value,
self._beatmap_hash.value, self._score.value, self.get_rank()
))
)

View File

@ -14,6 +14,6 @@ replay.set_score(score = 29284624,
combo = 358) # Set score info
replay.set_mods(osuMods.HIDDEN | osuMods.DOUBLETIME) # Enable HDDT mods
replay.set_timestamp(1552466941) # Set unix timestamp
replay.set_timestamp(636880715111611126, False)
replay.save("myReplay.osr") # Export replay to file