Skip to content

Commit

Permalink
Sanity commit to include Black formatting rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Crosswind committed Jul 29, 2024
1 parent ba73853 commit bec0e43
Showing 1 changed file with 60 additions and 26 deletions.
86 changes: 60 additions & 26 deletions redeem_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
in case it runs into errors without retrying to redeem a code
for everyone
"""

import argparse
import hashlib
import json
Expand All @@ -19,12 +20,10 @@

# Handle arguments the script is called with
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--code', required=True)
parser.add_argument('-f', '--player-file',
dest='player_file', default='player.json')
parser.add_argument('-r', '--results-file',
dest='results_file', default='results.json')
parser.add_argument('--restart', dest='restart', action="store_true")
parser.add_argument("-c", "--code", required=True)
parser.add_argument("-f", "--player-file", dest="player_file", default="player.json")
parser.add_argument("-r", "--results-file", dest="results_file", default="results.json")
parser.add_argument("--restart", dest="restart", action="store_true")
args = parser.parse_args()

# Open and read the user files
Expand All @@ -42,8 +41,7 @@
# Retrieve the result set if it exists or create an empty one
# We make sure that we get a view of the dictionary so we can modify
# it in our code and simply write the entire result list to file again later
found_item = next(
(result for result in results if result["code"] == args.code), None)
found_item = next((result for result in results if result["code"] == args.code), None)

if found_item is None:
print("New code: " + args.code + " adding to results file and processing.")
Expand All @@ -61,24 +59,36 @@
URL = "https://wos-giftcode-api.centurygame.com/api"
# The salt is appended to the string that is then signed using md5 and sent as part of the request
SALT = "tB87#kPtkxqOS2"
HTTP_HEADER = {"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json"}
HTTP_HEADER = {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
}

i = 0

# Enable retry login and backoff behavior so if you have a large number of players (> 30) it'll not fail
# Default rate limits of WOS API is 30 in 1 min.
r = requests.Session()
retry_config = Retry(total=5, backoff_factor=1, status_forcelist=[ 429 ], allowed_methods=False)
retry_config = Retry(
total=5, backoff_factor=1, status_forcelist=[429], allowed_methods=False
)
r.mount("https://", HTTPAdapter(max_retries=retry_config))

for player in players:

# Print progress bar
i += 1

print("\x1b[K" + str(i) + "/" + str(len(players)) +
" complete. Redeeming for " + player["original_name"], end="\r", flush=True)
print(
"\x1b[K"
+ str(i)
+ "/"
+ str(len(players))
+ " complete. Redeeming for "
+ player["original_name"],
end="\r",
flush=True,
)

# Check if the code has been redeemed for this player already
# Continue to the next iteration if it has been
Expand All @@ -89,32 +99,50 @@
# This is necessary because we reload the page every 5 players
# and the website isn't sometimes ready before we continue
request_data = {"fid": player["id"], "time": time.time_ns()}
request_data["sign"] = hashlib.md5(("fid=" + request_data["fid"] + "&time=" + str(
request_data["time"]) + SALT).encode("utf-8")).hexdigest()
request_data["sign"] = hashlib.md5(
(
"fid=" + request_data["fid"] + "&time=" + str(request_data["time"]) + SALT
).encode("utf-8")
).hexdigest()

# Login the player
# It is enough to send the POST request, we don't need to store any cookies/session tokens
# to authenticate during the next request
login_request = r.post(
URL + '/player', data=request_data, headers=HTTP_HEADER, timeout=30)
URL + "/player", data=request_data, headers=HTTP_HEADER, timeout=30
)
login_response = login_request.json()

# Login failed for user, report, count error and continue gracefully to complete all other players
if login_response["msg"] != "success":
print("Login not possible for player: " + player["original_name"] + " / " + player["id"] + " - validate their player ID. Skipping.")
print(
"Login not possible for player: "
+ player["original_name"]
+ " / "
+ player["id"]
+ " - validate their player ID. Skipping."
)
counter_error += 1
continue

# Create the request data that contains the signature and the code
request_data["cdk"] = args.code
request_data["sign"] = hashlib.md5(("cdk=" + request_data["cdk"] + \
"&fid=" + request_data["fid"] + \
"&time=" + str(request_data["time"]) + \
SALT).encode("utf-8")).hexdigest()
request_data["sign"] = hashlib.md5(
(
"cdk="
+ request_data["cdk"]
+ "&fid="
+ request_data["fid"]
+ "&time="
+ str(request_data["time"])
+ SALT
).encode("utf-8")
).hexdigest()

# Send the gif code redemption request
redeem_request = r.post(
URL + '/gift_code', data=request_data, headers=HTTP_HEADER, timeout=30)
URL + "/gift_code", data=request_data, headers=HTTP_HEADER, timeout=30
)
redeem_response = redeem_request.json()

# In case the gift code is broken, exit straight away
Expand All @@ -137,10 +165,16 @@
print("\nError occurred: " + str(redeem_response))
counter_error += 1

with open(args.results_file, 'w', encoding="utf-8") as fp:
with open(args.results_file, "w", encoding="utf-8") as fp:
json.dump(results, fp)

# Print general stats
print("\nSuccessfully claimed gift code for " + str(counter_successfully_claimed) + " players.\n" +
str(counter_already_claimed) + " had already claimed their gift. \nErrors ocurred for " +
str(counter_error) + " players.")
print(
"\nSuccessfully claimed gift code for "
+ str(counter_successfully_claimed)
+ " players.\n"
+ str(counter_already_claimed)
+ " had already claimed their gift. \nErrors ocurred for "
+ str(counter_error)
+ " players."
)

0 comments on commit bec0e43

Please sign in to comment.