upload_run_dimension.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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 = 5 # Dimension Hole Dungeon
  119. area = data_request["dungeon_id"]
  120. stage = data_request["difficulty"] # Stage is difficulty
  121. difficulty = None
  122. win = data_response["win_lose"]
  123. time = data_response["clear_time"]["current_time"]
  124. if ("mana" in data_response["reward"]):
  125. mana = data_response["reward"]["mana"]
  126. else:
  127. mana = 0
  128. if ("energy" in data_response["reward"]):
  129. energy = mana = data_response["reward"]["energy"]
  130. else:
  131. energy = 0
  132. if ("crystal" in data_response["reward"]):
  133. crystal = mana = data_response["reward"]["crystal"]
  134. else:
  135. crystal = 0
  136. helper = 0
  137. # Get the new ID and insert
  138. cursor.execute("SELECT max(id) + 1 AS id FROM run;")
  139. id = cursor.fetchone()[0]
  140. if id == None:
  141. id = 1
  142. score = None
  143. rank = None
  144. insert(db, "run", (uid, id, dtime, area_type, area, stage, difficulty, win, time, mana, energy, crystal, helper, score, rank))
  145. # Parse various types of reward
  146. crate = data_response["reward"]["crate"]
  147. if "item" in crate:
  148. for item in crate["item"]:
  149. insert(db, "run_drop_item", (id, item["item_id"], item["item_quantity"]))
  150. if "craft_stuff" in crate:
  151. for item in crate["craft_stuff"]:
  152. insert(db, ".run_drop_rune_craft", (id, item["item_id"], item["item_quantity"]))
  153. # Parse rune reward
  154. if "rune" in crate:
  155. rune = crate["rune"]
  156. rune_id = rune["rune_id"]
  157. rune_type = rune["set_id"]
  158. slot = rune["slot_no"]
  159. stars = rune["class"]
  160. ancient = 0
  161. quality = rune["rank"]
  162. value = rune["sell_value"]
  163. efficiency, max_efficiency = MAPPING.calculate_efficiency(rune)
  164. main_stat = rune["pri_eff"][0]
  165. main_stat_value = rune["pri_eff"][1]
  166. if "prefix_eff" in rune:
  167. innate_stat = rune["prefix_eff"][0]
  168. innate_stat_value = rune["prefix_eff"][1]
  169. else:
  170. innate_stat = 0
  171. innate_stat_value = 0
  172. substat_1 = 0
  173. substat_1_value = 0
  174. substat_2 = 0
  175. substat_2_value = 0
  176. substat_3 = 0
  177. substat_3_value = 0
  178. substat_4 = 0
  179. substat_4_value = 0
  180. if "0" in rune["sec_eff"]:
  181. substat_1 = rune["sec_eff"]["0"]["0"]
  182. substat_1_value = rune["sec_eff"]["0"]["1"]
  183. if "1" in rune["sec_eff"]:
  184. substat_1 = rune["sec_eff"]["1"]["0"]
  185. substat_1_value = rune["sec_eff"]["1"]["1"]
  186. if "2" in rune["sec_eff"]:
  187. substat_1 = rune["sec_eff"]["2"]["0"]
  188. substat_1_value = rune["sec_eff"]["2"]["1"]
  189. if "3" in rune["sec_eff"]:
  190. substat_1 = rune["sec_eff"]["3"]["0"]
  191. substat_1_value = rune["sec_eff"]["3"]["1"]
  192. 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))
  193. # Parse units
  194. for unit in data_request["unit_id_list"]:
  195. unit_id = unit["unit_id"]
  196. unit_master_id = None
  197. for k_unit in data_response["unit_list"]:
  198. if k_unit["unit_id"] == unit["unit_id"]:
  199. unit_master_id = k_unit["unit_master_id"];
  200. break;
  201. #unit_master_id = data_response["unit_list"][attribute]["unit_master_id"]
  202. leader = unit["is_leader"]
  203. front = 0
  204. insert(db, "run_party", (id, unit_master_id, unit_id, leader, front))
  205. db.commit()
  206. """
  207. Begin script
  208. """
  209. data_request = readData(2)
  210. data_response = readData(3)
  211. key = readKey()
  212. db = openDatabase()
  213. if verifyKey(db, data_response, key) == False:
  214. print("Invalid API KEY...")
  215. sys.exit(401)
  216. else:
  217. try:
  218. parseRun(db, data_request, data_response)
  219. except Exception as e:
  220. print("Error parsing Dimension Hole Dungeon run: " + str(e))
  221. sys.exit(400)
  222. sys.exit(201)