upload_run_dungeon.py 8.3 KB

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