almost working, getting some off by one byte errors
This commit is contained in:
@@ -5,8 +5,9 @@ from io import BytesIO
|
|||||||
|
|
||||||
def ReadCSharp_str(data: BytesIO) -> str:
|
def ReadCSharp_str(data: BytesIO) -> str:
|
||||||
charamount = read7bitEncoded_int(data)
|
charamount = read7bitEncoded_int(data)
|
||||||
print(charamount)
|
string: str = data.read(charamount).decode('utf-8', errors="replace")
|
||||||
return data.read(charamount).decode('utf-8', errors="replace")
|
print("read string: "+string)
|
||||||
|
return string
|
||||||
|
|
||||||
def WriteCSharp_str(data: BytesIO, string: str) -> str:
|
def WriteCSharp_str(data: BytesIO, string: str) -> str:
|
||||||
write7bitEncoded_int(len(string))
|
write7bitEncoded_int(len(string))
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
from os import replace
|
||||||
|
from types import FrameType
|
||||||
|
|
||||||
import lz4.block
|
import lz4.block
|
||||||
from . import resonite_types
|
from . import resonite_types
|
||||||
from . import common
|
from . import common
|
||||||
|
|
||||||
import ctypes
|
|
||||||
import typing
|
import typing
|
||||||
import struct
|
import struct
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
@@ -17,8 +18,8 @@ KeyframeInterpolation: dict[str, int] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class KeyFrame():
|
class KeyFrame():
|
||||||
time: resonite_types.float = 0
|
time: resonite_types.float = resonite_types.float(0)
|
||||||
interpolation: resonite_types.int = 0
|
interpolation: resonite_types.int = resonite_types.int(0)
|
||||||
value: resonite_types.ResoType
|
value: resonite_types.ResoType
|
||||||
left_tan: resonite_types.ResoType
|
left_tan: resonite_types.ResoType
|
||||||
right_tan: resonite_types.ResoType
|
right_tan: resonite_types.ResoType
|
||||||
@@ -27,14 +28,12 @@ class KeyFrame():
|
|||||||
def __getattr__(self, name: str):
|
def __getattr__(self, name: str):
|
||||||
if name == "interpolation":
|
if name == "interpolation":
|
||||||
interp: int = 0
|
interp: int = 0
|
||||||
if (self.__dict__["left_tan"] != None and self.__dict__["right_tan"] != None):
|
if (self["left_tan"] != None and self["right_tan"] != None):
|
||||||
interp = 3
|
interp = 3
|
||||||
|
|
||||||
|
|
||||||
return resonite_types.int(interp)
|
return resonite_types.int(interp)
|
||||||
return self.__dict__[name]
|
return super().__getattribute__(name)
|
||||||
def __setattr__(self, name, value):
|
|
||||||
self.__dict__[name] = value
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -49,8 +48,8 @@ class KeyFrame():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
class ResoTrack(resonite_types.ResoType):
|
class ResoTrack(resonite_types.ResoType):
|
||||||
_node: resonite_types.string
|
node: resonite_types.string = resonite_types.string("")
|
||||||
_property: resonite_types.string
|
property: resonite_types.string = resonite_types.string("")
|
||||||
Owner: AnimX
|
Owner: AnimX
|
||||||
FrameType: type[resonite_types.ResoType]
|
FrameType: type[resonite_types.ResoType]
|
||||||
keyframes: list[KeyFrame] = []
|
keyframes: list[KeyFrame] = []
|
||||||
@@ -59,16 +58,18 @@ class ResoTrack(resonite_types.ResoType):
|
|||||||
self.FrameType = FrameType
|
self.FrameType = FrameType
|
||||||
|
|
||||||
def write(self, data: BytesIO):
|
def write(self, data: BytesIO):
|
||||||
self._node.write(data)
|
self.node.write(data)
|
||||||
self._property.write(data)
|
self.property.write(data)
|
||||||
common.write7bitEncoded_ulong(data, len(self.keyframes))
|
common.write7bitEncoded_ulong(data, len(self.keyframes))
|
||||||
|
|
||||||
def read(self, data:BytesIO):
|
def read(self, data:BytesIO):
|
||||||
self._node.read(data)
|
self.node.read(data)
|
||||||
self._property.read(data)
|
self.property.read(data)
|
||||||
track_amount: int = int(common.read7bitEncoded_ulong(data))
|
track_amount: int = int(common.read7bitEncoded_ulong(data))
|
||||||
for i in range(0, track_amount):
|
for i in range(0, track_amount):
|
||||||
self.keyframes.append(KeyFrame())
|
key: KeyFrame = KeyFrame()
|
||||||
|
key.value = self.FrameType()
|
||||||
|
self.keyframes.append(key)
|
||||||
|
|
||||||
def removeKeyframe(self, time: float | int) -> bool:
|
def removeKeyframe(self, time: float | int) -> bool:
|
||||||
"""Takes a time and removes one with the same time"""
|
"""Takes a time and removes one with the same time"""
|
||||||
@@ -142,12 +143,12 @@ class ResoTrack(resonite_types.ResoType):
|
|||||||
|
|
||||||
|
|
||||||
class RawTrack(ResoTrack):
|
class RawTrack(ResoTrack):
|
||||||
interval: resonite_types.float = 0
|
interval: resonite_types.float = resonite_types.float(0)
|
||||||
|
|
||||||
def __getattr__(self, name: str):
|
def __getattr__(self, name: str):
|
||||||
if name == "interval":
|
if name == "interval":
|
||||||
return self.Owner.interval.x
|
return self.Owner.interval.x
|
||||||
return self.__dict__[name]
|
return super().__getattribute__(name)
|
||||||
|
|
||||||
def __init__(self, FrameType):
|
def __init__(self, FrameType):
|
||||||
super().__init__(FrameType)
|
super().__init__(FrameType)
|
||||||
@@ -204,7 +205,7 @@ class DiscreteTrack(ResoTrack):
|
|||||||
class CurveTrack(ResoTrack):
|
class CurveTrack(ResoTrack):
|
||||||
interpolations: bool = False
|
interpolations: bool = False
|
||||||
tangents: bool = False
|
tangents: bool = False
|
||||||
sharedinterpolation: resonite_types.int = -1
|
sharedinterpolation: resonite_types.int = resonite_types.int(-1)
|
||||||
|
|
||||||
def __getattr__(self, name: str):
|
def __getattr__(self, name: str):
|
||||||
if name == "interpolations":
|
if name == "interpolations":
|
||||||
@@ -215,7 +216,7 @@ class CurveTrack(ResoTrack):
|
|||||||
for key in self.keyframes:
|
for key in self.keyframes:
|
||||||
if key.interpolation.x == 3 or key.interpolation.x == 4:
|
if key.interpolation.x == 3 or key.interpolation.x == 4:
|
||||||
return True
|
return True
|
||||||
return self.__dict__[name]
|
return super().__getattribute__(name)
|
||||||
|
|
||||||
def __init__(self, FrameType):
|
def __init__(self, FrameType):
|
||||||
super().__init__(FrameType)
|
super().__init__(FrameType)
|
||||||
@@ -232,6 +233,8 @@ class CurveTrack(ResoTrack):
|
|||||||
self.sharedinterpolation.write(data)
|
self.sharedinterpolation.write(data)
|
||||||
|
|
||||||
for key in self.keyframes:
|
for key in self.keyframes:
|
||||||
|
if key.value == None:
|
||||||
|
key.value = self.FrameType()
|
||||||
key.value.write(data)
|
key.value.write(data)
|
||||||
key.time.write(data)
|
key.time.write(data)
|
||||||
|
|
||||||
@@ -242,9 +245,12 @@ class CurveTrack(ResoTrack):
|
|||||||
|
|
||||||
def read(self, data:BytesIO):
|
def read(self, data:BytesIO):
|
||||||
super().read(data)
|
super().read(data)
|
||||||
flags: int = struct.unpack("<B",data.read(1))
|
flags: int = struct.unpack("<B",data.read(1))[0]
|
||||||
self.interpolations = flags & 1
|
self.interpolations = (flags & 1) > 0
|
||||||
self.tangents = flags & 2
|
self.tangents = (flags & 2) > 0
|
||||||
|
|
||||||
|
print(str(self.interpolations))
|
||||||
|
print(str(self.tangents))
|
||||||
|
|
||||||
if(self.interpolations):
|
if(self.interpolations):
|
||||||
for key in self.keyframes:
|
for key in self.keyframes:
|
||||||
@@ -253,11 +259,18 @@ class CurveTrack(ResoTrack):
|
|||||||
self.sharedinterpolation.read(data)
|
self.sharedinterpolation.read(data)
|
||||||
|
|
||||||
for key in self.keyframes:
|
for key in self.keyframes:
|
||||||
|
print("key read!")
|
||||||
|
if key.value == None:
|
||||||
|
key.value = self.FrameType()
|
||||||
key.value.read(data)
|
key.value.read(data)
|
||||||
key.time.read(data)
|
key.time.read(data)
|
||||||
|
|
||||||
if(self.tangents):
|
if(self.tangents):
|
||||||
for key in self.keyframes:
|
for key in self.keyframes:
|
||||||
|
if key.left_tan == None:
|
||||||
|
key.left_tan = self.FrameType()
|
||||||
|
if key.right_tan == None:
|
||||||
|
key.right_tan = self.FrameType()
|
||||||
key.left_tan.read(data)
|
key.left_tan.read(data)
|
||||||
key.right_tan.read(data)
|
key.right_tan.read(data)
|
||||||
|
|
||||||
@@ -300,7 +313,7 @@ class BezierTrack(ResoTrack):
|
|||||||
"""PLACE HOLDER METHOD, DO NOT USE"""
|
"""PLACE HOLDER METHOD, DO NOT USE"""
|
||||||
raise Exception("BezierTrack track type is unsupported in resonite's code")
|
raise Exception("BezierTrack track type is unsupported in resonite's code")
|
||||||
#This is weird, but thank you python - @989onan
|
#This is weird, but thank you python - @989onan
|
||||||
TrackTypes: list[type[ResoTrack]] = [
|
TrackTypes: list[type] = [
|
||||||
RawTrack,
|
RawTrack,
|
||||||
DiscreteTrack,
|
DiscreteTrack,
|
||||||
CurveTrack,
|
CurveTrack,
|
||||||
@@ -354,7 +367,7 @@ elementTypes: list[type[resonite_types.ResoType]] = [
|
|||||||
|
|
||||||
|
|
||||||
most_recent_AnimX_vers: int = 1
|
most_recent_AnimX_vers: int = 1
|
||||||
|
import lzma#HALLLOOOYAH HALLOYAH!! - @989onan
|
||||||
class AnimX():
|
class AnimX():
|
||||||
|
|
||||||
|
|
||||||
@@ -375,7 +388,25 @@ class AnimX():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decompress_lzma(cls,data, format, filters) -> list:
|
||||||
|
results = []
|
||||||
|
while True:
|
||||||
|
decomp = lzma.LZMADecompressor(format, None, filters)
|
||||||
|
try:
|
||||||
|
res = decomp.decompress(data)
|
||||||
|
except lzma.LZMAError:
|
||||||
|
if results:
|
||||||
|
break # Leftover data is not a valid LZMA/XZ stream; ignore it.
|
||||||
|
else:
|
||||||
|
raise # Error on the first iteration; bail out.
|
||||||
|
results.append(res)
|
||||||
|
data = decomp.unused_data
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
if not decomp.eof:
|
||||||
|
raise lzma.LZMAError("Compressed data ended before the end-of-stream marker was reached")
|
||||||
|
return b"".join(results)
|
||||||
|
|
||||||
def read(self, file: str) -> bool:
|
def read(self, file: str) -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -393,10 +424,11 @@ class AnimX():
|
|||||||
|
|
||||||
self.track_amount.x = common.read7bitEncoded_ulong(data)
|
self.track_amount.x = common.read7bitEncoded_ulong(data)
|
||||||
self.global_duration.read(data)
|
self.global_duration.read(data)
|
||||||
print(self.track_amount.x)
|
print("track amont: "+str(self.track_amount.x))
|
||||||
|
print("file vers: "+str(self.file_version.x))
|
||||||
|
|
||||||
self.name.read(data)
|
self.name.read(data)
|
||||||
|
print("name: "+self.name.x)
|
||||||
|
|
||||||
match (struct.unpack('<B', data.read(1))[0]):
|
match (struct.unpack('<B', data.read(1))[0]):
|
||||||
case 0:
|
case 0:
|
||||||
@@ -405,9 +437,25 @@ class AnimX():
|
|||||||
from lz4.frame import decompress #why do you have to be a wheel? - @989onan
|
from lz4.frame import decompress #why do you have to be a wheel? - @989onan
|
||||||
data = BytesIO(decompress(data.read()))
|
data = BytesIO(decompress(data.read()))
|
||||||
case 2:
|
case 2:
|
||||||
import lzma#HALLLOOOYAH HALLOYAH!! - @989onan
|
|
||||||
filters = [{"id": "", "preset": lzma.PRESET_DEFAULT}]
|
filters = [
|
||||||
data = BytesIO(lzma.decompress(data.read(), filters=filters))
|
{"id" : lzma.FILTER_LZMA1, #idfk man - @989onan
|
||||||
|
"dict_size" : 2097152,
|
||||||
|
"lc" : 3,
|
||||||
|
"lp" : 0,
|
||||||
|
"pb" : 2, # private static int posStateBits = 2; //<-froox engine derived.
|
||||||
|
"mode" : lzma.MODE_NORMAL,
|
||||||
|
"nice_len" : 32, # private static int numFastBytes = 32; //<-froox engine derived.
|
||||||
|
"mf" : lzma.MF_BT4,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
data.read(5) #fuck off headers - @989onan
|
||||||
|
data.read(8) #fuck off stream headers - @989onan
|
||||||
|
data.read(8) #fuck off stream headers - @989onan
|
||||||
|
filelmza: bytes = bytes(AnimX.decompress_lzma(data.read(), lzma.FORMAT_RAW, filters))
|
||||||
|
|
||||||
|
print(f"decompressed bytes: {filelmza[:100]}")
|
||||||
|
data = BytesIO(filelmza)
|
||||||
case _:
|
case _:
|
||||||
raise Exception("Invalid encoding")
|
raise Exception("Invalid encoding")
|
||||||
|
|
||||||
@@ -415,7 +463,7 @@ class AnimX():
|
|||||||
trackType2: int = 0
|
trackType2: int = 0
|
||||||
num4: int = 0
|
num4: int = 0
|
||||||
if (self.file_version == 0):
|
if (self.file_version == 0):
|
||||||
b: ctypes.c_ubyte = ctypes.c_ubyte(struct.unpack('<B', data.read(1))[0])
|
b: int = int(struct.unpack('<B', data.read(1))[0])
|
||||||
num3: int = int(b & 1)
|
num3: int = int(b & 1)
|
||||||
trackType: int = 0
|
trackType: int = 0
|
||||||
if (num3 != 0):
|
if (num3 != 0):
|
||||||
@@ -429,9 +477,12 @@ class AnimX():
|
|||||||
else:
|
else:
|
||||||
trackType2 = int(struct.unpack('<B', data.read(1))[0])
|
trackType2 = int(struct.unpack('<B', data.read(1))[0])
|
||||||
num4 = int(struct.unpack('<B', data.read(1))[0])
|
num4 = int(struct.unpack('<B', data.read(1))[0])
|
||||||
animationTrack: ResoTrack = AnimX.GetTrackType(trackType2, elementTypes[num4], data)
|
try:
|
||||||
|
animationTrack = AnimX.GetTrackType(trackType2, elementTypes[num4], data)
|
||||||
animationTrack.Owner = self
|
animationTrack.Owner = self
|
||||||
self.tracks.append(animationTrack)
|
self.tracks.append(animationTrack)
|
||||||
|
except:
|
||||||
|
raise Exception("[InvalidDataException]: element type exception, beyond range: "+str(num4))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -457,16 +508,17 @@ class AnimX():
|
|||||||
|
|
||||||
for i in range(0,self.track_amount.x):
|
for i in range(0,self.track_amount.x):
|
||||||
|
|
||||||
data.write(struct.pack('<B', TrackTypes.index(type(self.tracks[i])))[0])
|
data.write(struct.pack('<B', TrackTypes.index(type(self.tracks[i]))))
|
||||||
data.write(struct.pack('<B', elementTypes.index(self.tracks[i].FrameType)))
|
data.write(struct.pack('<B', elementTypes.index(self.tracks[i].FrameType)))
|
||||||
self.tracks[i].write(data)
|
self.tracks[i].write(data)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def GetTrackType(cls, trackType2: int, value_type: int, data: BytesIO) -> ResoTrack:
|
def GetTrackType(cls, trackType2: int, value_type: type[resonite_types.ResoType], data: BytesIO) -> ResoTrack:
|
||||||
TrackType: type[ResoTrack] = TrackTypes[trackType2]
|
Track = TrackTypes[trackType2](value_type)
|
||||||
Track: ResoTrack = TrackType[elementTypes[value_type]](elementTypes[value_type])
|
print(type(Track))
|
||||||
|
print(value_type)
|
||||||
Track.read(data)
|
Track.read(data)
|
||||||
return Track
|
return Track
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import ctypes
|
|
||||||
import typing
|
import typing
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import struct
|
import struct
|
||||||
@@ -152,12 +151,12 @@ class bool2(bool):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def read(self,data: BytesIO):
|
def read(self,data: BytesIO):
|
||||||
byte: ctypes.c_ubyte = ctypes.c_ubyte(struct.unpack("<B",data.read(1))[0])
|
byte: int = int(struct.unpack("<B",data.read(1))[0])
|
||||||
self.x = (byte & 1) > 0
|
self.x = (byte & 1) > 0
|
||||||
self.y = (byte & 2) > 0
|
self.y = (byte & 2) > 0
|
||||||
|
|
||||||
def createflags(self) -> ctypes.c_byte:
|
def createflags(self) -> int:
|
||||||
flags: ctypes.c_ubyte = ctypes.c_ubyte(0)
|
flags: int = int(0)
|
||||||
flags |= (1 if self.x else 0)
|
flags |= (1 if self.x else 0)
|
||||||
flags |= (2 if self.y else 0)
|
flags |= (2 if self.y else 0)
|
||||||
return flags
|
return flags
|
||||||
@@ -173,13 +172,13 @@ class bool3(bool2):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def read(self,data):
|
def read(self,data):
|
||||||
byte: ctypes.c_ubyte = ctypes.c_ubyte(struct.unpack("<B",data.read(1))[0])
|
byte: int = int(struct.unpack("<B",data.read(1))[0])
|
||||||
self.x = (byte & 1) > 0
|
self.x = (byte & 1) > 0
|
||||||
self.y = (byte & 2) > 0
|
self.y = (byte & 2) > 0
|
||||||
self.z = (byte & 4) > 0
|
self.z = (byte & 4) > 0
|
||||||
|
|
||||||
def createflags(self) -> ctypes.c_byte:
|
def createflags(self) -> int:
|
||||||
flags: ctypes.c_ubyte = ctypes.c_ubyte(0)
|
flags: int = int(0)
|
||||||
flags |= (1 if self.x else 0)
|
flags |= (1 if self.x else 0)
|
||||||
flags |= (2 if self.y else 0)
|
flags |= (2 if self.y else 0)
|
||||||
flags |= (3 if self.z else 0)
|
flags |= (3 if self.z else 0)
|
||||||
@@ -196,14 +195,14 @@ class bool4(bool3):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def read(self,data: BytesIO):
|
def read(self,data: BytesIO):
|
||||||
byte: ctypes.c_ubyte = ctypes.c_ubyte(struct.unpack("<B",data.read(1))[0])
|
byte: int = int(struct.unpack("<B",data.read(1))[0])
|
||||||
self.x = (byte & 1) > 0
|
self.x = (byte & 1) > 0
|
||||||
self.y = (byte & 2) > 0
|
self.y = (byte & 2) > 0
|
||||||
self.z = (byte & 4) > 0
|
self.z = (byte & 4) > 0
|
||||||
self.w = (byte & 8) > 0
|
self.w = (byte & 8) > 0
|
||||||
|
|
||||||
def createflags(self) -> ctypes.c_ubyte:
|
def createflags(self) -> int:
|
||||||
flags: ctypes.c_ubyte = ctypes.c_ubyte(0)
|
flags: int = int(0)
|
||||||
flags |= (1 if self.x else 0)
|
flags |= (1 if self.x else 0)
|
||||||
flags |= (2 if self.y else 0)
|
flags |= (2 if self.y else 0)
|
||||||
flags |= (4 if self.z else 0)
|
flags |= (4 if self.z else 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user