Advertisement
Guest User

Untitled

a guest
Oct 19th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.78 KB | None | 0 0
  1. import struct
  2.  
  3. def unpack(f, fmt):
  4. return struct.unpack(fmt, f.read(struct.calcsize(fmt)))
  5.  
  6. def read_fixed_length_null_terminated_string(f, len):
  7. s = unpack(f, '{}s'.format(len))[0]
  8. len = next(i for i, v in enumerate(s) if v == 0)
  9. s = s[:len]
  10. return s.decode()
  11.  
  12. def read_length_prefixed_null_terminated_string(f):
  13. len = f.read(1)[0]
  14. s = f.read(len)[:-1]
  15. print(s)
  16. return s.decode()
  17.  
  18.  
  19. class Vector2(object):
  20. def __init__(self):
  21. self.x = 0
  22. self.y = 0
  23.  
  24. @staticmethod
  25. def from_buffer(f):
  26. vector = Vector2()
  27. vector.x, vector.y = unpack(f, '2f')
  28. return vector
  29.  
  30.  
  31. class Vector3(object):
  32. def __init__(self):
  33. self.x = 0
  34. self.y = 0
  35. self.z = 0
  36.  
  37. @staticmethod
  38. def from_buffer(f):
  39. vector = Vector3()
  40. vector.x, vector.y, vector.z = unpack(f, '3f')
  41. return vector
  42.  
  43.  
  44. class Color(object):
  45. def __init__(self):
  46. self.r = 0
  47. self.g = 0
  48. self.b = 0
  49.  
  50. @staticmethod
  51. def from_buffer(f):
  52. color = Color()
  53. color.r, color.g, color.b = unpack(f, '3B')
  54. return color
  55.  
  56. def __repr__(self):
  57. return ','.join(map(lambda x: str(x), [self.r, self.g, self.b]))
  58.  
  59.  
  60. class VisGroup(object):
  61. def __init__(self):
  62. self.name = ''
  63. self.color = Color()
  64. self.index = 0
  65. self.visible = False
  66.  
  67. def __repr__(self):
  68. return self.name
  69.  
  70. @staticmethod
  71. def from_buffer(f):
  72. visgroup = VisGroup()
  73. visgroup.name = read_fixed_length_null_terminated_string(f, 128)
  74. visgroup.color = Color.from_buffer(f)
  75. visgroup.unk1,\
  76. visgroup.index,\
  77. visgroup.is_visible = unpack(f, 'bib')
  78. return visgroup
  79.  
  80.  
  81. class Face(object):
  82. def __init__(self):
  83. self.texture_name = ''
  84. self.texture_u_axis = Vector3()
  85. self.texture_u_shift = 0.0
  86. self.texture_v_axis = Vector3()
  87. self.texture_v_shift = 0.0
  88. self.texture_rotation = 0.0
  89. self.texture_scale = Vector2()
  90. self.vertices = []
  91. self.plane = []
  92.  
  93. @staticmethod
  94. def from_buffer(f):
  95. face = Face()
  96. face.texture_name = read_fixed_length_null_terminated_string(f, 256)
  97. unpack(f, 'f')
  98. face.texture_u_axis = Vector3.from_buffer(f)
  99. face.texture_u_shift = unpack(f, 'f')
  100. face.texture_v_axis = Vector3.from_buffer(f)
  101. face.texture_u_shift = unpack(f, 'f')
  102. face.texture_rotation = unpack(f, 'f')
  103. face.texture_scale = Vector2.from_buffer(f)
  104. unpack(f, '16b')
  105. vertex_count = unpack(f, 'i')[0]
  106. face.vertices = [Vector3.from_buffer(f) for i in range(vertex_count)]
  107. face.plane = [Vector3.from_buffer(f) for i in range(3)]
  108. return face
  109.  
  110.  
  111. class Solid(object):
  112. def __init__(self):
  113. self.visgroup_index = 0
  114. self.color = Color()
  115. self.faces = []
  116.  
  117. @staticmethod
  118. def from_buffer(f):
  119. solid = Solid()
  120. solid.visgroup_index = unpack(f, 'i')
  121. solid.color = Color.from_buffer(f)
  122. unk1 = unpack(f, 'i')[0]
  123. print(unk1)
  124. face_count = unpack(f, 'i')[0]
  125. solid.faces = [Face.from_buffer(f) for i in range(face_count)]
  126. return solid
  127.  
  128. class World(object):
  129. def __init__(self):
  130. pass
  131.  
  132. @staticmethod
  133. def from_buffer(f):
  134. world = World()
  135. return world
  136.  
  137.  
  138. class Entity(object): # TODO: one of these has to be the rotation
  139. def __init__(self):
  140. self.visgroup_index = 0
  141. self.color = Color()
  142. self.brushes = []
  143. self.classname = ''
  144. self.flags = ''
  145. self.properties = {}
  146. self.location = Vector3()
  147. pass
  148.  
  149. @staticmethod
  150. def from_buffer(f):
  151. entity = Entity()
  152. entity.visgroup_index = unpack(f, 'i')[0]
  153. entity.color = Color.from_buffer(f)
  154. brush_count = unpack(f, 'i')[0]
  155. entity.brushes = [Solid.from_buffer(f) for i in range(brush_count)]
  156. entity.classname = read_length_prefixed_null_terminated_string(f)
  157. unpack(f, '4b')
  158. entity.flags = unpack(f, 'i')
  159. property_count = unpack(f, 'i')[0]
  160. for i in range(property_count):
  161. key = read_length_prefixed_null_terminated_string(f)
  162. value = read_length_prefixed_null_terminated_string(f)
  163. entity.properties[key] = value
  164. unpack(f, '14b')
  165. entity.location = Vector3.from_buffer(f)
  166. unpack(f, '4b')
  167. return entity
  168.  
  169.  
  170. class Group(object):
  171. def __init__(self):
  172. self.visgroup_index = 0
  173. self.color = Color()
  174. self.objects = []
  175.  
  176. @staticmethod
  177. def from_buffer(f):
  178. group = Group()
  179. group.visgroup_index = unpack(f, 'i')
  180. group.color = Color.from_buffer(f)
  181. object_count = unpack(f, 'i')[0]
  182. group.objects = [read_object(f) for i in range(object_count)]
  183. return group
  184.  
  185. _object_type_map_ = {
  186. 'CMapWorld': World,
  187. 'CMapEntity': Entity,
  188. 'CMapGroup': Group,
  189. 'CMapSolid': Solid,
  190. }
  191.  
  192. def read_object(f):
  193. print(f.tell())
  194. object_type_string = read_length_prefixed_null_terminated_string(f)
  195. object_type = _object_type_map_[object_type_string]
  196. return object_type.from_buffer(f)
  197.  
  198.  
  199. fp = r'C:\Users\Colin\Desktop\Leveling\Day of Defeat\dod_kaust\dod_kaust.rmf'
  200. with open(fp, 'rb') as f:
  201. version, magic = unpack(f, 'i3s')
  202. visgroup_count = unpack(f, 'i')[0]
  203. for i in range(visgroup_count):
  204. visgroup = VisGroup.from_buffer(f)
  205. object_type = read_length_prefixed_null_terminated_string(f)
  206. f.read(7)
  207. object_count = unpack(f, 'i')[0]
  208. objects = [read_object(f) for j in range(object_count)]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement