|
7 | 7 | in case it runs into errors without retrying to redeem a code |
8 | 8 | for everyone |
9 | 9 | """ |
| 10 | + |
10 | 11 | import argparse |
11 | 12 | import hashlib |
12 | 13 | import json |
|
19 | 20 |
|
20 | 21 | # Handle arguments the script is called with |
21 | 22 | parser = argparse.ArgumentParser() |
22 | | -parser.add_argument('-c', '--code', required=True) |
23 | | -parser.add_argument('-f', '--player-file', |
24 | | - dest='player_file', default='player.json') |
25 | | -parser.add_argument('-r', '--results-file', |
26 | | - dest='results_file', default='results.json') |
27 | | -parser.add_argument('--restart', dest='restart', action="store_true") |
| 23 | +parser.add_argument("-c", "--code", required=True) |
| 24 | +parser.add_argument("-f", "--player-file", dest="player_file", default="player.json") |
| 25 | +parser.add_argument("-r", "--results-file", dest="results_file", default="results.json") |
| 26 | +parser.add_argument("--restart", dest="restart", action="store_true") |
28 | 27 | args = parser.parse_args() |
29 | 28 |
|
30 | 29 | # Open and read the user files |
|
42 | 41 | # Retrieve the result set if it exists or create an empty one |
43 | 42 | # We make sure that we get a view of the dictionary so we can modify |
44 | 43 | # it in our code and simply write the entire result list to file again later |
45 | | -found_item = next( |
46 | | - (result for result in results if result["code"] == args.code), None) |
| 44 | +found_item = next((result for result in results if result["code"] == args.code), None) |
47 | 45 |
|
48 | 46 | if found_item is None: |
49 | 47 | print("New code: " + args.code + " adding to results file and processing.") |
|
61 | 59 | URL = "https://wos-giftcode-api.centurygame.com/api" |
62 | 60 | # The salt is appended to the string that is then signed using md5 and sent as part of the request |
63 | 61 | SALT = "tB87#kPtkxqOS2" |
64 | | -HTTP_HEADER = {"Content-Type": "application/x-www-form-urlencoded", |
65 | | - "Accept": "application/json"} |
| 62 | +HTTP_HEADER = { |
| 63 | + "Content-Type": "application/x-www-form-urlencoded", |
| 64 | + "Accept": "application/json", |
| 65 | +} |
66 | 66 |
|
67 | 67 | i = 0 |
68 | 68 |
|
69 | 69 | # Enable retry login and backoff behavior so if you have a large number of players (> 30) it'll not fail |
70 | 70 | # Default rate limits of WOS API is 30 in 1 min. |
71 | 71 | r = requests.Session() |
72 | | -retry_config = Retry(total=5, backoff_factor=1, status_forcelist=[ 429 ], allowed_methods=False) |
| 72 | +retry_config = Retry( |
| 73 | + total=5, backoff_factor=1, status_forcelist=[429], allowed_methods=False |
| 74 | +) |
73 | 75 | r.mount("https://", HTTPAdapter(max_retries=retry_config)) |
74 | 76 |
|
75 | 77 | for player in players: |
76 | 78 |
|
77 | 79 | # Print progress bar |
78 | 80 | i += 1 |
79 | 81 |
|
80 | | - print("\x1b[K" + str(i) + "/" + str(len(players)) + |
81 | | - " complete. Redeeming for " + player["original_name"], end="\r", flush=True) |
| 82 | + print( |
| 83 | + "\x1b[K" |
| 84 | + + str(i) |
| 85 | + + "/" |
| 86 | + + str(len(players)) |
| 87 | + + " complete. Redeeming for " |
| 88 | + + player["original_name"], |
| 89 | + end="\r", |
| 90 | + flush=True, |
| 91 | + ) |
82 | 92 |
|
83 | 93 | # Check if the code has been redeemed for this player already |
84 | 94 | # Continue to the next iteration if it has been |
|
89 | 99 | # This is necessary because we reload the page every 5 players |
90 | 100 | # and the website isn't sometimes ready before we continue |
91 | 101 | request_data = {"fid": player["id"], "time": time.time_ns()} |
92 | | - request_data["sign"] = hashlib.md5(("fid=" + request_data["fid"] + "&time=" + str( |
93 | | - request_data["time"]) + SALT).encode("utf-8")).hexdigest() |
| 102 | + request_data["sign"] = hashlib.md5( |
| 103 | + ( |
| 104 | + "fid=" + request_data["fid"] + "&time=" + str(request_data["time"]) + SALT |
| 105 | + ).encode("utf-8") |
| 106 | + ).hexdigest() |
94 | 107 |
|
95 | 108 | # Login the player |
96 | 109 | # It is enough to send the POST request, we don't need to store any cookies/session tokens |
97 | 110 | # to authenticate during the next request |
98 | 111 | login_request = r.post( |
99 | | - URL + '/player', data=request_data, headers=HTTP_HEADER, timeout=30) |
| 112 | + URL + "/player", data=request_data, headers=HTTP_HEADER, timeout=30 |
| 113 | + ) |
100 | 114 | login_response = login_request.json() |
101 | 115 |
|
102 | 116 | # Login failed for user, report, count error and continue gracefully to complete all other players |
103 | 117 | if login_response["msg"] != "success": |
104 | | - print("Login not possible for player: " + player["original_name"] + " / " + player["id"] + " - validate their player ID. Skipping.") |
| 118 | + print( |
| 119 | + "Login not possible for player: " |
| 120 | + + player["original_name"] |
| 121 | + + " / " |
| 122 | + + player["id"] |
| 123 | + + " - validate their player ID. Skipping." |
| 124 | + ) |
105 | 125 | counter_error += 1 |
106 | 126 | continue |
107 | 127 |
|
108 | 128 | # Create the request data that contains the signature and the code |
109 | 129 | request_data["cdk"] = args.code |
110 | | - request_data["sign"] = hashlib.md5(("cdk=" + request_data["cdk"] + \ |
111 | | - "&fid=" + request_data["fid"] + \ |
112 | | - "&time=" + str(request_data["time"]) + \ |
113 | | - SALT).encode("utf-8")).hexdigest() |
| 130 | + request_data["sign"] = hashlib.md5( |
| 131 | + ( |
| 132 | + "cdk=" |
| 133 | + + request_data["cdk"] |
| 134 | + + "&fid=" |
| 135 | + + request_data["fid"] |
| 136 | + + "&time=" |
| 137 | + + str(request_data["time"]) |
| 138 | + + SALT |
| 139 | + ).encode("utf-8") |
| 140 | + ).hexdigest() |
114 | 141 |
|
115 | 142 | # Send the gif code redemption request |
116 | 143 | redeem_request = r.post( |
117 | | - URL + '/gift_code', data=request_data, headers=HTTP_HEADER, timeout=30) |
| 144 | + URL + "/gift_code", data=request_data, headers=HTTP_HEADER, timeout=30 |
| 145 | + ) |
118 | 146 | redeem_response = redeem_request.json() |
119 | 147 |
|
120 | 148 | # In case the gift code is broken, exit straight away |
|
137 | 165 | print("\nError occurred: " + str(redeem_response)) |
138 | 166 | counter_error += 1 |
139 | 167 |
|
140 | | -with open(args.results_file, 'w', encoding="utf-8") as fp: |
| 168 | +with open(args.results_file, "w", encoding="utf-8") as fp: |
141 | 169 | json.dump(results, fp) |
142 | 170 |
|
143 | 171 | # Print general stats |
144 | | -print("\nSuccessfully claimed gift code for " + str(counter_successfully_claimed) + " players.\n" + |
145 | | - str(counter_already_claimed) + " had already claimed their gift. \nErrors ocurred for " + |
146 | | - str(counter_error) + " players.") |
| 172 | +print( |
| 173 | + "\nSuccessfully claimed gift code for " |
| 174 | + + str(counter_successfully_claimed) |
| 175 | + + " players.\n" |
| 176 | + + str(counter_already_claimed) |
| 177 | + + " had already claimed their gift. \nErrors ocurred for " |
| 178 | + + str(counter_error) |
| 179 | + + " players." |
| 180 | +) |
0 commit comments