Skip to content

Commit

Permalink
Merge pull request #11 from Gurrman375/master
Browse files Browse the repository at this point in the history
Python and JS Interactions
  • Loading branch information
kay-el-zed authored May 27, 2021
2 parents def5bc2 + f20ad29 commit 61691d2
Show file tree
Hide file tree
Showing 445 changed files with 40,864 additions and 369 deletions.
404 changes: 44 additions & 360 deletions .gitignore

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"problemMatcher": [],
"label": "npm: start",
"detail": "electron .",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Binary file not shown.
31 changes: 22 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,47 @@

A python script that grabs your XBL status for Halo MCC and shows it as a Discord rich presence status.

![image](https://i.imgur.com/51Zdnv9l.png) ![image](https://user-images.githubusercontent.com/6400909/85205705-5f117c80-b2f3-11ea-9ede-8af1440e23ca.png)
![image](https://i.imgur.com/51Zdnv9l.png)

![image](https://user-images.githubusercontent.com/25113575/118538638-509a3380-b703-11eb-8714-63601a201dc9.png)

![image](https://user-images.githubusercontent.com/6400909/85205654-11950f80-b2f3-11ea-8e71-2398b34e2ccb.png)

<h2>How to use</h2>

1. Launch the latest release executable.
2. Create a token (option 1) for Xbox Live. You will be prompted for your credentials to authenticate your account.
3. Launch the rich presense (option 2). If you would like to use your own discord developer app and use your own images, you can do so here.
4. It will wait until it sees Halo MCC in your Xbox Live presence to display a rich status on Discord.
1. Install both requirements using pip
2. Update discord_client_id with your valid application's client ID from the [Discord developer portal](https://discordapp.com/developers).

3. Run the latest [release](https://github.com/kay-el-zed/HaloMCC-DiscordRPC/releases).


1. Input your xbox sign on account. (Data is stored in AppData/Local/OpenXbox/xbox)
2. When prompted, enter your valid application's CID(client ID) from the [Discord developer portal](https://discord.com/developers/applications), along with a small and large image. (If you don't know how to do this, leave the option blank and default settings will be used.)
3. It will wait until it sees Halo MCC in your Xbox Live presence to display a rich status on Discord.

<h2>Requirements for Building</h2>

* [pypresence](https://github.com/qwertyquerty/pypresence)
* [xbox-webapi-python](https://github.com/openxbox/xbox-webapi-python)
* [xboxlive-api](https://github.com/XboxReplay/xboxlive-api)
* [xboxlive-auth](https://github.com/XboxReplay/xboxlive-auth/tree/4.0.0)
* A client ID for an application created in the [Discord developer portal](https://discordapp.com/developers)
* Sample images for 'cover' and 'win10' as shown above are provided for creating your own application.
* [pyinstaller](https://www.pyinstaller.org/downloads.html) for building the executable.
* [nodejs](https://nodejs.org/en/download/)
* [python](https://www.python.org/downloads/)


<h2>To-dos</h2>

All things that we'd like to work on can be found in [this issue](https://github.com/kay-el-zed/HaloMCC-DiscordRPC/issues/5)
* Add better checks for if the user is playing on either Xbox or PC.
* Clean up code.
* Add session timer tracking, i.e. How long a multiplayer session has run for
* Reduce debugging output.
* Possibly perform better detection for Halo MCC on PC by checking for processes(?)

<h2>Credits</h2>

<b>[pypresence](https://github.com/qwertyquerty/pypresence)</b> - Written by: [qwertyquerty](https://github.com/qwertyquerty) and [LewdNeko](https://github.com/lewdneko) Notable Contributors: [GiovanniMCMXCIX](https://github.com/GiovanniMCMXCIX), [GhostofGoes](https://github.com/GhostofGoes)

<b>[xbox-webapi-python](https://github.com/openxbox/xbox-webapi-python)</b> - uses parts of [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template. The authentication code is based on [joealcorn/xbox](https://github.com/joealcorn/xbox)
<b>[XboxReplay](https://github.com/XboxReplay)</b> - Written by: [Alexis ize](https://github.com/Alexis-Bize)

<b>[Gurrman375](https://github.com/Gurrman375)</b> - Major contributor to the repo. Most of the commits come from them.
Binary file added __pycache__/auth.cpython-37.pyc
Binary file not shown.
Binary file added __pycache__/dictionary.cpython-37.pyc
Binary file not shown.
26 changes: 26 additions & 0 deletions additional.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os
from os import system, name, sys

def application_path():
"""Get's the current application path
Returns:
string: Retruns current application path
"""
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the PyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
application_path = os.path.dirname(sys.argv[0])
else:
application_path = os.path.dirname(os.path.abspath(__file__))
return application_path

def clear():
"""Clears terminal of all data.
"""
if name == 'nt':
_ = system('cls')
# MacOs support and Linux not likely
else:
_ = system('clear')
159 changes: 159 additions & 0 deletions auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import requests, json
from additional import clear, application_path
from datetime import datetime
from os import path, makedirs
import webbrowser
from time import sleep
CLIENT_ID = "8f9b5ee4-b4eb-40ea-a02f-c9be1f7ae7bf"
REDIRECT_URI = "https://localhost/oauth_success"

def main():
"""Making sure tokens are up to date in case any errors arrive.
"""
current = datetime.now().isoformat(timespec='microseconds') + "9Z"

if(path.exists(application_path() + "\\tokens\\token.json")):
with open((application_path() + '\\tokens\\token.json'), 'r') as f:
tokens = json.load(f)
else:
tokens = None
if(tokens != None):
if(current > tokens['NotAfter']):
if(application_path() + "\\tokens\\accesstoken.json"):
with open((application_path() + "\\tokens\\accesstoken.json"), 'r+') as f:
accesstoken = json.load(f)
access_token = refreshToken(accesstoken['refresh_token'])
user_token = userToken(access_token)
XToken(user_token)
print("Generated a token.")
else:
url()
authorization_code = input("Enter URL:")
makedirs(application_path() + "\\tokens")
clear()
access_token = accessToken(authorization_code)
user_token = userToken(access_token)
XToken(user_token)
pass


def url() -> None:
"""
Authorize account for app and receive authorization code
"""
url = "https://login.live.com/oauth20_authorize.srf"
query_params = {
"client_id": CLIENT_ID,
"response_type": "code",
"approval_prompt": "auto",
"scope": "Xboxlive.signin Xboxlive.offline_access",
"redirect_uri": REDIRECT_URI,
}

destination_url = requests.Request("GET", url, params=query_params).prepare().url

print("Login to your xbox account and save the url.")
sleep(2)
webbrowser.open(destination_url)


def accessToken(authorization_code) -> str:
"""
Authenticate account via authorization code and receive access/refresh token
"""
base_url = "https://login.live.com/oauth20_token.srf"
params = {
"grant_type": "authorization_code",
"client_id": CLIENT_ID,
"scope": "Xboxlive.signin Xboxlive.offline_access",
"code": authorization_code.replace("https://localhost/oauth_success?code=", ""),
"redirect_uri": REDIRECT_URI,
}

resp = requests.post(base_url, data=params)
if resp.status_code != 200:
print("Failed to get access token")
return

access_token = resp.json()["access_token"]
with open('tokens\\accesstoken.json', 'w+') as f:
f.write(json.dumps(resp.json(), indent=2))
return access_token

def refreshToken(refresh_token) -> str:
"""
Authenticate account via refresh code and receive access/refresh token
"""
base_url = "https://login.live.com/oauth20_token.srf"
params = {
"grant_type": "refresh_token",
"client_id": CLIENT_ID,
"scope": "Xboxlive.signin Xboxlive.offline_access",
"refresh_token": refresh_token,
"redirect_uri": REDIRECT_URI,
}

resp = requests.post(base_url, data=params)
if resp.status_code != 200:
print("Failed to refresh token")
return

access_token = resp.json()["access_token"]
with open('tokens\\accesstoken.json', 'w+') as f:
f.write(json.dumps(resp.json(), indent=2))
return access_token

def userToken(access_token) -> str:
"""
Authenticate via access token and receive user token
"""
url = "https://user.auth.xboxlive.com/user/authenticate"
headers = {"x-xbl-contract-version": "1"}
data = {
"RelyingParty": "http://auth.xboxlive.com",
"TokenType": "JWT",
"Properties": {
"AuthMethod": "RPS",
"SiteName": "user.auth.xboxlive.com",
"RpsTicket": "d=" + access_token,
},
}

resp = requests.post(url, json=data, headers=headers)

if resp.status_code != 200:
print("Invalid response")
return

user_token = resp.json()["Token"]
with open('tokens\\token.json', 'w+') as f:
f.write(json.dumps(resp.json(), indent=2))
return user_token

def XToken(user_token) -> str:
"""
Authorize via user token and receive final X token
"""
url = "https://xsts.auth.xboxlive.com/xsts/authorize"
headers = {"x-xbl-contract-version": "1"}
data = {
"RelyingParty": "http://xboxlive.com",
"TokenType": "JWT",
"Properties": {
"UserTokens": [user_token],
"SandboxId": "RETAIL",
},
}

resp = requests.post(url, json=data, headers=headers)

if resp.status_code != 200:
print("Invalid response")
return

with open('tokens\\xtoken.json', 'w+') as f:
data = f.write(json.dumps(resp.json(), indent=2))
return data

if __name__ == "__main__":
main()
Loading

0 comments on commit 61691d2

Please sign in to comment.