convert_emotions.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #!/usr/bin/env python3
  2. """
  3. Simple scripts which replaces the old emotion script constants to the new
  4. script constants.
  5. The actual replacement list is in 'emotion_dict'.
  6. Related pull request: https://github.com/rathena/rathena/pull/2527
  7. """
  8. import fileinput
  9. import re
  10. import os
  11. import collections
  12. convert_folders = ["../npc", "../src"]
  13. parse_dict_file = '../src/map/script_constants.hpp'
  14. wl_file_extensions = ['.hpp', '.h', '.cpp', '.c', '.txt' ]
  15. script_file_extensions = ['.txt']
  16. bl_files = ['script_constants.hpp']
  17. BACKUP_EXT = '.bak'
  18. """
  19. This is the old emotion_dict, which is now parsed from script_constants.hpp.
  20. emotion_dict_old = collections.OrderedDict([
  21. ('E_GASP', 'ET_SURPRISE'),
  22. ('E_WHAT', 'ET_QUESTION'),
  23. ('E_HO', 'ET_DELIGHT'),
  24. ('E_LV', 'ET_THROB'),
  25. ('E_SWT', 'ET_SWEAT'),
  26. ('E_IC', 'ET_AHA'),
  27. ('E_AN', 'ET_FRET'),
  28. ('E_AG', 'ET_ANGER'),
  29. ('E_CASH', 'ET_MONEY'),
  30. ('E_DOTS', 'ET_THINK'),
  31. ('E_SCISSORS', 'ET_SCISSOR'),
  32. ('E_ROCK', 'ET_ROCK'),
  33. ('E_PAPER', 'ET_WRAP'),
  34. ('E_KOREA', 'ET_FLAG'),
  35. ('E_LV2', 'ET_BIGTHROB'),
  36. ('E_THX', 'ET_THANKS'),
  37. ('E_WAH', 'ET_KEK'),
  38. ('E_SRY', 'ET_SORRY'),
  39. ('E_HEH', 'ET_SMILE'),
  40. ('E_SWT2', 'ET_PROFUSELY_SWEAT'),
  41. ('E_HMM', 'ET_SCRATCH'),
  42. ('E_NO1', 'ET_BEST'),
  43. ('E_NO', 'ET_STARE_ABOUT'),
  44. ('E_OMG', 'ET_HUK'),
  45. ('E_OH', 'ET_O'),
  46. ('E_X', 'ET_X'),
  47. ('E_HLP', 'ET_HELP'),
  48. ('E_GO', 'ET_GO'),
  49. ('E_SOB', 'ET_CRY'),
  50. ('E_GG', 'ET_KIK'),
  51. ('E_KIS', 'ET_CHUP'),
  52. ('E_KIS2', 'ET_CHUPCHUP'),
  53. ('E_PIF', 'ET_HNG'),
  54. ('E_OK', 'ET_OK'),
  55. ('E_MUTE', 'ET_CHAT_PROHIBIT'),
  56. ('E_INDONESIA', 'ET_INDONESIA_FLAG'),
  57. ('E_BZZ', 'ET_STARE'),
  58. ('E_RICE', 'ET_HUNGRY'),
  59. ('E_AWSM', 'ET_COOL'),
  60. ('E_MEH', 'ET_MERONG'),
  61. ('E_SHY', 'ET_SHY'),
  62. ('E_PAT', 'ET_GOODBOY'),
  63. ('E_MP', 'ET_SPTIME'),
  64. ('E_SLUR', 'ET_SEXY'),
  65. ('E_COM', 'ET_COMEON'),
  66. ('E_YAWN', 'ET_SLEEPY'),
  67. ('E_GRAT', 'ET_CONGRATULATION'),
  68. ('E_HP', 'ET_HPTIME'),
  69. ('E_PHILIPPINES', 'ET_PH_FLAG'),
  70. ('E_MALAYSIA', 'ET_MY_FLAG'),
  71. ('E_SINGAPORE', 'ET_SI_FLAG'),
  72. ('E_BRAZIL', 'ET_BR_FLAG'),
  73. ('E_FLASH', 'ET_SPARK'),
  74. ('E_SPIN', 'ET_CONFUSE'),
  75. ('E_SIGH', 'ET_OHNO'),
  76. ('E_DUM', 'ET_HUM'),
  77. ('E_LOUD', 'ET_BLABLA'),
  78. ('E_OTL', 'ET_OTL'),
  79. ('E_DICE1', 'ET_DICE1'),
  80. ('E_DICE2', 'ET_DICE2'),
  81. ('E_DICE3', 'ET_DICE3'),
  82. ('E_DICE4', 'ET_DICE4'),
  83. ('E_DICE5', 'ET_DICE5'),
  84. ('E_DICE6', 'ET_DICE6'),
  85. ('E_INDIA', 'ET_INDIA_FLAG'),
  86. ('E_LUV', 'ET_LUV'),
  87. ('E_RUSSIA', 'ET_FLAG8'),
  88. ('E_VIRGIN', 'ET_FLAG9'),
  89. ('E_MOBILE', 'ET_MOBILE'),
  90. ('E_MAIL', 'ET_MAIL'),
  91. ('E_CHINESE', 'ET_ANTENNA0'),
  92. ('E_ANTENNA1', 'ET_ANTENNA1'),
  93. ('E_ANTENNA2', 'ET_ANTENNA2'),
  94. ('E_ANTENNA3', 'ET_ANTENNA3'),
  95. ('E_HUM', 'ET_HUM2'),
  96. ('E_ABS', 'ET_ABS'),
  97. ('E_OOPS', 'ET_OOPS'),
  98. ('E_SPIT', 'ET_SPIT'),
  99. ('E_ENE', 'ET_ENE'),
  100. ('E_PANIC', 'ET_PANIC'),
  101. ('E_WHISP', 'ET_WHISP'),
  102. ('E_YUT1', 'ET_YUT1'),
  103. ('E_YUT2', 'ET_YUT2'),
  104. ('E_YUT3', 'ET_YUT3'),
  105. ('E_YUT4', 'ET_YUT4'),
  106. ('E_YUT5', 'ET_YUT5'),
  107. ('E_YUT6', 'ET_YUT6'),
  108. ('E_YUT7', 'ET_YUT7')
  109. ])
  110. """
  111. def parse_emotion_dict(filepath):
  112. ret_list = []
  113. with fileinput.FileInput(filepath) as fiFile:
  114. for line in fiFile:
  115. found = re.search('"(E_[A-Z_0-9]+)"\s*,\s*(ET_[A-Z_0-9]+)\s*', line)
  116. if found:
  117. ret_list.append((found.group(1), found.group(2)))
  118. return ret_list
  119. emotion_dict = collections.OrderedDict(parse_emotion_dict(parse_dict_file))
  120. emotion_array = [val for val in emotion_dict.values()]
  121. pattern_oldconst = re.compile(r'\b(' + '|'.join(emotion_dict.keys()) + r')\b', re.IGNORECASE)
  122. pattern_value = re.compile(r'\b(' + '|'.join(["emotion\s+%d+"%i for i in range(len(emotion_array))]) + r')\b', re.IGNORECASE)
  123. def revert_to_backup(filename):
  124. os.rename(filename+BACKUP_EXT, filename)
  125. def apply_substitutions(new_line, is_script):
  126. remove_backup = True # only keep backup if the original file changed
  127. rpl_cnt = 0
  128. # E_GASP -> ET_SURPRISE
  129. new_line, rpl_cnt = pattern_oldconst.subn(lambda x: emotion_dict[x.group().upper()], new_line)
  130. remove_backup = False if rpl_cnt > 0 else remove_backup
  131. if is_script: # script only replacements
  132. # 0 -> ET_SURPRISE
  133. new_line, rpl_cnt = pattern_value.subn(lambda x: 'emotion '+emotion_array[int(x.group().split()[-1])], new_line)
  134. remove_backup = False if rpl_cnt > 0 else remove_backup
  135. # emotion e,0,"Record player#e152a01"; -> emotion e, getnpcid(0,"Record player#e152a01");
  136. new_line, rpl_cnt = re.subn(r"emotion\s+([^,]+)\s*,\s*0\s*,\s*([^;]+);",
  137. "emotion \g<1>, getnpcid(0, \g<2>);", new_line)
  138. remove_backup = False if rpl_cnt > 0 else remove_backup
  139. # emotion e,1; -> emotion e, playerattached();
  140. new_line, rpl_cnt = re.subn(r"emotion\s+([^,]+)\s*,\s*1\s*;",
  141. "emotion \g<1>, playerattached();", new_line)
  142. remove_backup = False if rpl_cnt > 0 else remove_backup
  143. # unitemote <id>,<emotion>; -> emotion <emotion>, <id>;
  144. new_line, rpl_cnt = re.subn(r"unitemote\s+([^,]+)\s*,\s*([^,;]+)\s*;",
  145. "emotion \g<2>, \g<1>;", new_line)
  146. remove_backup = False if rpl_cnt > 0 else remove_backup
  147. return new_line, remove_backup
  148. def replace_emoticons_in_file(filename):
  149. is_script = True if any([filename.endswith(script_ext) for script_ext in script_file_extensions]) else False
  150. remove_backup = True
  151. with fileinput.FileInput(filename, inplace=True, backup=BACKUP_EXT) as fiFile:
  152. try:
  153. for line in fiFile:
  154. new_line, rm_backup = apply_substitutions(line, is_script)
  155. if not rm_backup:
  156. remove_backup = False
  157. print(new_line, end='')
  158. if remove_backup:
  159. os.remove(filename+BACKUP_EXT)
  160. except UnicodeDecodeError:
  161. # Encoding error, reapply the backup
  162. revert_to_backup(filename)
  163. fileiter = (os.path.join(root, f)
  164. for conv_folder in convert_folders
  165. for root, _, files in os.walk(conv_folder)
  166. for f in files
  167. if any([f.endswith(wl) for wl in wl_file_extensions])
  168. if not any([bl in f for bl in bl_files])
  169. )
  170. for f in fileiter:
  171. print("Updating file", f)
  172. replace_emoticons_in_file(f)