upload_run_lab.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #!/usr/bin/python3
  2. import sqlite3
  3. import json
  4. import sys
  5. import os
  6. import MAPPING
  7. """
  8. Reads the API KEY, that must be passed as first command line argument.
  9. :returns: Recovered API KEY.
  10. :raises Exception: Th KEY couldn't be red.
  11. """
  12. def readKey():
  13. try:
  14. key = sys.argv[1]
  15. return key
  16. except Exception as e:
  17. print("Error parsing API KEY: " + str(e))
  18. raise
  19. """
  20. Reads the JSON data, that must be passed as second command line argument.
  21. :param: index 2 for start data, 3 for result data
  22. :returns: Recovered data, in JSON format.
  23. :raises Exception: The data couldn't be red or converted to JSON.
  24. """
  25. def readData(index):
  26. try:
  27. data = json.loads(sys.argv[index])
  28. return data
  29. except Exception as e:
  30. print("Error parsing data: " + str(e))
  31. raise
  32. """
  33. Verifies that the API key matches the player data and that it exists in th DB.
  34. :param db: Connection to the database.
  35. :returns: Connection to the database.
  36. :param data: Data in json format.
  37. :param key: API KEY.
  38. :returns: True if key and player match, False otherwise.
  39. :raises IntegrityError: The queryes couldn't bre executed.
  40. """
  41. def verifyKey(db, data, key):
  42. print('Verifying KEY...')
  43. status = False
  44. try:
  45. uid = data["wizard_info"]["wizard_id"]
  46. cursor = db.cursor()
  47. cursor.execute('SELECT count(uid) AS c FROM player WHERE uid = ? AND api_key = ?;', (uid, key))
  48. if cursor.fetchone()[0] == 1:
  49. status = True
  50. cursor.close()
  51. except sqlite3.IntegrityError as e:
  52. print("Error executing statement: " + str(e))
  53. raise
  54. return status
  55. """
  56. Opens the database file and deletes from the user tables
  57. :param name: The path to the sqlite database.
  58. :returns: Connection to the database.
  59. :raises IntegrityError: The queryes couldn't bre executed.
  60. :raises IOError: The sqlite file couldn't be created.
  61. """
  62. def openDatabase():
  63. kdb = os.path.dirname(os.path.realpath(sys.argv[0])) + '/../../../sw.sqlite'
  64. udb = os.path.dirname(os.path.realpath(sys.argv[0])) + '/../../../../data/sw.sqlite'
  65. print('Configuring database...')
  66. try:
  67. db = sqlite3.connect(kdb)
  68. cursor = db.cursor()
  69. cursor.execute('attach "' + udb + '" as data;')
  70. cursor.close()
  71. return db
  72. except sqlite3.IntegrityError as e:
  73. print("Error executing statement: " + str(e))
  74. raise
  75. except IOError as e:
  76. print("I/O Error creating database " + name + ": " + str(e))
  77. raise
  78. """
  79. Inserts a row into the database.
  80. :param db: Connection to the database.
  81. :param table: Name of the table to insert into.
  82. :param values: List of values to insert.
  83. :raises IntegrityError: The insert query was unsuccesfull.
  84. """
  85. def insert(db, table, values):
  86. cursor = db.cursor()
  87. placeholders = ''
  88. for x in range(0, len(values)):
  89. placeholders = placeholders + '?, '
  90. placeholders = placeholders[:len(placeholders) - 2]
  91. query = 'INSERT INTO ' + table + ' VALUES (' + placeholders + ')'
  92. try:
  93. cursor.execute(query, values)
  94. except sqlite3.IntegrityError as e:
  95. print('Error Inserting into ' + table + ' with values (' + str(values) + '): ' + str(e))
  96. raise
  97. cursor.close;
  98. """
  99. Parses run data (tables run, run_party, run_drop_rune, run_drop_runecraft,
  100. run_drop_item, run_drop_unit, run_drop_sd, run_drop_unit_pieces,
  101. run_drop_shapeshifting).
  102. :param db: Sqlite database connection.
  103. :param data_start: JSON data of the run start.
  104. :param data_result: JSON data of the run result.
  105. """
  106. def parseRun(db, data_request, data_response):
  107. print("Parsing run...")
  108. cursor = db.cursor()
  109. # Read basic data
  110. uid = data_request["wizard_id"]
  111. dtime = data_response["tvaluelocal"]
  112. # Check if run has already been inserted.
  113. cursor.execute("SELECT count(id) AS c FROM run WHERE uid = ? AND dtime = ?;", (uid, dtime))
  114. if (cursor.fetchone()[0] > 0):
  115. print(" Run already in database. Stopping....")
  116. return 409;
  117. # We are inserting, get aditional info
  118. area_type = 9 # Tartarus Labyrinth
  119. area = 9 # Tartarus Labyrinth
  120. stage = 0 # Battle type
  121. difficulty = data_request["difficulty"]
  122. win = data_response["win_lose"]
  123. helper = 0
  124. tile_id = data_request["tile_id"]
  125. # We now have the tile id from the request.
  126. # Now we must loop all tiles in the response to get the info
  127. for tile in data_response["guildmaze_tiles"]:
  128. # TODO: Get correct types
  129. if tile["tile_id"] == tile_id:
  130. if tile["battle_type"] == 0: # Tartarus
  131. stage = 1
  132. elif tile["battle_type"] == 302: # Kottos (Fire guardian)
  133. stage = 2
  134. elif tile["battle_type"] == 0: # Leos (Water guardian)
  135. stage = 3
  136. elif tile["battle_type"] == 0: # Guilles (Wind guardian)
  137. stage = 4
  138. elif tile["battle_type"] == 0: # Normal stage
  139. stage = 5
  140. elif tile["battle_type"] == 0: # Rescue stage
  141. stage = 6
  142. elif tile["battle_type"] == 0: # Explode stage
  143. stage = 7
  144. elif tile["battle_type"] == 0: # Cooltime stage
  145. stage = 8
  146. elif tile["battle_type"] == 201: # Speed limit stage
  147. stage = 9
  148. elif tile["battle_type"] == 202: # Time limit stage
  149. stage = 10
  150. break
  151. score = 0 # TODO
  152. rank = ''
  153. time = data_request["clear_time"]
  154. if ("mana" in data_response["reward"]):
  155. mana = data_response["reward"]["mana"]
  156. else:
  157. mana = 0
  158. if ("energy" in data_response["reward"]):
  159. energy = data_response["reward"]["energy"]
  160. else:
  161. energy = 0
  162. if ("crystal" in data_response["reward"]):
  163. crystal = data_response["reward"]["crystal"]
  164. else:
  165. crystal = 0
  166. if ("guild-point" in data_response["reward"]):
  167. guild_points = data_response["reward"]["guild-point"]
  168. else:
  169. guild_points = 0
  170. # Get the new ID and insert
  171. cursor.execute("SELECT max(id) + 1 AS id FROM run;")
  172. id = cursor.fetchone()[0]
  173. if id == None:
  174. id = 1
  175. insert(db, "run", (uid, id, dtime, area_type, area, stage, difficulty, win, time, mana, energy, crystal, guild_points, helper, score, rank))
  176. # Parse various types of reward
  177. crate = data_response["reward"]["crate"]
  178. # Parse rune reward
  179. if "rune" in crate:
  180. rune = crate["rune"]
  181. rune_id = rune["rune_id"]
  182. rune_type = rune["set_id"]
  183. slot = rune["slot_no"]
  184. stars = rune["class"]
  185. ancient = 0
  186. quality = rune["rank"]
  187. value = rune["sell_value"]
  188. efficiency, max_efficiency = MAPPING.calculate_efficiency(rune)
  189. main_stat = rune["pri_eff"][0]
  190. main_stat_value = rune["pri_eff"][1]
  191. if "prefix_eff" in rune:
  192. innate_stat = rune["prefix_eff"][0]
  193. innate_stat_value = rune["prefix_eff"][1]
  194. else:
  195. innate_stat = 0
  196. innate_stat_value = 0
  197. substat_1 = 0
  198. substat_1_value = 0
  199. substat_2 = 0
  200. substat_2_value = 0
  201. substat_3 = 0
  202. substat_3_value = 0
  203. substat_4 = 0
  204. substat_4_value = 0
  205. if "0" in rune["sec_eff"]:
  206. substat_1 = rune["sec_eff"]["0"]["0"]
  207. substat_1_value = rune["sec_eff"]["0"]["1"]
  208. if "1" in rune["sec_eff"]:
  209. substat_1 = rune["sec_eff"]["1"]["0"]
  210. substat_1_value = rune["sec_eff"]["1"]["1"]
  211. if "2" in rune["sec_eff"]:
  212. substat_1 = rune["sec_eff"]["2"]["0"]
  213. substat_1_value = rune["sec_eff"]["2"]["1"]
  214. if "3" in rune["sec_eff"]:
  215. substat_1 = rune["sec_eff"]["3"]["0"]
  216. substat_1_value = rune["sec_eff"]["3"]["1"]
  217. insert(db, "run_drop_rune", (id, rune_id, rune_type, slot, stars, ancient, quality, value, efficiency, max_efficiency, main_stat, main_stat_value, innate_stat, innate_stat_value, substat_1, substat_1_value, substat_2, substat_2_value, substat_3, substat_3_value, substat_4, substat_4_value))
  218. # TODO: Parse grindstones/gems
  219. # Parse units
  220. first = True
  221. for unit in data_response["unit_list"]:
  222. unit_id = unit["unit_id"]
  223. unit_master_id = unit["unit_master_id"]
  224. if (first):
  225. leader = 1
  226. first = False
  227. else:
  228. leader = 0
  229. front = 0
  230. insert(db, "run_party", (id, unit_id, unit_master_id, leader, front))
  231. db.commit()
  232. """
  233. Begin script
  234. """
  235. data_request = readData(2)
  236. data_response = readData(3)
  237. key = readKey()
  238. db = openDatabase()
  239. if verifyKey(db, data_response, key) == False:
  240. print("Invalid API KEY...")
  241. sys.exit(401)
  242. else:
  243. parseRun(db, data_request, data_response)
  244. sys.exit(201)