From fc8313041313c2e2b4530f5e92875aadc56160ac Mon Sep 17 00:00:00 2001 From: Li Date: Wed, 31 Aug 2022 09:52:13 +0000 Subject: [PATCH] oops --- PlayFab.py | 332 ++++++++++++++++++++++++++--------------------------- 1 file changed, 164 insertions(+), 168 deletions(-) diff --git a/PlayFab.py b/PlayFab.py index 6108b33..8d45087 100644 --- a/PlayFab.py +++ b/PlayFab.py @@ -1,169 +1,165 @@ -import requests -import os -import json -import binascii -import base64 -import struct -import hashlib -import datetime - -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.hazmat.primitives.asymmetric import padding - -# Production PlayFab Environment -TITLE_ID = "20CA2" -TITLE_SHARED_SECRET = "S8RS53ZEIGMYTYG856U3U19AORWXQXF41J7FT3X9YCWAC7I35X" - -# Internal PlayFab Environment -#TITLE_ID = "E9D1" -#TITLE_SHARED_SECRET = "RX4U3XF1KAG8W6WOOTUKO4BY1P4Z48UMHWEND7KSJHDIKCIWD6" - -PLAYFAB_HEADERS = { -"User-Agent": "libhttpclient/1.0.0.0", -"Content-Type": "application/json", -"Accept-Language": "en-US" -} - -PLAYFAB_SESSION = requests.Session() -PLAYFAB_SESSION.headers.update(PLAYFAB_HEADERS) - -PLAYFAB_DOMAIN = "https://" + TITLE_ID.lower() + ".playfabapi.com" - -SETTING_FILE = "settings.json" -PLAYFAB_SETTINGS = {} - -def sendPlayFabRequest(endpoint, data, hdrs={}): - rsp = PLAYFAB_SESSION.post(PLAYFAB_DOMAIN+endpoint, json=data, headers=hdrs).json() - if rsp['code'] != 200: - print(rsp) - else: - return rsp['data'] - -def genCustomId(): - return "MCPF"+binascii.hexlify(os.urandom(16)).decode("UTF-8").upper() - -def genPlayerSecret(): - return base64.b64encode(os.urandom(32)).decode("UTF-8") - -def getMojangCsp(): - return base64.b64decode(sendPlayFabRequest("/Client/GetTitlePublicKey", { - "TitleId":TITLE_ID, - "TitleSharedSecret": TITLE_SHARED_SECRET - })['RSAPublicKey']) - -def importCspKey(csp): - e = struct.unpack("I", csp[0x10:0x14])[0] - n = bytearray(csp[0x14:]) - n.reverse() - n = int(binascii.hexlify(n), 16) - return rsa.RSAPublicNumbers(e, n).public_key() - - - -def genPlayFabTimestamp(): - return datetime.datetime.now().isoformat()+"Z" - -def genPlayFabSignature(requestBody, timestamp): - sha256 = hashlib.sha256() - sha256.update(requestBody.encode("UTF-8") + b"." + timestamp.encode("UTF-8") + b"." + configGet("PLAYER_SECRET").encode("UTF-8")) - return base64.b64encode(sha256.digest()) - -def configGet(key): - global PLAYFAB_SETTINGS - if key in PLAYFAB_SETTINGS: - return PLAYFAB_SETTINGS[key] - return None - - -def configSet(key, newValue): - global PLAYFAB_SETTINGS - if os.path.exists(SETTING_FILE): - PLAYFAB_SETTINGS = json.loads(open(SETTING_FILE, "r").read()) - - PLAYFAB_SETTINGS[key] = newValue - open(SETTING_FILE, "w").write(json.dumps(PLAYFAB_SETTINGS)) - return newValue - -def LoginWithCustomId(): - global TITLE_ID - - customId = configGet("CUSTOM_ID") - playerSecret = configGet("PLAYER_SECRET") - createNewAccount = False - - if customId == None: - customId = genCustomId() - createNewAccount = True - - if playerSecret == None: - playerSecret = genPlayerSecret() - createNewAccount = True - - configSet("CUSTOM_ID", customId) - configSet("PLAYER_SECRET", playerSecret) - - payload = { - "CreateAccount" : None, - "CustomId": None, - "EncryptedRequest" : None, - "InfoRequestParameters" : { - "GetCharacterInventories" : False, - "GetCharacterList" : False, - "GetPlayerProfile" : True, - "GetPlayerStatistics" : False, - "GetTitleData" : False, - "GetUserAccountInfo" : True, - "GetUserData" : False, - "GetUserInventory" : False, - "GetUserReadOnlyData" : False, - "GetUserVirtualCurrency" : False, - "PlayerStatisticNames" : None, - "ProfileConstraints" : None, - "TitleDataKeys" : None, - "UserDataKeys" : None, - "UserReadOnlyDataKeys" : None - }, - "PlayerSecret" : None, - "TitleId" : TITLE_ID - } - - req = None - if createNewAccount: - toEnc = json.dumps({"CustomId":customId, "PlayerSecret": playerSecret}).encode("UTF-8") - pubkey = importCspKey(getMojangCsp()) - - payload["CreateAccount"] = True - payload["EncryptedRequest"] = base64.b64encode(pubkey.encrypt(toEnc, padding.PKCS1v15())).decode("UTF-8") - - req = sendPlayFabRequest("/Client/LoginWithCustomID", payload) - else: - payload["CustomId"] = customId - ts = genPlayFabTimestamp() - sig = genPlayFabSignature(json.dumps(payload), ts) - req = sendPlayFabRequest("/Client/LoginWithCustomID", payload, {"X-PlayFab-Signature": sig, "X-PlayFab-Timestamp": ts}) - entitytoken = req["EntityToken"]["EntityToken"] - PLAYFAB_SESSION.headers.update({"X-EntityToken": entitytoken}) - return req - -def GetEntityToken(playfabId, accType): - req = sendPlayFabRequest("/Authentication/GetEntityToken", { - "Entity" : { - "Id" : playfabId, - "Type" : accType - } - }) - entitytoken = req["EntityToken"] - PLAYFAB_SESSION.headers.update({"X-EntityToken": entitytoken}) - return req - -def Search(query, sfilter, orderBy, select, top, skip): - return sendPlayFabRequest("/Catalog/Search", { - "count": True, - "query": query, - "filter": sfilter, - "orderBy": orderBy, - "scid": "4fc10100-5f7a-4470-899b-280835760c07", - "select": select, - "top": top, - "skip": skip +import requests +import os +import json +import binascii +import base64 +import struct +import hashlib +import datetime + +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.asymmetric import padding + +# Production PlayFab Environment +TITLE_ID = "20CA2" +TITLE_SHARED_SECRET = "S8RS53ZEIGMYTYG856U3U19AORWXQXF41J7FT3X9YCWAC7I35X" + +PLAYFAB_HEADERS = { +"User-Agent": "libhttpclient/1.0.0.0", +"Content-Type": "application/json", +"Accept-Language": "en-US" +} + +PLAYFAB_SESSION = requests.Session() +PLAYFAB_SESSION.headers.update(PLAYFAB_HEADERS) + +PLAYFAB_DOMAIN = "https://" + TITLE_ID.lower() + ".playfabapi.com" + +SETTING_FILE = "settings.json" +PLAYFAB_SETTINGS = {} + +def sendPlayFabRequest(endpoint, data, hdrs={}): + rsp = PLAYFAB_SESSION.post(PLAYFAB_DOMAIN+endpoint, json=data, headers=hdrs).json() + if rsp['code'] != 200: + print(rsp) + else: + return rsp['data'] + +def genCustomId(): + return "MCPF"+binascii.hexlify(os.urandom(16)).decode("UTF-8").upper() + +def genPlayerSecret(): + return base64.b64encode(os.urandom(32)).decode("UTF-8") + +def getMojangCsp(): + return base64.b64decode(sendPlayFabRequest("/Client/GetTitlePublicKey", { + "TitleId":TITLE_ID, + "TitleSharedSecret": TITLE_SHARED_SECRET + })['RSAPublicKey']) + +def importCspKey(csp): + e = struct.unpack("I", csp[0x10:0x14])[0] + n = bytearray(csp[0x14:]) + n.reverse() + n = int(binascii.hexlify(n), 16) + return rsa.RSAPublicNumbers(e, n).public_key() + + + +def genPlayFabTimestamp(): + return datetime.datetime.now().isoformat()+"Z" + +def genPlayFabSignature(requestBody, timestamp): + sha256 = hashlib.sha256() + sha256.update(requestBody.encode("UTF-8") + b"." + timestamp.encode("UTF-8") + b"." + configGet("PLAYER_SECRET").encode("UTF-8")) + return base64.b64encode(sha256.digest()) + +def configGet(key): + global PLAYFAB_SETTINGS + if key in PLAYFAB_SETTINGS: + return PLAYFAB_SETTINGS[key] + return None + + +def configSet(key, newValue): + global PLAYFAB_SETTINGS + if os.path.exists(SETTING_FILE): + PLAYFAB_SETTINGS = json.loads(open(SETTING_FILE, "r").read()) + + PLAYFAB_SETTINGS[key] = newValue + open(SETTING_FILE, "w").write(json.dumps(PLAYFAB_SETTINGS)) + return newValue + +def LoginWithCustomId(): + global TITLE_ID + + customId = configGet("CUSTOM_ID") + playerSecret = configGet("PLAYER_SECRET") + createNewAccount = False + + if customId == None: + customId = genCustomId() + createNewAccount = True + + if playerSecret == None: + playerSecret = genPlayerSecret() + createNewAccount = True + + configSet("CUSTOM_ID", customId) + configSet("PLAYER_SECRET", playerSecret) + + payload = { + "CreateAccount" : None, + "CustomId": None, + "EncryptedRequest" : None, + "InfoRequestParameters" : { + "GetCharacterInventories" : False, + "GetCharacterList" : False, + "GetPlayerProfile" : True, + "GetPlayerStatistics" : False, + "GetTitleData" : False, + "GetUserAccountInfo" : True, + "GetUserData" : False, + "GetUserInventory" : False, + "GetUserReadOnlyData" : False, + "GetUserVirtualCurrency" : False, + "PlayerStatisticNames" : None, + "ProfileConstraints" : None, + "TitleDataKeys" : None, + "UserDataKeys" : None, + "UserReadOnlyDataKeys" : None + }, + "PlayerSecret" : None, + "TitleId" : TITLE_ID + } + + req = None + if createNewAccount: + toEnc = json.dumps({"CustomId":customId, "PlayerSecret": playerSecret}).encode("UTF-8") + pubkey = importCspKey(getMojangCsp()) + + payload["CreateAccount"] = True + payload["EncryptedRequest"] = base64.b64encode(pubkey.encrypt(toEnc, padding.PKCS1v15())).decode("UTF-8") + + req = sendPlayFabRequest("/Client/LoginWithCustomID", payload) + else: + payload["CustomId"] = customId + ts = genPlayFabTimestamp() + sig = genPlayFabSignature(json.dumps(payload), ts) + req = sendPlayFabRequest("/Client/LoginWithCustomID", payload, {"X-PlayFab-Signature": sig, "X-PlayFab-Timestamp": ts}) + entitytoken = req["EntityToken"]["EntityToken"] + PLAYFAB_SESSION.headers.update({"X-EntityToken": entitytoken}) + return req + +def GetEntityToken(playfabId, accType): + req = sendPlayFabRequest("/Authentication/GetEntityToken", { + "Entity" : { + "Id" : playfabId, + "Type" : accType + } + }) + entitytoken = req["EntityToken"] + PLAYFAB_SESSION.headers.update({"X-EntityToken": entitytoken}) + return req + +def Search(query, sfilter, orderBy, select, top, skip): + return sendPlayFabRequest("/Catalog/Search", { + "count": True, + "query": query, + "filter": sfilter, + "orderBy": orderBy, + "scid": "4fc10100-5f7a-4470-899b-280835760c07", + "select": select, + "top": top, + "skip": skip }) \ No newline at end of file