Advertisement
Ramaraunt1

Untitled

Jan 16th, 2017
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.45 KB | None | 0 0
  1. WRECK_VERSION = '1.0.0'
  2.  
  3. import sys
  4. if (sys.version_info[0] != 2) or (sys.version_info[1] < 6):
  5. exit("\nYou're running Python version {0}.{1}.{2}.\nW.R.E.C.K. requires Python version 2.6.x or 2.7.x to run!\n".format(*sys.version_info[0:3]))
  6. sys.dont_write_bytecode = True
  7.  
  8. from time import time as gettime
  9. from os import makedirs
  10.  
  11. from traceback import extract_tb
  12.  
  13. # Color support
  14. if 'bw' in sys.argv:
  15. COLORAMA = ('', '', '', '', '', '', '', '')
  16. else:
  17. try:
  18. import colorama
  19. colorama.init()
  20. COLORAMA = ('\x1b[0m', '\x1b[31m', '\x1b[32m', '\x1b[33m', '\x1b[34m', '\x1b[35m', '\x1b[36m', '\x1b[37m')
  21. except:
  22. COLORAMA = ('', '', '', '', '', '', '', '')
  23.  
  24. from compiler import *
  25.  
  26.  
  27.  
  28. write_id_files = "ID_%s.py" # Where the compiler will write new iteration ID-files.
  29. show_performance_data = False # Set to true to display compiler performance data by default.
  30. export_filename = '%s.txt' # How to name export files (only used for some debugging purposes).
  31.  
  32. WRECK.time_started = gettime()
  33.  
  34.  
  35. print
  36. print '{2}*** Warband Refined & Enhanced Compiler Kit (W.R.E.C.K.) version {version!s} ***{0}'.format(*COLORAMA, version = WRECK_VERSION)
  37. print 'Please report errors, problems and suggestions at {5}http://lav.lomskih.net/wreck/{0}'.format(*COLORAMA)
  38. print
  39.  
  40. try:
  41.  
  42. # +-----------------------------------------------------------------------------------------------
  43. # /
  44. # +
  45. # |
  46.  
  47. print 'Loading module...',
  48.  
  49. try:
  50.  
  51. # Info module and plugins
  52. WRECK.current_module = 'info'
  53. from module_info import *
  54. WRECK.destination = export_dir.rstrip('/')
  55. globals().update(WRECK.syntax_extensions)
  56. globals().update(WRECK.plugin_globals)
  57.  
  58. # Optional modules
  59. WRECK.current_module = 'item_modifiers'
  60. try:
  61. from module_item_modifiers import *
  62. except ImportError:
  63. #from defaults.module_item_modifiers import *
  64. item_modifiers = DEFAULT_ITEM_MODIFIERS
  65. WRECK.generate_item_modifiers = False
  66. generate_imod_constants_for_backwards_compatibility(item_modifiers)
  67. WRECK.current_module = 'ui_strings'
  68. try:
  69. from module_ui_strings import *
  70. except ImportError:
  71. ui_strings = []
  72. WRECK.generate_ui_strings = False
  73. WRECK.current_module = 'user_hints'
  74. try:
  75. from module_user_hints import *
  76. except ImportError:
  77. user_hints = []
  78. WRECK.generate_user_hints = False
  79.  
  80. # Required modules
  81. WRECK.current_module = 'skills'
  82. from module_skills import *
  83. generate_skill_constants_for_backwards_compatibility(skills)
  84. WRECK.current_module = 'animations'
  85. from module_animations import *
  86. WRECK.current_module = 'factions'
  87. from module_factions import *
  88. WRECK.current_module = 'game_menus'
  89. from module_game_menus import *
  90. WRECK.current_module = 'info_pages'
  91. from module_info_pages import *
  92. WRECK.current_module = 'meshes'
  93. from module_meshes import *
  94. WRECK.current_module = 'mission_templates'
  95. from module_mission_templates import *
  96. WRECK.current_module = 'tracks'
  97. from module_music import *
  98. WRECK.current_module = 'particle_systems'
  99. from module_particle_systems import *
  100. WRECK.current_module = 'postfx_params'
  101. from module_postfx import *
  102. WRECK.current_module = 'quests'
  103. from module_quests import *
  104. WRECK.current_module = 'scene_props'
  105. from module_scene_props import *
  106. WRECK.current_module = 'scenes'
  107. from module_scenes import *
  108. WRECK.current_module = 'scripts'
  109. from module_scripts import *
  110. WRECK.current_module = 'simple_triggers'
  111. from module_simple_triggers import *
  112. WRECK.current_module = 'sounds'
  113. from module_sounds import *
  114. WRECK.current_module = 'strings'
  115. from module_strings import *
  116. WRECK.current_module = 'tableaus'
  117. from module_tableau_materials import *
  118. WRECK.current_module = 'triggers'
  119. from module_triggers import *
  120. WRECK.current_module = 'items'
  121. from module_items import *
  122. WRECK.current_module = 'map_icons'
  123. from module_map_icons import *
  124. WRECK.current_module = 'skins'
  125. from module_skins import *
  126. WRECK.current_module = 'presentations'
  127. from module_presentations import *
  128. WRECK.current_module = 'troops'
  129. from module_troops import *
  130. WRECK.current_module = 'party_templates'
  131. from module_party_templates import *
  132. WRECK.current_module = 'parties'
  133. from module_parties import *
  134. WRECK.current_module = 'dialogs'
  135. from module_dialogs import *
  136. WRECK.current_module = None
  137.  
  138. except Exception, e:
  139. print '{1}FAILED.\nMODULE `{module!s}` ERROR:\n{error!s}{0}'.format(*COLORAMA, module = WRECK.current_module, error = (e.formatted() if isinstance(e, MSException) else formatted_exception()))
  140. if isinstance(e, TypeError) and (('object is not callable' in e.message) or ('indices must be integers' in e.message)):
  141. exc_type, exc_value, exc_traceback = sys.exc_info()
  142. error_info = extract_tb(exc_traceback)[-1]
  143. print '{6} Compiler hint: this error is typically caused by a missing comma.\n Please check that tuples are followed by commas in `{path!s}` above line {line}:\n\n {5}{code!s}{0}'.format(*COLORAMA, path = path_split(error_info[0])[1], line = error_info[1], code = error_info[3])
  144. WRECK.time_loaded = gettime()
  145. raise MSException()
  146. print '{2}DONE.{0}'.format(*COLORAMA)
  147. WRECK.time_loaded = gettime()
  148.  
  149. # |
  150. # +
  151. # \
  152. # +===============================================================================================
  153. # /
  154. # +
  155. # |
  156.  
  157. print 'Loading plugins...',
  158.  
  159. try:
  160. # Check plugin requirements
  161. prereq_errors = []
  162. for plugin, required_by in WRECK.requirements.iteritems():
  163. if plugin not in WRECK.plugins:
  164. prereq_errors.append('Plugin %s not imported but required by %s.' % (plugin, ', '.join(required_by)))
  165. if prereq_errors:
  166. raise MSException('\r\n'.join(prereq_errors))
  167. # Process data injections
  168. glob = get_globals()
  169. for plugin in WRECK.plugins:
  170. for parser in parsers.iterkeys():
  171. if hasattr(glob[plugin], parser):
  172. glob[parser].extend(getattr(glob[plugin], parser))
  173. injections = getattr(glob[plugin], 'injection', None)
  174. if injections:
  175. for inj_name, inj_elements in injections.iteritems():
  176. WRECK.injections.setdefault(inj_name, []).extend(inj_elements)
  177. #WRECK.warnings.append('Injection: %d elements for `%s` in `%s`' % (len(inj_elements), inj_name, plugin))
  178. except Exception, e:
  179. print '{1}FAILED.\nPLUGIN `{module!s}` ERROR:\n{error!s}{0}'.format(*COLORAMA, module = plugin, error = (e.formatted() if isinstance(e, MSException) else formatted_exception()))
  180. WRECK.time_plugins = gettime()
  181. raise MSException()
  182. print '{2}DONE.{0}'.format(*COLORAMA)
  183. WRECK.time_plugins = gettime()
  184.  
  185. # |
  186. # +
  187. # \
  188. # +===============================================================================================
  189. # /
  190. # +
  191. # |
  192.  
  193. print 'Checking module syntax...',
  194.  
  195. try:
  196. for entity_name, entity_def in parsers.iteritems():
  197. WRECK.current_module = entity_name
  198. get_globals()[entity_name] = check_syntax(get_globals()[entity_name], [entity_def['parser']], entity_def.get('uid', 0))
  199. WRECK.current_module = None
  200. except Exception, e:
  201. print '{1}FAILED.\nMODULE `{module!s}` ERROR:\n{error!s}{0}'.format(*COLORAMA, module = entity_name, error = (e.formatted() if isinstance(e, MSException) else formatted_exception()))
  202. WRECK.time_syntax = gettime()
  203. raise MSException()
  204. print '{2}DONE.{0}'.format(*COLORAMA)
  205. WRECK.time_syntax = gettime()
  206.  
  207. WRECK.anim[7] = animations
  208. WRECK.fac[7] = factions
  209. WRECK.ip[7] = info_pages
  210. WRECK.imod[7] = item_modifiers
  211. WRECK.itm[7] = items
  212. WRECK.icon[7] = map_icons
  213. WRECK.mnu[7] = game_menus
  214. WRECK.mesh[7] = meshes
  215. WRECK.mt[7] = mission_templates
  216. WRECK.track[7] = tracks
  217. WRECK.psys[7] = particle_systems
  218. WRECK.p[7] = parties
  219. WRECK.pt[7] = party_templates
  220. WRECK.pfx[7] = postfx_params
  221. WRECK.prsnt[7] = presentations
  222. WRECK.qst[7] = quests
  223. WRECK.spr[7] = scene_props
  224. WRECK.scn[7] = scenes
  225. WRECK.script[7] = scripts
  226. WRECK.skl[7] = skills
  227. WRECK.snd[7] = sounds
  228. WRECK.s[7] = strings
  229. WRECK.tableau[7] = tableaus
  230. WRECK.trp[7] = troops
  231.  
  232. # |
  233. # +
  234. # \
  235. # +===============================================================================================
  236. # /
  237. # +
  238. # |
  239.  
  240. print 'Allocating identifiers...',
  241.  
  242. try:
  243. allocate_global_variables()
  244. allocate_quick_strings()
  245. calculate_identifiers(animations, anim)
  246. calculate_identifiers(factions, fac)
  247. calculate_identifiers(info_pages, ip)
  248. calculate_identifiers(item_modifiers, imod, imodbit)
  249. calculate_identifiers(items, itm)
  250. calculate_identifiers(map_icons, icon)
  251. calculate_identifiers(game_menus, mnu)
  252. calculate_identifiers(meshes, mesh)
  253. calculate_identifiers(mission_templates, mt)
  254. calculate_identifiers(tracks, track)
  255. calculate_identifiers(particle_systems, psys)
  256. calculate_identifiers(parties, p)
  257. calculate_identifiers(party_templates, pt)
  258. calculate_identifiers(postfx_params, pfx)
  259. calculate_identifiers(presentations, prsnt)
  260. calculate_identifiers(quests, qst)
  261. calculate_identifiers(scene_props, spr)
  262. calculate_identifiers(scenes, scn)
  263. calculate_identifiers(scripts, script)
  264. calculate_identifiers(skills, skl)
  265. calculate_identifiers(sounds, snd)
  266. calculate_identifiers(strings, s)
  267. calculate_identifiers(tableaus, tableau)
  268. calculate_identifiers(troops, trp)
  269. undefined = undefined_identifiers()
  270. if undefined: raise MSException('undeclared identifiers found in module source:\n * %s' % ('\n * '.join(['%s (referenced by \'%s\')' % (name, '\', \''.join(refs)) for name, refs in undefined])))
  271. except Exception, e:
  272. print '{1}FAILED.'.format(*COLORAMA)
  273. if isinstance(e, MSException):
  274. print 'MODULE ERROR:\n{error!s}{0}'.format(*COLORAMA, error = e.formatted())
  275. else:
  276. print 'COMPILER INTERNAL ERROR:\n{error!s}{0}'.format(*COLORAMA, error = formatted_exception())
  277. WRECK.time_identifiers = gettime()
  278. raise MSException()
  279. print '{2}DONE.{0}'.format(*COLORAMA)
  280. WRECK.time_identifiers = gettime()
  281.  
  282. # |
  283. # +
  284. # \
  285. # +===============================================================================================
  286. # /
  287. # +
  288. # |
  289.  
  290. print 'Compiling module...',
  291.  
  292. try:
  293. stage = 0
  294. # Pre-processing (note that all entity-level injections are already done but script-level injections are not).
  295. glob = get_globals()
  296. preprocess_entities_internal(glob)
  297. stage = 1
  298. for plugin in WRECK.plugins:
  299. processor = getattr(glob[plugin], 'preprocess_entities', None)
  300. if processor:
  301. try: processor(glob)
  302. except Exception, e: raise MSException('Error in %r pre-processor script.' % plugin, formatted_exception())
  303. # Compiling...
  304. stage = 2
  305. for entity_name, entity_def in parsers.iteritems():
  306. stage = 3
  307. entities = get_globals()[entity_name]
  308. stage = 4
  309. for index in xrange(len(entities)):
  310. entities[index] = entity_def['processor'](entities[index], index)
  311. stage = 5
  312. setattr(WRECK, entity_name, entity_def['aggregator'](entities))
  313. # Post-processing (plugins are NOT allowed to do anything here as we are dealing with already compiled code)
  314. stage = 6
  315. postprocess_entities()
  316. except Exception, e:
  317. print '{1}FAILED.'.format(*COLORAMA)
  318. if isinstance(e, MSException):
  319. if stage == 0:
  320. print 'COMPILER PREPROCESSOR ERROR:\n{error!s}{0}'.format(*COLORAMA, error = e.formatted())
  321. if stage == 1:
  322. print 'PLUGIN {module!s} PREPROCESSOR ERROR:\n{error!s}{0}'.format(*COLORAMA, module = plugin, error = e.formatted())
  323. elif stage == 3:
  324. print 'MODULE {module!s} ENTITY #{index} COMPILATION ERROR:\n{error!s}{0}'.format(*COLORAMA, module = entity_name, index = index, error = e.formatted())
  325. elif stage == 4:
  326. print 'MODULE {module!s} AGGREGATOR ERROR:\n{error!s}{0}'.format(*COLORAMA, module = entity_name, error = e.formatted())
  327. elif stage == 5:
  328. print 'COMPILER POSTPROCESSOR ERROR:\n{error!s}{0}'.format(*COLORAMA, error = e.formatted())
  329. else:
  330. print 'COMPILER INTERNAL ERROR:\n{error!s}{0}'.format(*COLORAMA, error = formatted_exception())
  331. WRECK.time_compile = gettime()
  332. raise MSException()
  333. print '{2}DONE.{0}'.format(*COLORAMA)
  334. WRECK.time_compile = gettime()
  335.  
  336. # |
  337. # +
  338. # \
  339. # +===============================================================================================
  340. # /
  341. # +
  342. # |
  343.  
  344. print 'Exporting module...',
  345.  
  346. export = {
  347. 'animations': export_filename % 'actions',
  348. 'dialogs': export_filename % 'conversation',
  349. 'dialog_states': export_filename % 'dialog_states',
  350. 'factions': export_filename % 'factions',
  351. 'game_menus': export_filename % 'menus',
  352. 'info_pages': export_filename % 'info_pages',
  353. 'items': export_filename % 'item_kinds1',
  354. 'map_icons': export_filename % 'map_icons',
  355. 'meshes': export_filename % 'meshes',
  356. 'mission_templates': export_filename % 'mission_templates',
  357. 'tracks': export_filename % 'music',
  358. 'particle_systems': export_filename % 'particle_systems',
  359. 'parties': export_filename % 'parties',
  360. 'party_templates': export_filename % 'party_templates',
  361. 'postfx_params': export_filename % 'postfx',
  362. 'presentations': export_filename % 'presentations',
  363. 'quests': export_filename % 'quests',
  364. 'scene_props': export_filename % 'scene_props',
  365. 'scenes': export_filename % 'scenes',
  366. 'scripts': export_filename % 'scripts',
  367. 'simple_triggers': export_filename % 'simple_triggers',
  368. 'skills': export_filename % 'skills',
  369. 'skins': export_filename % 'skins',
  370. 'sounds': export_filename % 'sounds',
  371. 'strings': export_filename % 'strings',
  372. 'tableaus': export_filename % 'tableau_materials',
  373. 'triggers': export_filename % 'triggers',
  374. 'troops': export_filename % 'troops',
  375. 'variables': export_filename % 'variables',
  376. 'quick_strings': export_filename % 'quick_strings',
  377. }
  378. if WRECK.generate_item_modifiers: export['item_modifiers'] = 'Data/item_modifiers.txt'
  379. if WRECK.generate_ui_strings: export['ui_strings'] = 'Languages/en/ui.csv'
  380. if WRECK.generate_user_hints: export['user_hints'] = 'Languages/en/hints.csv'
  381.  
  382. try:
  383. for entity_name, filename in export.iteritems():
  384. contents = getattr(WRECK, entity_name)
  385. if contents is None:
  386. #print 'Module %s has no changes, skipping export.' % entity_name
  387. continue
  388. #print 'Exporting module %s...' % entity_name
  389. filename = path_split(filename.replace('\\', '/'))
  390. folder = ('%s/%s' % (WRECK.destination, filename[0])) if filename[0] else WRECK.destination
  391. if filename[0] and not(path_exists(folder)): makedirs(folder)
  392. with open('%s/%s' % (folder, filename[1]), 'w+b') as f: f.write(contents)
  393. except Exception, e:
  394. print '{1}FAILED.\nCOMPILER INTERNAL ERROR WHILE WRECKING {module!s}:\n{error!s}{0}'.format(*COLORAMA, module = entity_name, error = formatted_exception())
  395. WRECK.time_export = gettime()
  396. raise MSException()
  397.  
  398. if write_id_files is not None:
  399. export = {
  400. 'animations': (WRECK.anim, 'anim_'),
  401. 'factions': (WRECK.fac, 'fac_'),
  402. 'info_pages': (WRECK.ip, 'ip_'),
  403. 'items': (WRECK.itm, 'itm_'),
  404. 'map_icons': (WRECK.icon, 'icon_'),
  405. 'menus': (WRECK.mnu, 'mnu_'),
  406. 'meshes': (WRECK.mesh, 'mesh_'),
  407. 'mission_templates': (WRECK.mt, 'mt_'),
  408. 'music': (WRECK.track, 'track_'),
  409. 'particle_systems': (WRECK.psys, 'psys_'),
  410. 'parties': (WRECK.p, 'p_'),
  411. 'party_templates': (WRECK.pt, 'pt_'),
  412. 'postfx_params': (WRECK.pfx, 'pfx_'),
  413. 'presentations': (WRECK.prsnt, 'prsnt_'),
  414. 'quests': (WRECK.qst, 'qst_'),
  415. 'scene_props': (WRECK.spr, 'spr_'),
  416. 'scenes': (WRECK.scn, 'scn_'),
  417. 'scripts': (WRECK.script, 'script_'),
  418. 'skills': (WRECK.skl, 'skl_'),
  419. 'sounds': (WRECK.snd, 'snd_'),
  420. 'strings': (WRECK.s, 'str_'),
  421. 'tableau_materials': (WRECK.tableau, 'tableau_'),
  422. 'troops': (WRECK.trp, 'trp_'),
  423. }
  424. try:
  425. for entity_name, (entity, prefix) in export.iteritems():
  426. contents = '\n'.join(['%s%s = %d' % (prefix, ref, index) for ref, index in sorted(map(lambda i:(i[0],int(i[1]&0xFFFFFFFF)), entity[0].iteritems()), lambda x,y:cmp(x[1],y[1]))])
  427. with open(write_id_files % entity_name, 'w+b') as f:
  428. f.write(contents)
  429. f.write('\n')
  430. except Exception, e:
  431. print '{1}FAILED.\nCOMPILER INTERNAL ERROR WHILE WRECKING {module!s}:\n{error!s}{0}'.format(*COLORAMA, module = write_id_files % entity_name, error = formatted_exception())
  432. WRECK.time_export = gettime()
  433. raise MSException()
  434.  
  435. print '{2}DONE.{0}'.format(*COLORAMA)
  436. WRECK.time_export = gettime()
  437.  
  438. # |
  439. # +
  440. # \
  441. # +-----------------------------------------------------------------------------------------------
  442.  
  443.  
  444. except MSException:
  445. WRECK.successful = False
  446.  
  447. print
  448. if WRECK.successful:
  449. print '{2}COMPILATION SUCCESSFUL.{0}\n'.format(*COLORAMA)
  450. else:
  451. print '{1}COMPILATION FAILED.{0}\n'.format(*COLORAMA)
  452.  
  453. error_reporting_level = 3
  454. if 'silent' in sys.argv: error_reporting_level = 0
  455. if ('error' in sys.argv) or ('errors' in sys.argv): error_reporting_level = 1
  456. if ('error' in sys.argv) or ('warnings' in sys.argv): error_reporting_level = 2
  457. if ('notice' in sys.argv) or ('notices' in sys.argv): error_reporting_level = 3
  458.  
  459. if WRECK.errors and (error_reporting_level > 0):
  460. print 'The following errors were generated during compilation:{1}\n '.format(*COLORAMA),
  461. print '\n '.join(WRECK.errors)
  462. print '{0}'.format(*COLORAMA)
  463. if WRECK.warnings and (error_reporting_level > 1):
  464. print 'The following warnings were generated during compilation:{3}\n '.format(*COLORAMA),
  465. print '\n '.join(WRECK.warnings)
  466. print '{0}'.format(*COLORAMA)
  467. if WRECK.notices and (error_reporting_level > 2):
  468. print 'The following notifications were generated during compilation:{6}\n '.format(*COLORAMA),
  469. print '\n '.join(WRECK.notices)
  470. print '{0}'.format(*COLORAMA)
  471. if show_performance_data and WRECK.time_loaded:
  472. print 'Displaying W.R.E.C.K. performance information.'
  473. print 'Use {5}show_performance_data = False{0} directive in {5}module_info.py{0} file to disable.'.format(*COLORAMA)
  474. print
  475. if WRECK.time_loaded: print ' %.03f sec spent to load module data.' % (WRECK.time_loaded - WRECK.time_started)
  476. if WRECK.time_plugins: print ' %.03f sec spent to load plugins.' % (WRECK.time_plugins - WRECK.time_loaded)
  477. if WRECK.time_syntax: print ' %.03f sec spent to check module syntax.' % (WRECK.time_syntax - WRECK.time_plugins)
  478. if WRECK.time_identifiers: print ' %.03f sec spent to allocate identifiers.' % (WRECK.time_identifiers - WRECK.time_syntax)
  479. if WRECK.time_compile: print ' %.03f sec spent to compile module.' % (WRECK.time_compile - WRECK.time_identifiers)
  480. if WRECK.time_export: print ' %.03f sec spent to export module.' % (WRECK.time_export - WRECK.time_compile)
  481. print
  482. print ' >>> %.03f sec total time spent. <<<' % (gettime() - WRECK.time_started)
  483. print
  484. if 'wait' in sys.argv: raw_input('Press Enter to finish>')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement