Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # created using python 3.6
- from struct import pack, unpack, calcsize
- import sys
- SCMAPMAGIC = b'\x4d\x61\x70\x1a'
- DDSMAGIC = b'DDS '
- class MapParsingException(Exception):
- def __init__( self, subject, fileObject ):
- self.fileName = fileObject.name
- self.offset = fileObject.tell()
- self.message = "Couldn't parse {} from \"{}\" before offset {} ".format( subject, self.fileName, self.offset )
- super(Exception, self).__init__( self.message )
- def readcstr(f):
- buf = b''
- while True:
- b = f.read(1)
- if b is None or b == b'\0':
- return buf
- else:
- buf += b
- def readMap( pathToScmap ):
- with open(pathToScmap,'rb') as scmap:
- scmapMagic = scmap.read(4)
- if len(scmapMagic) < 4 or scmapMagic != SCMAPMAGIC:
- raise MapParsingException( "file magic", scmap )
- fileVersionMajor = unpack('I', scmap.read(4) )[0]
- if not fileVersionMajor:
- raise MapParsingException( "file major version", scmap )
- print("fileVersionMajor: {}".format(fileVersionMajor))
- # always 0xbeeffeed and other always 2
- (unknown3,unknown4) = ( scmap.read(4), scmap.read(4) )
- print("unknown3: {}".format(unknown3))
- print("unknown4: {}".format(unknown4))
- (scaledMapWidth,scaledMapHeight) = unpack('ff', scmap.read(calcsize('ff')) )
- if not scaledMapWidth or not scaledMapHeight:
- raise MapParsingException( "scaled map size", scmap )
- print("scaledMapWidth: {}".format(scaledMapWidth))
- print("scaledMapHeight: {}".format(scaledMapHeight))
- # always 0
- (unknown5,unknown6) = ( scmap.read(4), scmap.read(2) )
- print("unknown5: {}".format(unknown5))
- print("unknown6: {}".format(unknown6))
- #######################################################################
- ### Preview Image
- #######################################################################
- previewImageDataLength = unpack('I', scmap.read(4) )[0]
- if not previewImageDataLength:
- raise MapParsingException( "preview image data length", scmap )
- previewImageData = scmap.read(previewImageDataLength)
- if len(previewImageData) != previewImageDataLength:
- raise MapParsingException( "preview image data ({} bytes)".format(previewImageDataLength), scmap )
- print("previewImageDataLength: {} bytes".format(previewImageDataLength))
- print("previewImageDataMagic: {}".format(previewImageData[0:4].decode()))
- #if previewImageData[0:4] == DDSMAGIC:
- #previewDataPath = "{}_preview.dds".format( scmap.name )
- #with open(previewDataPath,'wb') as previewDumpFile:
- #previewDumpFile.write( previewImageData )
- #print("preview image dumped to \"{}\"".format(previewDataPath))
- fileVersionMinor = unpack('I', scmap.read(4) )[0]
- if not fileVersionMinor:
- raise MapParsingException( "file minor version", scmap )
- print("fileVersionMinor: {}".format(fileVersionMinor))
- if fileVersionMinor not in [60, 59, 56, 53]:
- raise MapParsingException( "unsupported file minor version", scmap )
- #######################################################################
- (mapWidth,mapHeight) = unpack('II', scmap.read(8) )
- if not mapWidth or not mapHeight:
- raise MapParsingException( "map size", scmap )
- print("mapWidth: {}".format(mapWidth))
- print("mapHeight: {}".format(mapHeight))
- #######################################################################
- ### Height Map
- #######################################################################
- print("read position: 0x{:08X}".format(scmap.tell()))
- # Height Scale, usually 1/128
- heightScale = unpack('f', scmap.read(4) )[0]
- print("heightScale: {}".format(heightScale))
- heightMapDataLength = ( mapHeight + 1 ) * ( mapWidth + 1 ) * calcsize('h')
- print("heightMapDataLength: {}".format(heightMapDataLength))
- heightMapData = scmap.read(heightMapDataLength)
- #######################################################################
- ### Some Strings
- #######################################################################
- if fileVersionMinor >= 56:
- unknown7 = readcstr(scmap)
- print("unknown7: {}".format(unknown7))
- terrain = readcstr(scmap)
- print("terrain: {}".format(terrain))
- texPathBackground = readcstr(scmap)
- print("texPathBackground: {}".format(texPathBackground))
- texPathSkyCubemap = readcstr(scmap)
- print("texPathSkyCubemap: {}".format(texPathSkyCubemap))
- if fileVersionMinor < 56:
- texPathEnvCubemap = readcstr(scmap)
- print("texPathEnvCubemap: {}".format(texPathEnvCubemap))
- elif fileVersionMinor >= 56:
- environmentLookupTexturesCount = unpack('I', scmap.read(4) )[0]
- print("environmentLookupTexturesCount: {}".format(environmentLookupTexturesCount))
- for i in range(environmentLookupTexturesCount):
- environmentLookupTexturesLabel = readcstr(scmap)
- print("environmentLookupTexturesLabel: {}".format(environmentLookupTexturesLabel))
- environmentLookupTexturesFile = readcstr(scmap)
- print("environmentLookupTexturesFile: {}".format(environmentLookupTexturesFile))
- #######################################################################
- ### Render Settings
- #######################################################################
- lightingMultiplier = unpack('f', scmap.read(4) )[0]
- print("lightingMultiplier: {}".format(lightingMultiplier))
- lightDirection = unpack('fff', scmap.read(12) )
- print("lightDirection: {}".format(lightDirection))
- ambienceLightColor = unpack('fff', scmap.read(12) )
- print("ambienceLightColor: {}".format(ambienceLightColor))
- lightColor = unpack('fff', scmap.read(12) )
- print("lightColor: {}".format(lightColor))
- shadowFillColor = unpack('fff', scmap.read(12) )
- print("shadowFillColor: {}".format(shadowFillColor))
- specularColor = unpack('ffff', scmap.read(16) )
- print("specularColor: {}".format(specularColor))
- bloom = unpack('f', scmap.read(4) )[0]
- print("bloom: {}".format(bloom))
- fogColor = unpack('fff', scmap.read(12) )
- print("fogColor: {}".format(fogColor))
- fogStart = unpack('f', scmap.read(4) )[0]
- print("fogStart: {}".format(fogStart))
- fogEnd = unpack('f', scmap.read(4) )[0]
- print("fogEnd: {}".format(fogEnd))
- hasWater = unpack('c', scmap.read(1) )[0]
- print("hasWater: {}".format(hasWater))
- waterElevation = unpack('f', scmap.read(4) )[0]
- print("waterElevation: {}".format(waterElevation))
- waterElevationDeep = unpack('f', scmap.read(4) )[0]
- print("waterElevationDeep: {}".format(waterElevationDeep))
- waterElevationAbyss = unpack('f', scmap.read(4) )[0]
- print("waterElevationAbyss: {}".format(waterElevationAbyss))
- surfaceColor = unpack('fff', scmap.read(12) )
- print("surfaceColor: {}".format(surfaceColor))
- colorLerpMin = unpack('f', scmap.read(4) )[0]
- print("colorLerpMin: {}".format(colorLerpMin))
- colorLerpMax = unpack('f', scmap.read(4) )[0]
- print("colorLerpMax: {}".format(colorLerpMax))
- refraction = unpack('f', scmap.read(4) )[0]
- print("refraction: {}".format(refraction))
- fresnelBias = unpack('f', scmap.read(4) )[0]
- print("fresnelBias: {}".format(fresnelBias))
- fresnelPower = unpack('f', scmap.read(4) )[0]
- print("fresnelPower: {}".format(fresnelPower))
- reflectionUnit = unpack('f', scmap.read(4) )[0]
- print("reflectionUnit: {}".format(reflectionUnit))
- reflectionSky = unpack('f', scmap.read(4) )[0]
- print("reflectionSky: {}".format(reflectionSky))
- sunShininess = unpack('f', scmap.read(4) )[0]
- print("sunShininess: {}".format(sunShininess))
- sunStrength = unpack('f', scmap.read(4) )[0]
- print("sunStrength: {}".format(sunStrength))
- sunGlow = unpack('f', scmap.read(4) )[0]
- print("sunGlow: {}".format(sunGlow))
- unknown8 = unpack('f', scmap.read(4) )[0]
- print("unknown8: {}".format(unknown8))
- unknown9 = unpack('f', scmap.read(4) )[0]
- print("unknown9: {}".format(unknown9))
- sunColor = unpack('fff', scmap.read(12) )
- print("sunColor: {}".format(sunColor))
- reflectionSun = unpack('f', scmap.read(4) )[0]
- print("reflectionSun: {}".format(reflectionSun))
- print("read position: 0x{:08X}".format(scmap.tell()))
- unknown10 = unpack('f', scmap.read(4) )[0]
- print("unknown10: {}".format(unknown10))
- ### Texture Maps
- texPathWaterCubemap = readcstr(scmap)
- print("texPathWaterCubemap: {}".format(texPathWaterCubemap))
- texPathWaterRamp = readcstr(scmap)
- print("texPathWaterRamp: {}".format(texPathWaterRamp))
- for i in range(4):
- print("waveTexture: {}".format(i))
- normalsFrequency = unpack('f', scmap.read(4) )[0]
- print("normalsFrequency: {}".format(normalsFrequency))
- for i in range(4):
- print("waveTexture: {}".format(i))
- waveTextureScaleX = unpack('f', scmap.read(4) )[0]
- print("waveTextureScaleX: {}".format(waveTextureScaleX))
- waveTextureScaleY = unpack('f', scmap.read(4) )[0]
- print("waveTextureScaleY: {}".format(waveTextureScaleY))
- waveTexturePath = readcstr(scmap)
- print("waveTexturePath: {}".format(waveTexturePath))
- waveGeneratorCount = unpack('I', scmap.read(4) )[0]
- print("waveGeneratorCount: {}".format(waveGeneratorCount))
- for i in range(waveGeneratorCount):
- print("waveGenerator: {}".format(i))
- textureName = readcstr(scmap)
- print("textureName: {}".format(textureName))
- rampName = readcstr(scmap)
- print("rampName: {}".format(rampName))
- position = unpack('fff', scmap.read(12) )
- print("position: {}".format(position))
- rotation = unpack('f', scmap.read(4) )[0]
- print("rotation: {}".format(rotation))
- velocity = unpack('fff', scmap.read(12) )
- print("velocity: {}".format(velocity))
- lifetimeFirst = unpack('f', scmap.read(4) )[0]
- print("lifetimeFirst: {}".format(lifetimeFirst))
- lifetimeSecond = unpack('f', scmap.read(4) )[0]
- print("lifetimeSecond: {}".format(lifetimeSecond))
- periodFirst = unpack('f', scmap.read(4) )[0]
- print("periodFirst: {}".format(periodFirst))
- periodSecond = unpack('f', scmap.read(4) )[0]
- print("periodSecond: {}".format(periodSecond))
- scaleFirst = unpack('f', scmap.read(4) )[0]
- print("scaleFirst: {}".format(scaleFirst))
- scaleSecond = unpack('f', scmap.read(4) )[0]
- print("scaleSecond: {}".format(scaleSecond))
- frameCount = unpack('f', scmap.read(4) )[0]
- print("frameCount: {}".format(frameCount))
- frameRateFirst = unpack('f', scmap.read(4) )[0]
- print("frameRateFirst: {}".format(frameRateFirst))
- frameRateSecond = unpack('f', scmap.read(4) )[0]
- print("frameRateSecond: {}".format(frameRateSecond))
- stripCount = unpack('f', scmap.read(4) )[0]
- print("stripCount: {}".format(stripCount))
- print("read position: 0x{:08X}".format(scmap.tell()))
- if fileVersionMinor >= 59:
- unkownData12 = scmap.read(28)
- print("unkownData12: {}".format(unkownData12.hex()))
- elif fileVersionMinor > 53:
- unkownData12 = scmap.read(24)
- print("unkownData12: {}".format(unkownData12.hex()))
- else:
- noTileset = readcstr(scmap)
- print("noTileset: {}".format(noTileset))
- if fileVersionMinor > 53:
- strata = ['LowerStratum','Stratum1','Stratum2','Stratum3','Stratum4','Stratum5','Stratum6','Stratum7','Stratum8','UpperStratum']
- print("strata: {}".format(strata))
- for stratum in strata:
- print("stratum: {}".format(stratum))
- albedoFile = readcstr(scmap)
- print("albedoFile: {}".format(albedoFile))
- albedoScale = unpack('f', scmap.read(4) )[0]
- print("albedoScale: {}".format(albedoScale))
- print("-"*80)
- for stratum in strata:
- # fucking special cases
- if stratum == 'UpperStratum':
- # no Normal for UpperStratum
- continue
- print("stratum: {}".format(stratum))
- normalFile = readcstr(scmap)
- print("normalFile: {}".format(normalFile))
- normalScale = unpack('f', scmap.read(4) )[0]
- print("normalScale: {}".format(normalScale))
- print("-"*80)
- else:
- strataCount = unpack('I', scmap.read(4) )[0]
- print("strataCount: {}".format(strataCount))
- for stratum in range(strataCount):
- print("stratum: {}".format(stratum))
- albedoFile = readcstr(scmap)
- print("albedoFile: {}".format(albedoFile))
- normalFile = readcstr(scmap)
- print("normalFile: {}".format(normalFile))
- albedoScale = unpack('f', scmap.read(4) )[0]
- print("albedoScale: {}".format(albedoScale))
- normalScale = unpack('f', scmap.read(4) )[0]
- print("normalScale: {}".format(normalScale))
- print("-"*80)
- print("read position: 0x{:08X}".format(scmap.tell()))
- unknown13 = unpack('I', scmap.read(4) )[0]
- print("unknown13: {}".format(unknown13))
- unknown14 = unpack('I', scmap.read(4) )[0]
- print("unknown14: {}".format(unknown14))
- decalsCount = unpack('I', scmap.read(4) )[0]
- print("decalsCount: {}".format(decalsCount))
- for decalIndex in range(decalsCount):
- decalId = unpack('I', scmap.read(4) )[0]
- print("decalId: {}".format(decalId))
- unknown15 = unpack('I', scmap.read(4) )[0]
- print("unknown15: {}".format(unknown15))
- unknown16 = unpack('I', scmap.read(4) )[0]
- print("unknown16: {}".format(unknown16))
- #decalsTextureCount = unpack('I', scmap.read(4) )[0]
- #print("decalsTextureCount: {}".format(decalsTextureCount))
- #for i in range(decalsTextureCount):
- #while True:
- decalsTexturePathLength = unpack('I', scmap.read(4) )[0]
- print("decalsTexturePathLength: {}".format(decalsTexturePathLength))
- #if decalsTexturePathLength == 0:
- #break
- if decalsTexturePathLength > 1024:
- raise MapParsingException( "decalsTexturePathLength", scmap )
- decalsTexturePath = scmap.read(decalsTexturePathLength)
- print("decalsTexturePath: {}".format(decalsTexturePath))
- decalsTexturePathLength = unpack('I', scmap.read(4) )[0]
- print("decalsTexturePathLength: {}".format(decalsTexturePathLength))
- if decalsTexturePathLength > 1024:
- raise MapParsingException( "decalsTexturePathLength", scmap )
- if decalsTexturePathLength > 0:
- decalsTexturePath = scmap.read(decalsTexturePathLength)
- print("decalsTexturePath: {}".format(decalsTexturePath))
- scale = unpack('fff', scmap.read(12) )
- print("scale: {}".format(scale))
- position = unpack('fff', scmap.read(12) )
- print("position: {}".format(position))
- rotation = unpack('fff', scmap.read(12) )
- print("rotation: {}".format(rotation))
- cutOffLOD = unpack('f', scmap.read(4) )[0]
- print("cutOffLOD: {}".format(cutOffLOD))
- ownerArmy = unpack('I', scmap.read(4) )[0]
- print("ownerArmy: {}".format(ownerArmy))
- unknown17 = unpack('I', scmap.read(4) )[0]
- print("unknown17: {}".format(unknown17))
- print("read position: 0x{:08X}".format(scmap.tell()))
- decalGroupsCount = unpack('I', scmap.read(4) )[0]
- print("decalGroupsCount: {}".format(decalGroupsCount))
- for decalGroupIndex in range(decalGroupsCount):
- decalGroupId = unpack('I', scmap.read(4) )[0]
- print("decalGroupId: {}".format(decalGroupId))
- decalGroupName = readcstr(scmap)
- print("decalGroupName: {}".format(decalGroupName))
- decalGroupEntriesCount = unpack('I', scmap.read(4) )[0]
- print("decalGroupEntriesCount: {}".format(decalGroupEntriesCount))
- for i in range(decalGroupEntriesCount):
- decalGroupEntry = unpack('I', scmap.read(4) )[0]
- print("decalGroupEntry: {}".format(decalGroupEntry))
- (unknown19Width,unknown19Height) = unpack('II', scmap.read(8) )
- print("unknown19Width: {}".format(unknown19Width))
- print("unknown19Height: {}".format(unknown19Height))
- # most often 1, sometimes 4
- normalMapsCount = unpack('I', scmap.read(4) )[0]
- print("normalMapsCount: {}".format(normalMapsCount))
- for normalMapIndex in range(normalMapsCount):
- normalMapDataLength = unpack('I', scmap.read(4) )[0]
- print("normalMapDataLength: {}".format(normalMapDataLength))
- normalMapData = scmap.read(normalMapDataLength)
- print("normalMapData: {}...".format(normalMapData[:4]))
- #if normalMapData[0:4] == DDSMAGIC:
- #pnormalMapDataPath = "{}_normalMap{}.dds".format( scmap.name, normalMapIndex )
- #with open(pnormalMapDataPath,'wb') as dumpFile:
- #dumpFile.write( normalMapData )
- #print("normalMapData dumped to \"{}\"".format(pnormalMapDataPath))
- print("read position: 0x{:08X}".format(scmap.tell()))
- if fileVersionMinor < 56:
- unknown20 = unpack('I', scmap.read(4) )[0]
- print("unknown20: {}".format(unknown20))
- textureMapDataLength = unpack('I', scmap.read(4) )[0]
- print("textureMapDataLength: {}".format(textureMapDataLength))
- textureMapData = scmap.read(textureMapDataLength)
- print("textureMapData: {}...".format(textureMapData[:4]))
- print("read position: 0x{:08X}".format(scmap.tell()))
- if fileVersionMinor < 56:
- unknown21 = unpack('I', scmap.read(4) )[0]
- print("unknown21: {}".format(unknown21))
- waterMapDataLength = unpack('I', scmap.read(4) )[0]
- print("waterMapDataLength: {}".format(waterMapDataLength))
- waterMapData = scmap.read(waterMapDataLength)
- print("waterMapData: {}...".format(waterMapData[:4]))
- if fileVersionMinor > 53:
- unknown22 = unpack('I', scmap.read(4) )[0]
- print("unknown22: {}".format(unknown22))
- unknown23MapDataLength = unpack('I', scmap.read(4) )[0]
- print("unknown23MapDataLength: {}".format(unknown23MapDataLength))
- unknown23MapData = scmap.read(unknown23MapDataLength)
- print("unknown23MapData: {}...".format(unknown23MapData[:4]))
- someWaterMapLength = int( (mapWidth / 2) * (mapHeight / 2) )
- waterFoamMapData = scmap.read(someWaterMapLength)
- print("waterFoamMapData: {}...".format(waterFoamMapData[:4]))
- waterFlatnessMapData = scmap.read(someWaterMapLength)
- print("waterFlatnessMapData: {}...".format(waterFlatnessMapData[:4]))
- waterDepthBiasMapData = scmap.read(someWaterMapLength)
- print("waterDepthBiasMapData: {}...".format(waterDepthBiasMapData[:4]))
- print("read position: 0x{:08X}".format(scmap.tell()))
- terrainTypeDataLength = mapWidth * mapHeight
- print("terrainTypeDataLength: {}...".format(terrainTypeDataLength))
- terrainTypeData = scmap.read(terrainTypeDataLength)
- print("terrainTypeData: {}...".format(terrainTypeData[:4]))
- if fileVersionMinor < 53:
- unknown24 = unpack('h', scmap.read(2) )[0]
- print("unknown24: {}".format(unknown24))
- if fileVersionMinor >= 59:
- unknown25 = scmap.read(64)
- print("unknown25: {}".format(unknown25[:4]))
- unknown26String = readcstr(scmap)
- print("unknown26String: {}".format(unknown26String))
- unknown27String = readcstr(scmap)
- print("unknown27String: {}".format(unknown27String))
- unknown28 = unpack('I', scmap.read(4) )[0]
- print("unknown28: {}".format(unknown28))
- unknown28MagicFactor = 40
- if unknown28 > 0:
- unknown29 = scmap.read( unknown28 * unknown28MagicFactor )
- print("unknown29: {}".format(unknown29[:4]))
- unknown30 = scmap.read(19)
- print("unknown30: {}".format(unknown30))
- unknown31String = readcstr(scmap)
- print("unknown31String: {}".format(unknown31String))
- unknown31 = scmap.read(88)
- print("unknown31: {}".format(unknown31[:4]))
- print("read position: 0x{:08X}".format(scmap.tell()))
- propsCount = unpack('I', scmap.read(4) )[0]
- print("propsCount: {}".format(propsCount))
- newPropsList = []
- for propIndex in range( 0, propsCount ):
- print("prop {}".format(propIndex))
- blueprintPath = readcstr(scmap)
- print("blueprintPath: {}".format(blueprintPath))
- position = unpack('fff', scmap.read(12) )
- print("position: {}".format(position))
- rotationX = unpack('fff', scmap.read(12) )
- print("rotationX: {}".format(rotationX))
- rotationY = unpack('fff', scmap.read(12) )
- print("rotationY: {}".format(rotationX))
- rotationZ = unpack('fff', scmap.read(12) )
- print("rotationZ: {}".format(rotationX))
- scale = unpack('fff', scmap.read(12) )
- newPosition = (position[2],position[1],position[0])
- newPropsList += [(blueprintPath,*newPosition,*rotationX,*rotationY,*rotationZ,*scale)]
- print("(unused) scale: {}".format(scale))
- print("-"*80)
- if __name__ == '__main__':
- if len(sys.argv) < 2:
- print("Usage: {} <file>".format(sys.argv[0]))
- sys.exit(1)
- readMap( pathToScmap = sys.argv[1] )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement