update shit
This commit is contained in:
		@ -1,6 +1,7 @@
 | 
			
		||||
import VTReader
 | 
			
		||||
import VTStruct
 | 
			
		||||
import VTReader, VTStruct, VTConstants
 | 
			
		||||
 | 
			
		||||
ckFile = VTStruct.CKFile()
 | 
			
		||||
VTReader.CKFileReader.Load(ckFile, "D:\\libcmo21\\PyCmo\\Language.nmo", VTConstants.CK_LOAD_FLAGS(VTConstants.CK_LOAD_FLAGS.CK_LOAD_DEFAULT))
 | 
			
		||||
print(ckFile)
 | 
			
		||||
print(str(ckFile.m_FileObjects))
 | 
			
		||||
 | 
			
		||||
with open("D:\\libcmo21\\PyCmo\\Gameplay.nmo", 'rb') as fs:
 | 
			
		||||
    composition = VTReader.ReadCKComposition(fs)
 | 
			
		||||
    print(composition.Header)
 | 
			
		||||
@ -1,50 +1,70 @@
 | 
			
		||||
import enum
 | 
			
		||||
 | 
			
		||||
class CKEnumItem(object):
 | 
			
		||||
    def __init__(self, name: str, value: int):
 | 
			
		||||
        self.name: str = name
 | 
			
		||||
        self.value: int = value
 | 
			
		||||
 | 
			
		||||
