upload_run_rift.py 8.5 KB

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