/tools/create_msg.py

https://github.com/JimB16/PokePlat
Python | 227 lines | 158 code | 31 blank | 38 comment | 44 complexity | 4e7c0770db19f05477ce073362b7c148 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. """
  3. ---
  4. """
  5. import os
  6. import sys
  7. from copy import copy, deepcopy
  8. from ctypes import c_int8
  9. import random
  10. import json
  11. import operator
  12. import array
  13. import codecs
  14. import configuration
  15. def words(fileobj):
  16. for line in fileobj:
  17. for word in line.split():
  18. yield word
  19. def decryptOffsetSize(seed, text):
  20. ret = array.array('I')
  21. num = len(text)
  22. i = 0
  23. overallsize = 0
  24. while i < num:
  25. key = ((seed*(i+1)*0x2FD)&0xFFFF) | ((seed*(i+1)*0x2FD0000)&0xFFFF0000)
  26. offset = 4 + 8*num + overallsize*2
  27. # print("offset: " + str(offset))
  28. size = len(text[i])
  29. overallsize += size
  30. #print("size: " + str(size))
  31. offsets = (offset ^ key)
  32. sizes = (size ^ key)
  33. ret.append(offsets)
  34. ret.append(sizes)
  35. i += 1
  36. return ret
  37. def decryptMsg(seed, text):
  38. i = 0
  39. num = len(text)
  40. ret = array.array('H')
  41. i = 0
  42. while i < num:
  43. key = (0x91BD3*(i+1))&0xFFFF
  44. for c in text[i]:
  45. c2 = c ^ key
  46. #print(hex(c) + " -> " + hex(c2))
  47. key = (key+0x493D)&0xFFFF
  48. ret.append(c2)
  49. i += 1
  50. return ret
  51. def parseMsg(text):
  52. ret = []
  53. line = []
  54. SYMBOLS = {}
  55. with open("tools/lists/poketext.tbl") as f:
  56. content = f.readlines()
  57. for l in content:
  58. l = l.decode('utf-8')
  59. l2 = []
  60. l2 = [l[0:4]]
  61. l2 += [l[5:-2]]
  62. if len(l2[1]) == 1:
  63. #print(l2[1])
  64. SYMBOLS[ord(l2[1])] = int(l2[0].encode('ascii','ignore'), 16)
  65. #print("SYMBOLS")
  66. #print(ord(u'é'))
  67. #print(SYMBOLS)
  68. s = 0
  69. MsgNr = 0
  70. #text = text.decode('utf8')
  71. #print(text)
  72. while s < len(text):
  73. #print(text[s])
  74. #print(ord(text[s]))
  75. if text[s] == "\\":
  76. if text[s+1] == "v":
  77. nr = text[s+2] + text[s+3] + text[s+4] + text[s+5]
  78. value = []
  79. value.append(int("0xfffe", 16))
  80. value.append(int(nr, 16))
  81. s += 6
  82. while (len(text) >= s+5) and (text[s] == "\\" and text[s+1] == "x"):
  83. nr = text[s+2] + text[s+3] + text[s+4] + text[s+5]
  84. value.append(int(nr, 16))
  85. s += 6
  86. #print(value)
  87. line.append(value[0])
  88. line.append(value[1])
  89. line.append(len(value)-2)
  90. i = 2
  91. while i < len(value):
  92. line.append(value[i])
  93. i += 1
  94. elif (text[s+1] == "x") and (text[s+2] == "0") and (text[s+3] == "1" and (text[s+4] == "e") and (text[s+5] == "2")):
  95. if (len(text) >= s+5):
  96. nr = text[s+2] + text[s+3] + text[s+4] + text[s+5]
  97. line.append(int(nr, 16))
  98. #print(int(nr, 16))
  99. s += 6
  100. elif text[s+1] == "f":
  101. line.append(0x25bd)
  102. s += 2
  103. elif text[s+1] == "n":
  104. line.append(0xe000)
  105. s += 2
  106. elif text[s+1] == "r":
  107. line.append(0x25bc)
  108. s += 2
  109. elif text[s+1] == "c": # compression
  110. line.append(0xf100)
  111. val = 0
  112. shift = 0
  113. while (s+2 < len(text)) and (text[s+2] != "\n"):
  114. nr = SYMBOLS.get(ord(text[s+2])) & 0x1ff
  115. val |= (nr<<shift)
  116. shift += 9
  117. while shift >= 15:
  118. shift -= 15
  119. line.append(val & 0x7fff)
  120. val >>= 15
  121. s += 1
  122. if shift > 0:
  123. val |= (0xffff<<shift)
  124. line.append(val & 0x7fff)
  125. #line.append(0xffff)
  126. s += 2
  127. else:
  128. s += 1
  129. elif text[s] == "\n":
  130. line.append(0xffff)
  131. ret.append(line)
  132. #if MsgNr == 2:
  133. # print("MsgNr " + str(MsgNr) + ": " + str(line))
  134. MsgNr += 1
  135. line = []
  136. s += 1
  137. else:
  138. nr = SYMBOLS.get(ord(text[s]))
  139. #print(text[s])
  140. #if(ord(text[s]) == ord(u'é')):
  141. if nr == None:
  142. line.append(0x0)
  143. else:
  144. line.append(nr)
  145. s += 1
  146. line.append(0xffff)
  147. ret.append(line)
  148. return ret
  149. if __name__ == "__main__":
  150. conf = configuration.Config()
  151. filename = sys.argv[1]
  152. dir = sys.argv[2]
  153. output = ""
  154. offset = 0
  155. if not os.path.exists(os.path.dirname(dir)):
  156. os.makedirs(os.path.dirname(dir))
  157. head, tail = os.path.split(filename)
  158. out = open(os.path.join(dir + tail.replace(".msg", ".bin")), 'w')
  159. text = ""
  160. num = 0
  161. seed = 0
  162. with codecs.open(filename, "r", "utf-8") as fin:
  163. for line in fin:
  164. words = line.split()
  165. if((len(words) == 2) and (words[0] == u"num:" or num == 0)):
  166. #print(words[0] + " " + words[1])
  167. c = array.array("H")
  168. c.append(int(words[1], 0))
  169. num = int(words[1], 0)
  170. c.tofile(out)
  171. elif((len(words) == 2) and words[0] == u"seed:"):
  172. #print("seed_: " + words[1])
  173. c = array.array("H")
  174. c.append(int(words[1], 0))
  175. seed = int(words[1], 0)
  176. c.tofile(out)
  177. else:
  178. text += line
  179. #print(words[0])
  180. text.encode('utf8')
  181. #print(text)
  182. parsedtext = parseMsg(text)
  183. #print(parsedtext)
  184. #a = array.array('L')
  185. #for c in decryptOffsetSize(num, seed, parsedtext):
  186. #print(hex(c))
  187. #a.append(int(c))
  188. #a.tofile(out)
  189. decryptOffsetSize(seed, parsedtext).tofile(out)
  190. #for c in decryptMsg(seed, parsedtext):
  191. # print(hex(c))
  192. decryptMsg(seed, parsedtext).tofile(out)
  193. #for word in line.split():
  194. # print(word)
  195. #filenames.append((words[1], words[0], '\x00'))
  196. #filenames.append(("data/header.bin", 0x4000, '\x00'))