class CKEnum(object):
 | 
			
		||||
    def __init__(self, val: int):
 | 
			
		||||
        self.m_Value: int = val
 | 
			
		||||
 | 
			
		||||
        self.__ItemsList = (
 | 
			
		||||
            CKEnumItem(attr, getattr(self, attr)) 
 | 
			
		||||
            for attr in dir(self) if not attr.startswith("__") and not callable(getattr(self, attr))
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def Set(self, data: int):
 | 
			
		||||
        self.m_Value = data
 | 
			
		||||
 | 
			
		||||
    def __iter__(self):
 | 
			
		||||
        return self.__ItemsList
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        for i in self:
 | 
			
		||||
            if i.value == val:
 | 
			
		||||
                return i.name
 | 
			
		||||
            if i.value == self.m_Value:
 | 
			
		||||
                return '<' + i.name + '>'
 | 
			
		||||
 | 
			
		||||
        return "[None]"
 | 
			
		||||
        return "<[None] {:d}>".format(self.m_Value)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.__repr__()
 | 
			
		||||
 | 
			
		||||
class CKFlagEnum(CKEnum):
 | 
			
		||||
    def Contain(self: CKFlagEnum, probe: int):
 | 
			
		||||
        return bool(self.m_Value & probe)
 | 
			
		||||
 | 
			
		||||
    def Add(self: CKFlagEnum, data: int):
 | 
			
		||||
    def Add(self, data: int):
 | 
			
		||||
        self.m_Value = self.m_Value | data
 | 
			
		||||
 | 
			
		||||
    def __contains__(self, probe):
 | 
			
		||||
        if isinstance(probe, int):
 | 
			
		||||
            return bool(self.m_Value & probe)
 | 
			
		||||
        if isinstance(probe, CKFlagEnum):
 | 
			
		||||
            return bool(self.m_Value & probe.m_Value)
 | 
			
		||||
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        pending = []
 | 
			
		||||
 | 
			
		||||
        for i in self:
 | 
			
		||||
            # if it have exactly same entry, return directly
 | 
			
		||||
            if i.value == val:
 | 
			
		||||
            if i.value == self.m_Value:
 | 
			
		||||
                return i.name
 | 
			
		||||
 | 
			
		||||
            # check exist
 | 
			
		||||
            if bool(val & i.value):
 | 
			
		||||
            if bool(self.m_Value & i.value):
 | 
			
		||||
                pending.append(i.name)
 | 
			
		||||
 | 
			
		||||
        result = ', '.join(pending)
 | 
			
		||||
        return result if len(result) != 9 else "[None]"
 | 
			
		||||
        return ('<' + result + '>') if len(result) != 9 else "<[None] {:d}>".format(self.m_Value)
 | 
			
		||||
 | 
			
		||||
class CK_FILE_WRITEMODE(CKFlagEnum, enum.IntEnum):
 | 
			
		||||
class CK_FILE_WRITEMODE(CKFlagEnum):
 | 
			
		||||
    CKFILE_UNCOMPRESSED	       =0	# Save data uncompressed
 | 
			
		||||
    CKFILE_CHUNKCOMPRESSED_OLD =1	# Obsolete
 | 
			
		||||
    CKFILE_EXTERNALTEXTURES_OLD=2	# Obsolete : use CKContext::SetGlobalImagesSaveOptions instead.
 | 
			
		||||
    CKFILE_FORVIEWER           =4	# Don't save Interface Data within the file, the level won't be editable anymore in the interface
 | 
			
		||||
    CKFILE_WHOLECOMPRESSED     =8	# Compress the whole file
 | 
			
		||||
 | 
			
		||||
class CK_LOAD_FLAGS(CKFlagEnum, enum.IntEnum):
 | 
			
		||||
class CK_LOAD_FLAGS(CKFlagEnum):
 | 
			
		||||
    CK_LOAD_ANIMATION					=1<<0	# Load animations
 | 
			
		||||
    CK_LOAD_GEOMETRY					=1<<1	# Load geometry.
 | 
			
		||||
    CK_LOAD_DEFAULT						=CK_LOAD_GEOMETRY|CK_LOAD_ANIMATION	# Load animations & geometry
 | 
			
		||||
@ -56,8 +76,85 @@ class CK_LOAD_FLAGS(CKFlagEnum, enum.IntEnum):
 | 
			
		||||
    CK_LOAD_CHECKDEPENDENCIES			=1<<7 # Check if every plugins needed are availables
 | 
			
		||||
    CK_LOAD_ONLYBEHAVIORS				=1<<8 # 
 | 
			
		||||
 | 
			
		||||
CK_CLASSID = int
 | 
			
		||||
class CKCID(enum.IntEnum):
 | 
			
		||||
class CK_FO_OPTIONS(CKEnum):
 | 
			
		||||
    CK_FO_DEFAULT = 0
 | 
			
		||||
    CK_FO_RENAMEOBJECT = 1
 | 
			
		||||
    CK_FO_REPLACEOBJECT = 2
 | 
			
		||||
    CK_FO_DONTLOADOBJECT = 3
 | 
			
		||||
 | 
			
		||||
CK_ID = int
 | 
			
		||||
 | 
			
		||||
ClassHierarchy = {
 | 
			
		||||
    1: ("CKCID_OBJECT", ),
 | 
			
		||||
    2: ("CKCID_OBJECT", "CKCID_PARAMETERIN", ),
 | 
			
		||||
    4: ("CKCID_OBJECT", "CKCID_PARAMETEROPERATION", ),
 | 
			
		||||
    5: ("CKCID_OBJECT", "CKCID_STATE", ),
 | 
			
		||||
    6: ("CKCID_OBJECT", "CKCID_BEHAVIORLINK", ),
 | 
			
		||||
    8: ("CKCID_OBJECT", "CKCID_BEHAVIOR", ),
 | 
			
		||||
    9: ("CKCID_OBJECT", "CKCID_BEHAVIORIO", ),
 | 
			
		||||
    12: ("CKCID_OBJECT", "CKCID_RENDERCONTEXT", ),
 | 
			
		||||
    13: ("CKCID_OBJECT", "CKCID_KINEMATICCHAIN", ),
 | 
			
		||||
    11: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", ),
 | 
			
		||||
    15: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_OBJECTANIMATION", ),
 | 
			
		||||
    16: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_ANIMATION", ),
 | 
			
		||||
    18: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_ANIMATION", "CKCID_KEYEDANIMATION", ),
 | 
			
		||||
    19: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", ),
 | 
			
		||||
    52: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_DATAARRAY", ),
 | 
			
		||||
    10: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SCENE", ),
 | 
			
		||||
    21: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_LEVEL", ),
 | 
			
		||||
    22: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_PLACE", ),
 | 
			
		||||
    23: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_GROUP", ),
 | 
			
		||||
    24: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SOUND", ),
 | 
			
		||||
    25: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SOUND", "CKCID_WAVESOUND", ),
 | 
			
		||||
    26: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SOUND", "CKCID_MIDISOUND", ),
 | 
			
		||||
    30: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_MATERIAL", ),
 | 
			
		||||
    31: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_TEXTURE", ),
 | 
			
		||||
    32: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_MESH", ),
 | 
			
		||||
    53: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_MESH", "CKCID_PATCHMESH", ),
 | 
			
		||||
    47: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", ),
 | 
			
		||||
    27: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", "CKCID_2DENTITY", ),
 | 
			
		||||
    28: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", "CKCID_2DENTITY", "CKCID_SPRITE", ),
 | 
			
		||||
    29: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", "CKCID_2DENTITY", "CKCID_SPRITETEXT", ),
 | 
			
		||||
    33: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", ),
 | 
			
		||||
    50: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_GRID", ),
 | 
			
		||||
    36: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CURVEPOINT", ),
 | 
			
		||||
    37: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_SPRITE3D", ),
 | 
			
		||||
    43: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CURVE", ),
 | 
			
		||||
    34: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CAMERA", ),
 | 
			
		||||
    35: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CAMERA", "CKCID_TARGETCAMERA", ),
 | 
			
		||||
    38: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_LIGHT", ),
 | 
			
		||||
    39: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_LIGHT", "CKCID_TARGETLIGHT", ),
 | 
			
		||||
    40: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CHARACTER", ),
 | 
			
		||||
    41: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_3DOBJECT", ),
 | 
			
		||||
    42: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_3DOBJECT", "CKCID_BODYPART", ),
 | 
			
		||||
    46: ("CKCID_OBJECT", "CKCID_PARAMETER", ),
 | 
			
		||||
    45: ("CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETERLOCAL", ),
 | 
			
		||||
    55: ("CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETERLOCAL", "CKCID_PARAMETERVARIABLE", ),
 | 
			
		||||
    3: ("CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETEROUT", ),
 | 
			
		||||
    48: ("CKCID_OBJECT", "CKCID_INTERFACEOBJECTMANAGER", ),
 | 
			
		||||
    49: ("CKCID_OBJECT", "CKCID_CRITICALSECTION", ),
 | 
			
		||||
    51: ("CKCID_OBJECT", "CKCID_LAYER", ),
 | 
			
		||||
    54: ("CKCID_OBJECT", "CKCID_PROGRESSIVEMESH", ),
 | 
			
		||||
    20: ("CKCID_OBJECT", "CKCID_SYNCHRO", ),
 | 
			
		||||
    80: ("CKCID_OBJECTARRAY", ),
 | 
			
		||||
    81: ("CKCID_SCENEOBJECTDESC", ),
 | 
			
		||||
    82: ("CKCID_ATTRIBUTEMANAGER", ),
 | 
			
		||||
    83: ("CKCID_MESSAGEMANAGER", ),
 | 
			
		||||
    84: ("CKCID_COLLISIONMANAGER", ),
 | 
			
		||||
    85: ("CKCID_OBJECTMANAGER", ),
 | 
			
		||||
    86: ("CKCID_FLOORMANAGER", ),
 | 
			
		||||
    87: ("CKCID_RENDERMANAGER", ),
 | 
			
		||||
    88: ("CKCID_BEHAVIORMANAGER", ),
 | 
			
		||||
    89: ("CKCID_INPUTMANAGER", ),
 | 
			
		||||
    90: ("CKCID_PARAMETERMANAGER", ),
 | 
			
		||||
    91: ("CKCID_GRIDMANAGER", ),
 | 
			
		||||
    92: ("CKCID_SOUNDMANAGER", ),
 | 
			
		||||
    93: ("CKCID_TIMEMANAGER", ),
 | 
			
		||||
    -1: ("CKCID_CUIKBEHDATA", ),
 | 
			
		||||
    56: ("CKCID_MAXCLASSID", ),
 | 
			
		||||
    128: ("CKCID_MAXMAXCLASSID", ),
 | 
			
		||||
}
 | 
			
		||||
class CK_CLASSID(CKEnum):
 | 
			
		||||
    CKCID_OBJECT = 1
 | 
			
		||||
    CKCID_PARAMETERIN = 2
 | 
			
		||||
    CKCID_PARAMETEROPERATION = 4
 | 
			
		||||
@ -129,91 +226,74 @@ class CKCID(enum.IntEnum):
 | 
			
		||||
    CKCID_MAXCLASSID = 56
 | 
			
		||||
    CKCID_MAXMAXCLASSID = 128
 | 
			
		||||
 | 
			
		||||
    __ClassHierarchy = {
 | 
			
		||||
        1: ("CKCID_OBJECT", ),
 | 
			
		||||
        2: ("CKCID_OBJECT", "CKCID_PARAMETERIN", ),
 | 
			
		||||
        4: ("CKCID_OBJECT", "CKCID_PARAMETEROPERATION", ),
 | 
			
		||||
        5: ("CKCID_OBJECT", "CKCID_STATE", ),
 | 
			
		||||
        6: ("CKCID_OBJECT", "CKCID_BEHAVIORLINK", ),
 | 
			
		||||
        8: ("CKCID_OBJECT", "CKCID_BEHAVIOR", ),
 | 
			
		||||
        9: ("CKCID_OBJECT", "CKCID_BEHAVIORIO", ),
 | 
			
		||||
        12: ("CKCID_OBJECT", "CKCID_RENDERCONTEXT", ),
 | 
			
		||||
        13: ("CKCID_OBJECT", "CKCID_KINEMATICCHAIN", ),
 | 
			
		||||
        11: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", ),
 | 
			
		||||
        15: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_OBJECTANIMATION", ),
 | 
			
		||||
        16: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_ANIMATION", ),
 | 
			
		||||
        18: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_ANIMATION", "CKCID_KEYEDANIMATION", ),
 | 
			
		||||
        19: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", ),
 | 
			
		||||
        52: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_DATAARRAY", ),
 | 
			
		||||
        10: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SCENE", ),
 | 
			
		||||
        21: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_LEVEL", ),
 | 
			
		||||
        22: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_PLACE", ),
 | 
			
		||||
        23: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_GROUP", ),
 | 
			
		||||
        24: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SOUND", ),
 | 
			
		||||
        25: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SOUND", "CKCID_WAVESOUND", ),
 | 
			
		||||
        26: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_SOUND", "CKCID_MIDISOUND", ),
 | 
			
		||||
        30: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_MATERIAL", ),
 | 
			
		||||
        31: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_TEXTURE", ),
 | 
			
		||||
        32: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_MESH", ),
 | 
			
		||||
        53: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_MESH", "CKCID_PATCHMESH", ),
 | 
			
		||||
        47: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", ),
 | 
			
		||||
        27: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", "CKCID_2DENTITY", ),
 | 
			
		||||
        28: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", "CKCID_2DENTITY", "CKCID_SPRITE", ),
 | 
			
		||||
        29: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_RENDEROBJECT", "CKCID_2DENTITY", "CKCID_SPRITETEXT", ),
 | 
			
		||||
        33: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", ),
 | 
			
		||||
        50: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_GRID", ),
 | 
			
		||||
        36: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CURVEPOINT", ),
 | 
			
		||||
        37: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_SPRITE3D", ),
 | 
			
		||||
        43: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CURVE", ),
 | 
			
		||||
        34: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CAMERA", ),
 | 
			
		||||
        35: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CAMERA", "CKCID_TARGETCAMERA", ),
 | 
			
		||||
        38: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_LIGHT", ),
 | 
			
		||||
        39: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_LIGHT", "CKCID_TARGETLIGHT", ),
 | 
			
		||||
        40: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_CHARACTER", ),
 | 
			
		||||
        41: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_3DOBJECT", ),
 | 
			
		||||
        42: ("CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_3DOBJECT", "CKCID_BODYPART", ),
 | 
			
		||||
        46: ("CKCID_OBJECT", "CKCID_PARAMETER", ),
 | 
			
		||||
        45: ("CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETERLOCAL", ),
 | 
			
		||||
        55: ("CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETERLOCAL", "CKCID_PARAMETERVARIABLE", ),
 | 
			
		||||
        3: ("CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETEROUT", ),
 | 
			
		||||
        48: ("CKCID_OBJECT", "CKCID_INTERFACEOBJECTMANAGER", ),
 | 
			
		||||
        49: ("CKCID_OBJECT", "CKCID_CRITICALSECTION", ),
 | 
			
		||||
        51: ("CKCID_OBJECT", "CKCID_LAYER", ),
 | 
			
		||||
        54: ("CKCID_OBJECT", "CKCID_PROGRESSIVEMESH", ),
 | 
			
		||||
        20: ("CKCID_OBJECT", "CKCID_SYNCHRO", ),
 | 
			
		||||
        80: ("CKCID_OBJECTARRAY", ),
 | 
			
		||||
        81: ("CKCID_SCENEOBJECTDESC", ),
 | 
			
		||||
        82: ("CKCID_ATTRIBUTEMANAGER", ),
 | 
			
		||||
        83: ("CKCID_MESSAGEMANAGER", ),
 | 
			
		||||
        84: ("CKCID_COLLISIONMANAGER", ),
 | 
			
		||||
        85: ("CKCID_OBJECTMANAGER", ),
 | 
			
		||||
        86: ("CKCID_FLOORMANAGER", ),
 | 
			
		||||
        87: ("CKCID_RENDERMANAGER", ),
 | 
			
		||||
        88: ("CKCID_BEHAVIORMANAGER", ),
 | 
			
		||||
        89: ("CKCID_INPUTMANAGER", ),
 | 
			
		||||
        90: ("CKCID_PARAMETERMANAGER", ),
 | 
			
		||||
        91: ("CKCID_GRIDMANAGER", ),
 | 
			
		||||
        92: ("CKCID_SOUNDMANAGER", ),
 | 
			
		||||
        93: ("CKCID_TIMEMANAGER", ),
 | 
			
		||||
        -1: ("CKCID_CUIKBEHDATA", ),
 | 
			
		||||
        56: ("CKCID_MAXCLASSID", ),
 | 
			
		||||
        128: ("CKCID_MAXMAXCLASSID", ),
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def __init__(self, code: CK_CLASSID):
 | 
			
		||||
        self.code: CK_CLASSID = code
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        hierarchy = self.__ClassHierarchy.get(self.code, None)
 | 
			
		||||
        hierarchy = ClassHierarchy.get(self.m_Value, None)
 | 
			
		||||
        if hierarchy is None:
 | 
			
		||||
            return "[Undefined]"
 | 
			
		||||
            return "[Undefined] {:d}".format(self.m_Value)
 | 
			
		||||
        return "{} ({})".format(
 | 
			
		||||
            hierarchy[-1],
 | 
			
		||||
            ' -> '.join(hierarchy)
 | 
			
		||||
        )
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        hierarchy = ClassHierarchy.get(self.m_Value, None)
 | 
			
		||||
        if hierarchy is None:
 | 
			
		||||
            return "[Undefined] {:d}".format(self.m_Value)
 | 
			
		||||
        return hierarchy[-1]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CKERROR = int
 | 
			
		||||
class CKERR():
 | 
			
		||||
ErrorDescription = {
 | 
			
		||||
    0: "Operation successful",
 | 
			
		||||
    -1: "One of the parameter passed to the function was invalid",
 | 
			
		||||
    -2: "One of the parameter passed to the function was invalid",
 | 
			
		||||
    -3: "The parameter size was invalid",
 | 
			
		||||
    -4: "The operation type didn't exist",
 | 
			
		||||
    -5: "The function used to execute the operation is not yet implemented",
 | 
			
		||||
    -6: "There was not enough memory to perform the action",
 | 
			
		||||
    -7: "The function  is not yet implemented",
 | 
			
		||||
    -11: "There was an attempt to remove something not present",
 | 
			
		||||
    -13: "There is no level currently created",
 | 
			
		||||
    -14: "There is no level currently created",
 | 
			
		||||
    -16: "The notification message was not used",
 | 
			
		||||
    -17: "Attempt to add an item that was already present",
 | 
			
		||||
    -18: "the render context is not valid",
 | 
			
		||||
    -19: "the render context is not activated for rendering",
 | 
			
		||||
    -20: "there was no plugins to load this kind of file",
 | 
			
		||||
    -21: "there was no plugins to save this kind of file",
 | 
			
		||||
    -22: "attempt to load an invalid file",
 | 
			
		||||
    -23: "attempt to load with an invalid plugin",
 | 
			
		||||
    -24: "attempt use an object that wasnt initialized",
 | 
			
		||||
    -25: "attempt use a message type that wasn't registred",
 | 
			
		||||
    -29: "No dll file found in the parse directory",
 | 
			
		||||
    -30: "this dll has already been registred",
 | 
			
		||||
    -31: "this dll does not contain information to create the prototype",
 | 
			
		||||
    -34: "Invalid Object (attempt to Get an object from an invalid ID)",
 | 
			
		||||
    -35: "Invalid window was provided as console window",
 | 
			
		||||
    -36: "Invalid kinematic chain ( end and start effector may not be part of the same hierarchy )",
 | 
			
		||||
    -37: "Keyboard not attached or not working properly",
 | 
			
		||||
    -38: "Mouse not attached or not working properly",
 | 
			
		||||
    -39: "Joystick not attached or not working properly",
 | 
			
		||||
    -40: "Try to link imcompatible Parameters",
 | 
			
		||||
    -44: "There is no render engine dll",
 | 
			
		||||
    -45: "There is no current level (use CKSetCurrentLevel )",
 | 
			
		||||
    -46: "Sound Management has been disabled",
 | 
			
		||||
    -47: "DirectInput Management has been disabled",
 | 
			
		||||
    -48: "Guid is already in use or invalid",
 | 
			
		||||
    -49: "There was no more free space on disk when trying to save a file",
 | 
			
		||||
    -50: "Impossible to write to file (write-protection ?)",
 | 
			
		||||
    -51: "The behavior cannnot be added to this entity",
 | 
			
		||||
    -52: "The behavior cannnot be added to this entity",
 | 
			
		||||
    -53: "A manager was registered more than once",
 | 
			
		||||
    -54: "CKprocess or TimeManager process while CK is paused will fail",
 | 
			
		||||
    -55: "Some plugins were missing whileloading a file",
 | 
			
		||||
    -56: "Virtools version too old to load this file",
 | 
			
		||||
    -57: "CRC Error while loading file",
 | 
			
		||||
    -58: "A Render context is already in Fullscreen Mode",
 | 
			
		||||
    -59: "Operation was cancelled by user",
 | 
			
		||||
    -121: "there were no animation key at the given index",
 | 
			
		||||
    -122: "attemp to acces an animation key with an invalid index",
 | 
			
		||||
    -123: "the animation is invalid (no entity associated or zero length)",
 | 
			
		||||
}
 | 
			
		||||
class CKERROR(CKEnum):
 | 
			
		||||
    CKERR_OK =  0
 | 
			
		||||
    CKERR_INVALIDPARAMETER = -1
 | 
			
		||||
    CKERR_INVALIDPARAMETERTYPE = -2
 | 
			
		||||
@ -265,61 +345,6 @@ class CKERR():
 | 
			
		||||
    CKERR_INVALIDINDEX = -122
 | 
			
		||||
    CKERR_INVALIDANIMATION = -123
 | 
			
		||||
 | 
			
		||||
    __ErrorDescription = {
 | 
			
		||||
        0: "Operation successful",
 | 
			
		||||
        -1: "One of the parameter passed to the function was invalid",
 | 
			
		||||
        -2: "One of the parameter passed to the function was invalid",
 | 
			
		||||
        -3: "The parameter size was invalid",
 | 
			
		||||
        -4: "The operation type didn't exist",
 | 
			
		||||
        -5: "The function used to execute the operation is not yet implemented",
 | 
			
		||||
        -6: "There was not enough memory to perform the action",
 | 
			
		||||
        -7: "The function  is not yet implemented",
 | 
			
		||||
        -11: "There was an attempt to remove something not present",
 | 
			
		||||
        -13: "There is no level currently created",
 | 
			
		||||
        -14: "There is no level currently created",
 | 
			
		||||
        -16: "The notification message was not used",
 | 
			
		||||
        -17: "Attempt to add an item that was already present",
 | 
			
		||||
        -18: "the render context is not valid",
 | 
			
		||||
        -19: "the render context is not activated for rendering",
 | 
			
		||||
        -20: "there was no plugins to load this kind of file",
 | 
			
		||||
        -21: "there was no plugins to save this kind of file",
 | 
			
		||||
        -22: "attempt to load an invalid file",
 | 
			
		||||
        -23: "attempt to load with an invalid plugin",
 | 
			
		||||
        -24: "attempt use an object that wasnt initialized",
 | 
			
		||||
        -25: "attempt use a message type that wasn't registred",
 | 
			
		||||
        -29: "No dll file found in the parse directory",
 | 
			
		||||
        -30: "this dll has already been registred",
 | 
			
		||||
        -31: "this dll does not contain information to create the prototype",
 | 
			
		||||
        -34: "Invalid Object (attempt to Get an object from an invalid ID)",
 | 
			
		||||
        -35: "Invalid window was provided as console window",
 | 
			
		||||
        -36: "Invalid kinematic chain ( end and start effector may not be part of the same hierarchy )",
 | 
			
		||||
        -37: "Keyboard not attached or not working properly",
 | 
			
		||||
        -38: "Mouse not attached or not working properly",
 | 
			
		||||
        -39: "Joystick not attached or not working properly",
 | 
			
		||||
        -40: "Try to link imcompatible Parameters",
 | 
			
		||||
        -44: "There is no render engine dll",
 | 
			
		||||
        -45: "There is no current level (use CKSetCurrentLevel )",
 | 
			
		||||
        -46: "Sound Management has been disabled",
 | 
			
		||||
        -47: "DirectInput Management has been disabled",
 | 
			
		||||
        -48: "Guid is already in use or invalid",
 | 
			
		||||
        -49: "There was no more free space on disk when trying to save a file",
 | 
			
		||||
        -50: "Impossible to write to file (write-protection ?)",
 | 
			
		||||
        -51: "The behavior cannnot be added to this entity",
 | 
			
		||||
        -52: "The behavior cannnot be added to this entity",
 | 
			
		||||
        -53: "A manager was registered more than once",
 | 
			
		||||
        -54: "CKprocess or TimeManager process while CK is paused will fail",
 | 
			
		||||
        -55: "Some plugins were missing whileloading a file",
 | 
			
		||||
        -56: "Virtools version too old to load this file",
 | 
			
		||||
        -57: "CRC Error while loading file",
 | 
			
		||||
        -58: "A Render context is already in Fullscreen Mode",
 | 
			
		||||
        -59: "Operation was cancelled by user",
 | 
			
		||||
        -121: "there were no animation key at the given index",
 | 
			
		||||
        -122: "attemp to acces an animation key with an invalid index",
 | 
			
		||||
        -123: "the animation is invalid (no entity associated or zero length)",
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def __init__(self, code: CKERROR):
 | 
			
		||||
        self.code: CKERROR = code
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return self.__ErrorDescription.get(self.code, "[Undefined]")
 | 
			
		||||
        return ErrorDescription.get(self.m_Value, "[Undefined] {:d}".format(self.m_Value))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,50 +3,52 @@ import PyCmoMisc
 | 
			
		||||
import struct, io, datetime, zlib
 | 
			
		||||
import typing
 | 
			
		||||
 | 
			
		||||
g_HeaderPacker = struct.Struct('<' + 'i' * 8)
 | 
			
		||||
g_Header1Packer = struct.Struct('<iiIiiiii')
 | 
			
		||||
g_Header2Packer = struct.Struct('<iiiiiiii')
 | 
			
		||||
g_FileObjectPacker = struct.Struct('<iiii')
 | 
			
		||||
 | 
			
		||||
class CKFileReader():
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def ReadFileHeaders(self: VTStruct.CKFile) -> VTConstants.CKERROR:
 | 
			
		||||
        if self.m_Parser is None:
 | 
			
		||||
            return VTConstants.CKERR.CKERR_INVALIDPARAMETER
 | 
			
		||||
        header = VTStruct.CKFileHeader()
 | 
			
		||||
            return VTConstants.CKERROR(VTConstants.CKERROR.CKERR_INVALIDPARAMETER)
 | 
			
		||||
        parser = self.m_Parser
 | 
			
		||||
 | 
			
		||||
        # check magic words
 | 
			
		||||
        magic_words = self.m_Parser.GetReader()[0:4]
 | 
			
		||||
        # ========== magic words ==========
 | 
			
		||||
        magic_words = parser.GetReader()[0:4]
 | 
			
		||||
        if magic_words != b'Nemo':
 | 
			
		||||
            return VTConstants.CKERR.CKERR_INVALIDFILE
 | 
			
		||||
            return VTConstants.CKERROR(VTConstants.CKERROR.CKERR_INVALIDFILE)
 | 
			
		||||
        
 | 
			
		||||
        # read header1
 | 
			
		||||
        if self.m_Parser.GetSize() < 0x20:
 | 
			
		||||
            return VTConstants.CKERR.CKERR_INVALIDFILE
 | 
			
		||||
        header1 = g_HeaderPacker.unpack(self.m_Parser.GetReader().read(8 * 4))
 | 
			
		||||
        # ========== read header1 ==========
 | 
			
		||||
        if parser.GetSize() < 0x20:
 | 
			
		||||
            return VTConstants.CKERROR(VTConstants.CKERROR.CKERR_INVALIDFILE)
 | 
			
		||||
        header1 = list(g_Header1Packer.unpack(parser.GetReader().read(8 * 4)))
 | 
			
		||||
 | 
			
		||||
        # check header1
 | 
			
		||||
        if header1[5]:  # i don't know what is this fields stands for
 | 
			
		||||
            header1 = tuple(0 for _ in range(8))
 | 
			
		||||
            header1 = list(0 for _ in range(8))
 | 
			
		||||
 | 
			
		||||
        # virtools is too old to open this file. file is too new.
 | 
			
		||||
        if header1[4] > 9:  # file version
 | 
			
		||||
            return VTConstants.CKERR.CKERR_OBSOLETEVIRTOOLS
 | 
			
		||||
            return VTConstants.CKERROR(VTConstants.CKERROR.CKERR_OBSOLETEVIRTOOLS)
 | 
			
		||||
 | 
			
		||||
        # read header2
 | 
			
		||||
        # ========== read header2 ==========
 | 
			
		||||
        # file ver < 5 do not have second header
 | 
			
		||||
        if header1[4] < 5:
 | 
			
		||||
            header2 = tuple(0 for _ in range(8))
 | 
			
		||||
            header2 = list(0 for _ in range(8))
 | 
			
		||||
        else:
 | 
			
		||||
            if self.m_Parser.GetSize() < 0x40:
 | 
			
		||||
                return VTConstants.CKERR.CKERR_INVALIDFILE
 | 
			
		||||
            if parser.GetSize() < 0x40:
 | 
			
		||||
                return VTConstants.CKERROR(VTConstants.CKERROR.CKERR_INVALIDFILE)
 | 
			
		||||
 | 
			
		||||
            header2 = g_HeaderPacker.unpack(self.m_Parser.GetReader().read(8 * 4))
 | 
			
		||||
            header2 = g_Header2Packer.unpack(parser.GetReader().read(8 * 4))
 | 
			
		||||
 | 
			
		||||
        # forcely reset too big product ver
 | 
			
		||||
        if header2[5] >= 12:    # product version
 | 
			
		||||
            header2[5] = 0
 | 
			
		||||
            header2[6] = 0x1010000   # product build
 | 
			
		||||
 | 
			
		||||
        # assign value
 | 
			
		||||
        # ========== assign value ==========
 | 
			
		||||
        self.m_FileInfo.ProductVersion = header2[5]
 | 
			
		||||
        self.m_FileInfo.ProductBuild = header2[6]
 | 
			
		||||
        self.m_FileInfo.FileWriteMode.m_Value = header1[6]
 | 
			
		||||
@ -62,31 +64,78 @@ class CKFileReader():
 | 
			
		||||
        self.m_FileInfo.DataUnPackSize = header2[1]
 | 
			
		||||
        self.m_FileInfo.Crc = header1[2]
 | 
			
		||||
 | 
			
		||||
        # ========== crc and body unpacker ==========
 | 
			
		||||
        # file version greater than 8 have crc feature and compression feature
 | 
			
		||||
        if self.m_FileInfo.FileVersion >= 8:
 | 
			
		||||
            # reset crc field of header
 | 
			
		||||
            header1[2] = 0
 | 
			
		||||
 | 
			
		||||
        # process date independently
 | 
			
		||||
        # date is in BCD code
 | 
			
		||||
        day = PyCmoMisc.BcdCodeToDecCode((raw_date >> 24) & 0xff)
 | 
			
		||||
        month = PyCmoMisc.BcdCodeToDecCode((raw_date >> 16) & 0xff - 1)
 | 
			
		||||
        month = (month % 12) + 1
 | 
			
		||||
        year = PyCmoMisc.BcdCodeToDecCode(raw_date & 0xffff)
 | 
			
		||||
        header.Timestamp = datetime.date(year, month, day)
 | 
			
		||||
            # compute crc
 | 
			
		||||
            gotten_crc = zlib.adler32(g_Header1Packer.pack(*header1), 0)
 | 
			
		||||
 | 
			
		||||
        if header.FileVersion >= 8:
 | 
			
		||||
            # check crc
 | 
			
		||||
            gotten_crc = zlib.adler32(b'Nemo Fi\0', 0)
 | 
			
		||||
            gotten_crc = zlib.adler32(struct.pack("<6I", 0, raw_date, header.FileVersion, header.FileVersion2, header.SaveFlags, header.PrewHdrPackSize), gotten_crc)   # reset crc as zero
 | 
			
		||||
            gotten_crc = zlib.adler32(struct.pack("<8I", header.DataPackSize, header.DataUnpackSize, header.ManagerCount, header.ObjectCount, header.MaxIDSaved, header.ProductVersion, header.ProductBuild, header.PrewHdrUnpackSize), gotten_crc)
 | 
			
		||||
            gotten_crc = zlib.adler32(fs.read(header.PrewHdrPackSize), gotten_crc)
 | 
			
		||||
            gotten_crc = zlib.adler32(fs.read(header.DataPackSize), gotten_crc)
 | 
			
		||||
            if gotten_crc != header.Crc:
 | 
			
		||||
                raise Exception("Crc Error")
 | 
			
		||||
            reader = parser.GetReader()
 | 
			
		||||
            pos_cache = reader.tell()
 | 
			
		||||
            reader.seek(8 * 4, io.SEEK_SET)
 | 
			
		||||
            gotten_crc = zlib.adler32(reader.read(
 | 
			
		||||
                8 * 4 + self.m_FileInfo.Hdr1PackSize + self.m_FileInfo.DataPackSize
 | 
			
		||||
            ), gotten_crc)
 | 
			
		||||
            reader.seek(pos_cache, io.SEEK_SET)
 | 
			
		||||
 | 
			
		||||
            # compare crc
 | 
			
		||||
            if gotten_crc != self.m_FileInfo.Crc:
 | 
			
		||||
                return VTConstants.CKERROR(VTConstants.CKERROR.CKERR_FILECRCERROR)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            # compare size to decide wheher use compress feature
 | 
			
		||||
            if self.m_FileInfo.Hdr1UnPackSize != self.m_FileInfo.Hdr1PackSize:
 | 
			
		||||
                # create a new parser for following analyze
 | 
			
		||||
                parser = VTUtils.SmallZlibFileReader(parser, self.m_FileInfo.Hdr1PackSize, self.m_FileInfo.Hdr1UnPackSize)
 | 
			
		||||
 | 
			
		||||
        # ========== object list read ==========
 | 
			
		||||
        # file ver >= 7 have this features
 | 
			
		||||
        if self.m_FileInfo.FileVersion >= 7:
 | 
			
		||||
            self.m_SaveIDMax = self.m_FileInfo.MaxIDSaved
 | 
			
		||||
            # resize
 | 
			
		||||
            self.m_FileObjects = list(VTStruct.CKFileObject() for _ in range(self.m_FileInfo.ObjectCount))
 | 
			
		||||
 | 
			
		||||
            # read data
 | 
			
		||||
            reader = parser.GetReader()
 | 
			
		||||
            for fileobj in self.m_FileObjects:
 | 
			
		||||
                # set useless fields
 | 
			
		||||
                fileobj.ObjPtr = None
 | 
			
		||||
                fileobj.Name = None
 | 
			
		||||
                fileobj.Data = None
 | 
			
		||||
 | 
			
		||||
                # read basic fields
 | 
			
		||||
                (fileobj.Object, cid, fileobj.FileIndex, namelen) = g_FileObjectPacker.unpack(
 | 
			
		||||
                    reader.read(g_FileObjectPacker.size)
 | 
			
		||||
                )
 | 
			
		||||
                fileobj.ObjectCid.Set(cid)
 | 
			
		||||
 | 
			
		||||
                # read name
 | 
			
		||||
                if namelen > 0:
 | 
			
		||||
                    fileobj.Name = reader.read(namelen).decode('utf-8', errors = 'ignore')
 | 
			
		||||
                    
 | 
			
		||||
        # ========== dep list read ==========
 | 
			
		||||
        # only file ver >= 8, this sector is existed
 | 
			
		||||
        if self.m_FileInfo.FileVersion >= 8:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        return header
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def ReadCKComposition(fs: io.BufferedReader):
 | 
			
		||||
        composition = VTStruct.CKComposition()
 | 
			
		||||
    def Load(self: VTStruct.CKFile, filename: str, load_flags: VTConstants.CK_LOAD_FLAGS) -> VTConstants.CKERROR:
 | 
			
		||||
        # todo: clear first
 | 
			
		||||
 | 
			
		||||
        composition.Header = ReadCKFileHeader(fs)
 | 
			
		||||
        return composition
 | 
			
		||||
        # setup basic fields
 | 
			
		||||
        self.m_FileName = filename
 | 
			
		||||
        self.m_Flags = load_flags
 | 
			
		||||
        
 | 
			
		||||
        # setup parser
 | 
			
		||||
        self.m_Parser = VTUtils.RawFileReader(filename)
 | 
			
		||||
 | 
			
		||||
        # read header first
 | 
			
		||||
        err = CKFileReader.ReadFileHeaders(self)
 | 
			
		||||
 | 
			
		||||
        # todo: finish other read
 | 
			
		||||
 | 
			
		||||
        return err
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,24 @@ import VTConstants, VTUtils
 | 
			
		||||
import PyCmoMisc
 | 
			
		||||
import datetime
 | 
			
		||||
 | 
			
		||||
class CKGUID():
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.D1: int = 0
 | 
			
		||||
        self.D2: int = 0
 | 
			
		||||
    def __init__(self, d1: int, d2: int):
 | 
			
		||||
        self.D1: int = d1
 | 
			
		||||
        self.D2: int = d2
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f"<CKGUID: 0x{self.D1:08X}, 0x{self.D2:08X}"
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.__repr__()
 | 
			
		||||
 | 
			
		||||
class CKFileInfo:
 | 
			
		||||
    def __init__(self: CKFileInfo):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.ProductVersion: int = 0
 | 
			
		||||
        self.ProductBuild: int = 0
 | 
			
		||||
 | 
			
		||||
        self.FileWriteMode: VTConstants.CK_FILE_WRITEMODE = 0
 | 
			
		||||
        self.FileWriteMode: VTConstants.CK_FILE_WRITEMODE = VTConstants.CK_FILE_WRITEMODE(0)
 | 
			
		||||
        
 | 
			
		||||
        self.FileVersion: int = 0
 | 
			
		||||
        self.CKVersion: int = 0
 | 
			
		||||
@ -22,9 +34,9 @@ class CKFileInfo:
 | 
			
		||||
        self.Hdr1PackSize: int = 0
 | 
			
		||||
        self.Hdr1UnPackSize: int = 0
 | 
			
		||||
        self.DataPackSize: int = 0
 | 
			
		||||
        self.DataUnpackSize: int = 0
 | 
			
		||||
        self.DataUnPackSize: int = 0
 | 
			
		||||
 | 
			
		||||
    def GetProductBuildTuple(self: CKFileInfo) -> tuple[int]:
 | 
			
		||||
    def GetProductBuildTuple(self) -> tuple[int]:
 | 
			
		||||
        return (
 | 
			
		||||
            (self.ProductBuild >> 24) & 0xff, 
 | 
			
		||||
            (self.ProductBuild >> 16) & 0xff, 
 | 
			
		||||
@ -32,29 +44,73 @@ class CKFileInfo:
 | 
			
		||||
            self.ProductBuild & 0xff
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def __repr__(self: CKFileInfo) -> str:
 | 
			
		||||
        return f"""Version (File / CK): {self.FileVersion:08X} / {self.CKVersion:08X}
 | 
			
		||||
Product (Version / Build): {self.ProductVersion:d} / {'.0'.join(self.GetProductBuildTuple())}
 | 
			
		||||
Save Flags: {self.SaveFlags}
 | 
			
		||||
File Size: {PyCmoMisc.OutputSizeHumanReadable(self.FileSize)}
 | 
			
		||||
Crc: 0x{self.Crc:08X}
 | 
			
		||||
    def __repr__(self) -> str:
 | 
			
		||||
        return f"""<CKFile: 
 | 
			
		||||
    Version (File / CK): {self.FileVersion:d} / 0x{self.CKVersion:08X}
 | 
			
		||||
    Product (Version / Build): {self.ProductVersion:d} / {'.0'.join(map(lambda x: str(x), self.GetProductBuildTuple()))}
 | 
			
		||||
    Save Flags: {self.FileWriteMode}
 | 
			
		||||
    File Size: {PyCmoMisc.OutputSizeHumanReadable(self.FileSize)}
 | 
			
		||||
    Crc: 0x{self.Crc:08X}
 | 
			
		||||
 | 
			
		||||
Preview Header (Pack / Unpack): {PyCmoMisc.OutputSizeHumanReadable(self.PrewHdrPackSize)} / {PyCmoMisc.OutputSizeHumanReadable(self.PrewHdrUnpackSize)}
 | 
			
		||||
Data (Pack / Unpack): {PyCmoMisc.OutputSizeHumanReadable(self.DataPackSize)} / {PyCmoMisc.OutputSizeHumanReadable(self.DataUnpackSize)}
 | 
			
		||||
    Hdr1 (Pack / Unpack): {PyCmoMisc.OutputSizeHumanReadable(self.Hdr1PackSize)} / {PyCmoMisc.OutputSizeHumanReadable(self.Hdr1UnPackSize)}
 | 
			
		||||
    Data (Pack / Unpack): {PyCmoMisc.OutputSizeHumanReadable(self.DataPackSize)} / {PyCmoMisc.OutputSizeHumanReadable(self.DataUnPackSize)}
 | 
			
		||||
 | 
			
		||||
Manager Count: {self.ManagerCount:d}
 | 
			
		||||
Object Count: {self.ObjectCount:d}
 | 
			
		||||
Max ID Saved: {self.MaxIDSaved:d}
 | 
			
		||||
"""
 | 
			
		||||
    Manager Count: {self.ManagerCount:d}
 | 
			
		||||
    Object Count: {self.ObjectCount:d}
 | 
			
		||||
    Max ID Saved: {self.MaxIDSaved:d}
 | 
			
		||||
>"""
 | 
			
		||||
    def __str__(self) -> str:
 | 
			
		||||
        return self.__repr__()
 | 
			
		||||
 | 
			
		||||
class CKFileObject():
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.Object: VTConstants.CK_ID = 0
 | 
			
		||||
        self.CreatedObject: VTConstants.CK_ID = 0
 | 
			
		||||
        self.ObjectCid: VTConstants.CK_CLASSID = VTConstants.CK_CLASSID(VTConstants.CK_CLASSID.CKCID_OBJECT)
 | 
			
		||||
        self.ObjPtr = None
 | 
			
		||||
        self.Name: str = None
 | 
			
		||||
        self.Data = None
 | 
			
		||||
        self.PostPackSize: int = 0
 | 
			
		||||
        self.PrePackSize: int = 0
 | 
			
		||||
        self.Options: VTConstants.CK_FO_OPTIONS = VTConstants.CK_FO_OPTIONS(VTConstants.CK_FO_OPTIONS.CK_FO_DEFAULT)
 | 
			
		||||
        self.FileIndex: int = 0
 | 
			
		||||
        self.SaveFlags: VTConstants.CK_FILE_WRITEMODE = VTConstants.CK_FILE_WRITEMODE(0)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self) -> str:
 | 
			
		||||
        return f'<{self.Name if self.Name else "[Anonymous]"}: {self.ObjectCid}>'
 | 
			
		||||
    def __str__(self) -> str:
 | 
			
		||||
        return self.__repr__()
 | 
			
		||||
 | 
			
		||||
class CKFilePluginDependencies():
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.m_PluginCategory: int = 0
 | 
			
		||||
        self.m_Guids: list[CKGUID] = []
 | 
			
		||||
        self.ValidGuids: list[bool] = []
 | 
			
		||||
        
 | 
			
		||||
    def __repr__(self) -> str:
 | 
			
		||||
        return repr(self.m_Guids)
 | 
			
		||||
    def __str__(self) -> str:
 | 
			
		||||
        return self.__repr__()
 | 
			
		||||
 | 
			
		||||
class CKFile(object):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.m_FileName: str = ''
 | 
			
		||||
        self.m_SaveIDMax: int = 0
 | 
			
		||||
        self.m_FileObjects: list[CKFileObject] = []
 | 
			
		||||
        self.m_ManagersData = []
 | 
			
		||||
        self.m_PluginDep: list[CKFilePluginDependencies] = []
 | 
			
		||||
        self.m_IndexByClassId: list[list[int]] = []
 | 
			
		||||
        self.m_IncludedFiles: list[str] = []
 | 
			
		||||
 | 
			
		||||
        self.m_FileInfo: CKFileInfo = CKFileInfo()
 | 
			
		||||
 | 
			
		||||
        self.m_Flags: VTConstants.CK_LOAD_FLAGS = VTConstants.CK_LOAD_FLAGS(VTConstants.CK_LOAD_FLAGS.CK_LOAD_DEFAULT)
 | 
			
		||||
        self.m_FileName: str = ''
 | 
			
		||||
        self.m_Parser: VTUtils.UniversalFileReader = None
 | 
			
		||||
 | 
			
		||||
    def __repr__(self: CKFile) -> str:
 | 
			
		||||
        return self.m_FileInfo
 | 
			
		||||
        self.m_ReadFileDataDone: bool = False
 | 
			
		||||
 | 
			
		||||
    def __repr__(self) -> str:
 | 
			
		||||
        return repr(self.m_FileInfo)
 | 
			
		||||
    def __str__(self) -> str:
 | 
			
		||||
        return self.__repr__()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ class RawFileReader():
 | 
			
		||||
    def __init__(self, filename: str):
 | 
			
		||||
        self.__size: int = os.path.getsize(filename)
 | 
			
		||||
        self.__fs = open(filename, 'rb')
 | 
			
		||||
        self.__mm: mmap.mmap = mmap.mmap(self.__fs.fileno, 0, access = mmap.ACCESS_READ)
 | 
			
		||||
        self.__mm: mmap.mmap = mmap.mmap(self.__fs.fileno(), 0, access = mmap.ACCESS_READ)
 | 
			
		||||
    
 | 
			
		||||
    def __del__(self):
 | 
			
		||||
        self.__mm.close()
 | 
			
		||||
@ -49,7 +49,10 @@ class LargeZlibFileReader():
 | 
			
		||||
        return self.__mm
 | 
			
		||||
 | 
			
		||||
class SmallZlibFileReader():
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
    def __init__(self, raw_reader: RawFileReader, comp_size: int, uncomp_size: int):
 | 
			
		||||
        # set size
 | 
			
		||||
        self.__size: int = uncomp_size
 | 
			
		||||
 | 
			
		||||
        # create io
 | 
			
		||||
        self.__ss: io.BytesIO = io.BytesIO()
 | 
			
		||||
 | 
			
		||||
@ -61,13 +64,16 @@ class SmallZlibFileReader():
 | 
			
		||||
        while buf:
 | 
			
		||||
            self.__ss.write(parser.decompress(buf))
 | 
			
		||||
            buf = reader.read(io.DEFAULT_BUFFER_SIZE)
 | 
			
		||||
        self._ss.write(parser.flush())
 | 
			
		||||
        self.__ss.write(parser.flush())
 | 
			
		||||
 | 
			
		||||
        # reset cursor
 | 
			
		||||
        self.__ss.seek(0, io.SEEK_SET)
 | 
			
		||||
 | 
			
		||||
    def __del__(self):
 | 
			
		||||
        del self.__ss
 | 
			
		||||
 | 
			
		||||
    def GetSize(self) -> int:
 | 
			
		||||
        return len(self.__ss.getvalue())
 | 
			
		||||
        return self.__size
 | 
			
		||||
 | 
			
		||||
    def GetReader(self) -> io.BytesIO:
 | 
			
		||||
        return self.__ss
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user