mirror of
https://github.com/rangermix/TwitchDropsMiner.git
synced 2026-06-07 21:04:35 +00:00
Implement a lock to ensure only one verification is done at a time
This commit is contained in:
64
twitch.py
64
twitch.py
@@ -57,42 +57,22 @@ logger = logging.getLogger("TwitchDrops")
|
||||
gql_logger = logging.getLogger("TwitchDrops.gql")
|
||||
|
||||
|
||||
class _IntegrityToken:
|
||||
def __init__(self, response: JsonType):
|
||||
self.token: str = response["token"]
|
||||
self.expires: datetime = datetime.fromtimestamp(
|
||||
response["expiration"] / 1000, timezone.utc
|
||||
)
|
||||
# verify the integrity token's contents for the "is_bad_bot" flag
|
||||
stripped_token: str = self.token.split('.')[2] + "=="
|
||||
messy_json: str = urlsafe_b64decode(
|
||||
stripped_token.encode()
|
||||
).decode(errors="ignore").replace('\n', '')
|
||||
match = re.search(r'(.+)(?<="}).+$', messy_json)
|
||||
if match is None:
|
||||
raise MinerException("Unable to parse the integrity token")
|
||||
decoded_header: JsonType = json.loads(match.group(1))
|
||||
if decoded_header.get("is_bad_bot", "false") != "false":
|
||||
raise MinerException(
|
||||
"Twitch considers this miner as a \"Bad Bot\". "
|
||||
"Try deleting the cookie file and try again."
|
||||
)
|
||||
|
||||
@property
|
||||
def expired(self) -> bool:
|
||||
return datetime.now(timezone.utc) >= self.expires
|
||||
|
||||
|
||||
class _AuthState:
|
||||
def __init__(self, twitch: Twitch):
|
||||
self._twitch: Twitch = twitch
|
||||
self._lock = asyncio.Lock()
|
||||
self._logged_in = asyncio.Event()
|
||||
self.user_id: int
|
||||
self.device_id: str
|
||||
self.session_id: str
|
||||
self.access_token: str
|
||||
self.client_version: str
|
||||
self.integrity_token: _IntegrityToken
|
||||
self._logged_in = asyncio.Event()
|
||||
self.integrity_token: str
|
||||
self.integrity_expires: datetime
|
||||
|
||||
@property
|
||||
def integrity_expired(self) -> bool:
|
||||
return datetime.now(timezone.utc) >= self.integrity_expires
|
||||
|
||||
async def _login(self) -> str:
|
||||
logger.debug("Login flow started")
|
||||
@@ -190,10 +170,14 @@ class _AuthState:
|
||||
"X-Device-Id": self.device_id,
|
||||
}
|
||||
if integrity:
|
||||
headers["Client-Integrity"] = self.integrity_token.token
|
||||
headers["Client-Integrity"] = self.integrity_token
|
||||
return headers
|
||||
|
||||
async def verify(self):
|
||||
async with self._lock:
|
||||
await self._verify()
|
||||
|
||||
async def _verify(self):
|
||||
if not hasattr(self, "session_id"):
|
||||
self.session_id = create_nonce(CHARS_HEX_LOWER, 16)
|
||||
if not (hasattr(self, "client_version") and hasattr(self, "device_id")):
|
||||
@@ -248,13 +232,31 @@ class _AuthState:
|
||||
# update our cookie and save it
|
||||
jar.update_cookies(cookie, url)
|
||||
jar.save(COOKIES_PATH)
|
||||
if not hasattr(self, "integrity_token") or self.integrity_token.expired:
|
||||
if not hasattr(self, "integrity_token") or self.integrity_expired:
|
||||
async with self._twitch.request(
|
||||
"POST",
|
||||
"https://gql.twitch.tv/integrity",
|
||||
headers=self.gql_headers(integrity=False)
|
||||
) as response:
|
||||
self.integrity_token = _IntegrityToken(await response.json())
|
||||
response_json: JsonType = await response.json()
|
||||
self.integrity_token = cast(str, response_json["token"])
|
||||
self.integrity_expires = datetime.fromtimestamp(
|
||||
response_json["expiration"] / 1000, timezone.utc
|
||||
)
|
||||
# verify the integrity token's contents for the "is_bad_bot" flag
|
||||
stripped_token: str = self.integrity_token.split('.')[2] + "=="
|
||||
messy_json: str = urlsafe_b64decode(
|
||||
stripped_token.encode()
|
||||
).decode(errors="ignore").replace('\n', '')
|
||||
match = re.search(r'(.+)(?<="}).+$', messy_json)
|
||||
if match is None:
|
||||
raise MinerException("Unable to parse the integrity token")
|
||||
decoded_header: JsonType = json.loads(match.group(1))
|
||||
if decoded_header.get("is_bad_bot", "false") != "false":
|
||||
raise MinerException(
|
||||
"Twitch considers this miner as a \"Bad Bot\". "
|
||||
"Try deleting the cookie file and try again."
|
||||
)
|
||||
self._logged_in.set()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user